Skip to content

Instantly share code, notes, and snippets.

@mgoellnitz
Last active November 11, 2022 16:30
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mgoellnitz/45f4cbe6fa4d757a1e9803094361b846 to your computer and use it in GitHub Desktop.
Save mgoellnitz/45f4cbe6fa4d757a1e9803094361b846 to your computer and use it in GitHub Desktop.
Clean old GitLab CI build job's results
#!/bin/bash
#
# Copyright 2017-2021 Martin Goellnitz
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
if [ `jq 2>&1|wc -l` = 0 ] ; then
echo "To use this tool, jq must be installed."
exit
fi
if [ "$#" == "0" ]; then
echo "GitLab Project Pipeline Old Build Cleanup 'clean-old-gitlab-pipelines.sh'"
echo ""
echo "$0 [-s] [-b branch] [-u instance url] [-d date] [-t token] project"
echo ""
echo " -s - simulate - don't actually delete"
echo ""
echo " -b branch - no default - any branch is used"
echo ""
echo " -u instance base url - default https://gitlab.com"
echo ""
echo " -t gitlab api token - default \$GITLAB_COM_TOKEN"
echo ""
echo " -d yyyy-mm-dd - date to clean builds before"
exit 1
fi
# defaults
GITLAB="https://gitlab.com"
TOKEN=$GITLAB_COM_TOKEN
# Default: save builds for 30 days
REF=$[ $(date +%s) - 2592000 ]
PSTART=`echo $1|sed -e 's/^\(.\).*/\1/g'`
# echo $PSTART
while [ "$PSTART" = "-" ] ; do
# echo $#
if [ "$1" = "-s" ] ; then
SIMULATE="sim"
fi
if [ "$1" = "-u" ] ; then
shift
GITLAB="$1"
fi
if [ "$1" = "-t" ] ; then
shift
TOKEN="$1"
fi
if [ "$1" = "-b" ] ; then
shift
BRANCH="$1"
fi
if [ "$1" = "-d" ] ; then
shift
REF="$(date -d $1 +%s)"
fi
shift
PSTART=`echo $1|sed -e 's/^\(.\).*/\1/g'`
done
PROJECT=$1
HEADER="PRIVATE-TOKEN: $TOKEN"
REFDATE=$(date -d @$REF +%Y-%m-%d)
echo "project: $PROJECT gitlab: $GITLAB with token $TOKEN reference date $REFDATE"
if [ ! -z "$PROJECT" ] ; then
N=$(echo $PROJECT|sed -e 's/\(.*\)\/\(.*\)/\2/g')
PID=`curl -k -H "$HEADER" ${GITLAB}'/api/v4/projects?per_page=100&search='$N 2> /dev/null|jq '.[]|select(.path_with_namespace=="'$PROJECT'")|.id'`
echo "project ID for $PROJECT is $PID"
if [ -z "$PID" ] ; then
echo "Unknown project $PROJECT on $GITLAB ($TOKEN)"
exit 1
fi
URLADD="/projects/$PID"
else
echo "Cannot work without the context of a project. Sorry..."
exit 1
fi
PAGES=$(curl -k -D - -X "HEAD" -H "$HEADER" "${GITLAB}/api/v4$URLADD/pipelines?per_page=100&updated_before=$REFDATE" 2> /dev/null \
|grep '^x-total-pages'|sed -e 's/^.*[a-z]:.\([0-9][0-9]*\).*$/\1/g')
PAGE="0"
while [ "$PAGE" -lt "$PAGES" ] ; do
PAGE=$[ $PAGE + 1 ]
echo "Chunk $PAGE of $PAGES"
for PIPELINE in `curl -k -H "$HEADER" "${GITLAB}/api/v4$URLADD/pipelines?per_page=100&updated_before=$REFDATE&page=$PAGE" 2> /dev/null|jq '.[]|.id'` ; do
echo -n "Pipeline $PIPELINE: "
eval $(curl -k -H "$HEADER" ${GITLAB}/api/v4$URLADD/pipelines/$PIPELINE 2> /dev/null| \
jq -r "to_entries|map(\"\(.key)=\(.value|tostring)\")|.[]")
DATE=$(echo $finished_at|sed -e 's/^\(.*\)T.*/\1/g'|sed -e 's/null/1970-01-01/g')
# echo " date: $DATE"
if [ -z "$BRANCH" ] || [ "$BRANCH" = "$ref" ] || [ "$status" != "success" ] ; then
if [ "$tag" = "false" ] || [ "$status" != "success" ]; then
D=$(date -d $DATE +%s)
# echo "$D vs $REF"
if [ "$D" -lt "$REF" ] ; then
if [ -z "$SIMULATE" ] ; then
echo "Deleting pipeline $PIPELINE of $DATE ($ref)"
curl -k -H "$HEADER" -X "DELETE" ${GITLAB}/api/v4$URLADD/pipelines/$PIPELINE 2> /dev/null
else
echo "Would delete pipeline $PIPELINE of $DATE ($ref / $status)"
fi
fi
else
echo "Saving $ref ($status / $tag / $DATE)"
# for JOB in `curl -k -H "$HEADER" ${GITLAB}/api/v4$URLADD/pipelines/$PIPELINE/jobs 2> /dev/null|jq '.[]|.id'`; do
# echo -n " Erasing Job $JOB "
# curl -X POST -k -H "$HEADER" ${GITLAB}/api/v4$URLADD/jobs/${JOB}/erase 2> /dev/null|jq '.|.name'
# echo ""
# done
fi
else
echo "($ref)"
fi
done
done
# Deleting Jobs:
#for p in `curl -k -H "$HEADER" ${GITLAB}/api/v4$URLADD/pipelines?per_page=100 2> /dev/null|jq '.[]|(.id,.status)'` ; do
# if [ -z "$PING" ] ; then
# PING="pong"
# PIPELINE=$p
# else
# PING=
# echo "Checking Pipeline $PIPELINE ($D)."
# DATE=$(curl -k -H "$HEADER" ${GITLAB}/api/v4$URLADD/pipelines/$PIPELINE 2> /dev/null|jq '.finished_at'|sed -e 's/^"\(.*\)T.*/\1/g')
# # echo date: $DATE
# if [ "$DATE" != "null" ] ; then
# D=$(date -d $DATE +%s)
# # echo "$D vs $REF"
# if [ "$D" -lt "$REF" ] ; then
# echo "Working on Pipeline $PIPELINE"
# for JOB in `curl -k -H "$HEADER" ${GITLAB}/api/v4$URLADD/pipelines/$PIPELINE/jobs 2> /dev/null|jq '.[]|.id'`; do
# echo -n " Erasing Job $JOB "
# curl -X POST -k -H "$HEADER" ${GITLAB}/api/v4$URLADD/jobs/${JOB}/erase 2> /dev/null|jq '.|.name'
# done
# fi
# fi
# fi
#done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment