#!/bin/bash
# Suppression d'artefacts ou de jobs Gitlab
#
# Ce script a été conçu pour libérer de l'espace de stockage sur un serveur Gitlanb en supprimant les jobs ou artéfacts d'un projet.
# AVERTISSEMENT : la suppression n'est pas sélective, tous les artefacts ou jobs seront supprimés".
#
# Ce script repose sur les API Rest V4 de Gitlab :
# - jobs : https://docs.gitlab.com/ee/api/jobs.html
# - artefacts : https://docs.gitlab.com/ee/api/job_artifacts.html
# - Statistiques de projet : https://docs.gitlab.com/ee/api/projects.html
# Cf. les descriptions de ces API pour interprétation des codes retounés

# Syntaxe du script
usage () {
  echo "Usage : $0 [ID_PROJET] (jobs)"
  echo "  - [ID_PROJET] : identifiant numérique du projet Gitlab"
  echo "  - jobs        : si 2ème argument='jobs' alors suppression des jobs, uniquement les artefacts sinon"
  exit 10
}

# L'identifiant du projet est obligatoire
PROJECT_ID=$1 && [ -z "$PROJECT_ID" ] && usage
# Le jeton d'authentication doit être passé par variable d'environnment
[ -z "$PRIVATE_TOKEN" ] && echo "Variable PRIVATE_TOKEN absente" && exit 11
# Par défaut 100 résultats par pages (au max)
[ -z "$PER_PAGE" ] && PER_PAGE=100
# Par défaut Gitlab interne
[ -z "$GITLAB_URL" ] && GITLAB_URL=https://gitlab-forge.din.developpement-durable.gouv.fr
# Lire que supprimer : artefacts (par défaut) ou jobs (explicite)
ACTION=$2

# Calcul de la taille des artefacts
which jq 1>/dev/null 2>&1
if [ $? -eq 0 ]; then
  arts_size=$(curl -s --header "PRIVATE-TOKEN: $PRIVATE_TOKEN" "$GITLAB_URL/api/v4/projects/$PROJECT_ID?statistics=true" \
      | jq -r '.statistics.job_artifacts_size' | numfmt --to=iec --invalid=ignore) 
fi
# Affichage des principaux paramètres
echo "Suppression des artefacts/jobs Gitlab"
echo "Serveur Gitlab : $GITLAB_URL"
echo "Projet : $PROJECT_ID"
echo "Taille des artefacts des jobs : ${arts_size:-Non déterminé}"
echo "Taille des blocs de traitement (pages) : $PER_PAGE"
echo "------------------------------------------------"
nump=$(curl -sI --header "PRIVATE-TOKEN: $PRIVATE_TOKEN" "$GITLAB_URL/api/v4/projects/$PROJECT_ID/jobs?per_page=100" \
    | grep X-Total-Pages | grep -oe "[0-9]*")
echo "Nombre de pages : $nump"

# Annulation si pas de jobs, demande de confirmation sinon
[ -z "$nump" ] && echo "Aucun job trouvé, fin d'opérations" && exit 1
echo -n "Jobs trouvés, entre $((PER_PAGE*(nump-1))) et $((PER_PAGE*(nump))), confirmez vous la suppression (O/n) ?" && read
[ "$REPLY" != "O" ] && echo "Demande annulée" && exit 2

# Itération sur les jobs
for p in $(seq $nump); do
  for jobid in $(curl -s --header "PRIVATE-TOKEN: $PRIVATE_TOKEN" "$GITLAB_URL/api/v4/projects/$PROJECT_ID/jobs?per_page=100&page=$p" \
      | jq '.[].id'); do
    if [ "$ACTION" = "jobs" ]; then
      echo -n "Suppression du job $jobid : "
      curl -sI --request POST --header "PRIVATE-TOKEN: $PRIVATE_TOKEN" "$GITLAB_URL/api/v4/projects/$PROJECT_ID/jobs/$jobid/erase" | head -1
    else
      echo -n "Suppression des artefacts du job $jobid : "
      curl -sI --request DELETE --header "PRIVATE-TOKEN: $PRIVATE_TOKEN" "$GITLAB_URL/api/v4/projects/$PROJECT_ID/jobs/$jobid/artifacts" | head -1
    fi
   done
done