Created
December 20, 2021 22:01
-
-
Save gohoyer/73f9ed7919954df55990b61afd716b2e to your computer and use it in GitHub Desktop.
Bash script to deal with the Gitlab API pagination
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# This is a Gitlab Pagination Example on Bash for the forks API endpoint. | |
# | |
# Reference for the Gitlab API`s on 10.8.7: https://gitlab.com/gitlab-org/gitlab-foss/-/blob/v10.8.7/doc/api/README.md | |
script_banner() | |
{ | |
echo "+----------------------------------------------------------------------------------+" | |
printf "| %-80s |\n" "$(date)" | |
echo "| |" | |
printf "|$(tput bold) %-80s $(tput sgr0)|\n" "$@" | |
echo "+----------------------------------------------------------------------------------+" | |
SECONDS=0 | |
} | |
time_spent() | |
{ | |
echo "Took $SECONDS seconds to run." | |
} | |
script_banner "Starting script" | |
# Gitlab | |
GITLAB_ADDRESS="<https://your.gitlab.address.com>" | |
GITLAB_API="$GITLAB_ADDRESS/api/v4/" | |
GITLAB_TOKEN="you_token" | |
GIT_PROJECT_ID="you_project_id" | |
FORKS_ATTRIBUTES="per_page=100&order_by=last_activity_at&sort=asc" | |
DATE_COMMAND="date" | |
# List all forks from project | |
# (dealing with pagination on API return) | |
# (pass --include to curl in order to get the response headers) | |
script_banner "Listing forks - Getting first page" | |
RESPONSE=$( \ | |
curl --include --silent --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}"\ | |
"${GITLAB_API}projects/${GIT_PROJECT_ID}/forks?${FORKS_ATTRIBUTES}" \ | |
) || { script_banner "ERROR: Could not retrieve existing forks."; exit $?; } | |
# Get the last page from the attribute x-total-pages from the api response | |
LAST_PAGE=$(echo "$RESPONSE" | grep "x-total-pages" | sed 's|x-total-pages: ||g' | tr -d '\r') | |
# Get the forks returned on the first page | |
# grep "\[" ==> ignore headers and get only the data portion. | |
ALL_FORKS=$(echo "$RESPONSE" | grep "\[" | jq '.[] | "\(.id) \(.path_with_namespace) \(.last_activity_at)"') | |
time_spent | |
# If the list of forks has more than one page | |
if [[ "$LAST_PAGE" -gt "1" ]]; then | |
# Get the next pages | |
for PAGE in $( seq 2 "$LAST_PAGE" ); do | |
script_banner "Listing forks - Getting page $PAGE / $LAST_PAGE" | |
# Getting ID, Path and Last Activity | |
RESPONSE=$( \ | |
curl --silent --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}"\ | |
"${GITLAB_API}projects/${GIT_PROJECT_ID}/forks?${FORKS_ATTRIBUTES}&page=${PAGE}" \ | |
| jq '.[] | "\(.id) \(.path_with_namespace) \(.last_activity_at)"'\ | |
) || { script_banner "ERROR: Could not retrieve existing forks."; exit $?; } | |
ALL_FORKS+=$'\n'"$RESPONSE" | |
time_spent | |
done | |
fi | |
script_banner "$(echo "$ALL_FORKS" | wc -l) forks found." | |
if [ "$ALL_FORKS" != '' ]; then | |
# Iterate over each fork found | |
while IFS= read -r FORK | |
do | |
# Split the FORK variable into an array | |
# 0 - id | |
# 1 - path_with_namespace | |
# 2 - last_activity_at | |
# obs: the sed below is just to remove the leading and trailing double quotes | |
IFS=' ' read -ra FORK_ARR <<< "$(echo "$FORK" | sed 's/^"//;s/"$//')" | |
unset IFS | |
FORK_ID=${FORK_ARR[0]} | |
FORK_PATH=${FORK_ARR[1]} | |
FORK_LAST_ACTIVITY=$($DATE_COMMAND --date "${FORK_ARR[2]}" +'%s') | |
echo "Fork ID: $FORK_ID | Path: $FORK_PATH | Last Activity: $FORK_LAST_ACTIVITY" | |
done < <(printf '%s\n' "$ALL_FORKS") | |
else | |
script_banner "No forks detected. Exiting."; exit 0 | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment