Skip to content

Instantly share code, notes, and snippets.

@WoozyMasta
Created May 28, 2025 10:23
Show Gist options
  • Save WoozyMasta/a710edd8f324fed6b02219c7a42db158 to your computer and use it in GitHub Desktop.
Save WoozyMasta/a710edd8f324fed6b02219c7a42db158 to your computer and use it in GitHub Desktop.
Recursive delete all badges in GitLab projects
#!/usr/bin/env bash
set -euo pipefail
# Recursive delete all badges in GitLab projects
: "${GITLAB_HOST:?}"
: "${GITLAB_TOKEN:?}"
: "${GITLAB_GROUP_ID:?}"
gitlab() {
curl -sSfH "PRIVATE-TOKEN: $GITLAB_TOKEN" \
--url "https://$GITLAB_HOST/api/v4/$1" "${@:2}"
}
gitlab::paginate() {
local page=1 per_page=100 response on_page
while :; do
response="$(
gitlab "$1?page=$page&per_page=$per_page" "${@:2}"| jq -cer
)"
on_page="$(jq -er 'length' <<<"$response")"
[ "$on_page" -eq 0 ] && break
echo "$response"
[ "$on_page" -lt "$per_page" ] && break
((page++)) || :
done
}
delete_badges() {
local project_id=$1
while IFS=$'\t' read -r id name; do
printf '%-10s%s\n' Badge: "$name"
gitlab "projects/$project_id/badges/$id" -X DELETE
done < <(
gitlab::paginate "projects/$project_id/badges" \
| jq -er '.[] | [.id, .name] | @tsv'
)
}
process_group() {
local group_id=$1
# Delete badges for all projects in this group
while IFS=$'\t' read -r project_id path; do
printf '%-10s%s\n' Project: "$path"
delete_badges "$project_id" || echo "Fail $path"
done < <(
gitlab::paginate "groups/$group_id/projects" \
| jq -er '.[] | [.id, .path_with_namespace] | @tsv'
)
# Recursion into subgroups
while IFS=$'\t' read -r subgroup_id subgroup_name; do
printf '%-10s%s\n' Group: "$subgroup_name"
process_group "$subgroup_id"
done < <(
gitlab::paginate "groups/$group_id/subgroups" \
| jq -er '.[] | [.id, .full_path] | @tsv'
)
}
# kick off
process_group "$GITLAB_GROUP_ID"
echo "Done."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment