Skip to content

Instantly share code, notes, and snippets.

@gohoyer
Created December 20, 2021 22:01
Show Gist options
  • Save gohoyer/73f9ed7919954df55990b61afd716b2e to your computer and use it in GitHub Desktop.
Save gohoyer/73f9ed7919954df55990b61afd716b2e to your computer and use it in GitHub Desktop.
Bash script to deal with the Gitlab API pagination
#!/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