Last active
November 28, 2024 07:12
-
-
Save serpro69/405d3032246e26923c7c7d61551ac525 to your computer and use it in GitHub Desktop.
github workflow result polling
This file contains hidden or 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 | |
set -e | |
show_help() { | |
echo "Usage: ./test.sh <REPO_OWNER> <REPO_NAME> <WORKFLOW_ID> <COMMIT_SHA>" | |
echo "" | |
echo "This script polls the status of a GitHub Actions workflow run." | |
echo "" | |
echo "Arguments:" | |
echo " REPO_OWNER The owner of the repository (e.g., \"octocat\")." | |
echo " REPO_NAME The name of the repository (e.g., \"Hello-World\")." | |
echo " WORKFLOW_ID The ID of the workflow to check." | |
echo " COMMIT_SHA The sha of the git commit to check against." | |
echo "" | |
echo "Requirements:" | |
echo " - github cli (gh) must be installed and authenticated" | |
echo " - jq must be installed and available in the PATH" | |
echo "" | |
echo "The script will poll the workflow status every 30 seconds for a maximum of 30 attempts." | |
echo "It will stop polling if the workflow reaches a final state (\"completed\", \"skipped\", \"timed_out\")." | |
echo "" | |
echo "Example:" | |
echo " ./test.sh octocat Hello-World test.yml 5d36b88bb697a2d778f024048bafabd443d74503" | |
} | |
if [[ "$1" == "-h" || "$1" == "--help" ]]; then | |
show_help | |
exit 0 | |
fi | |
# GitHub API URL for the workflow run | |
REPO_OWNER=$1 | |
REPO_NAME=$2 | |
WORKFLOW_ID=$3 | |
COMMIT_SHA=$4 | |
POLL_INTERVAL=30 # Poll every X seconds | |
POLL_ATTEMPTS=30 # Number of polling attempts | |
MAX_DURATION=$((POLL_ATTEMPTS * POLL_INTERVAL)) | |
# States to stop polling | |
final_states=("completed" "skipped" "timed_out") | |
if ! which gh &> /dev/null; then | |
echo "github cli (gh) is not installed" | |
exit 1 | |
fi | |
if ! which jq &> /dev/null; then | |
echo "jq is not installed" | |
exit 1 | |
fi | |
contains() { | |
local value="$1" | |
shift | |
for item in "$@"; do | |
if [[ "$item" == "$value" ]]; then | |
return 0 | |
fi | |
done | |
return 1 | |
} | |
if ! git rev-parse --is-inside-work-tree &> /dev/null; then | |
echo "Not in a git repository." | |
exit 1 | |
fi | |
elapsed_time=0 | |
while true; do | |
echo "Checking workflow status..." | |
# shellcheck disable=SC2086 | |
response=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" \ | |
/repos/${REPO_OWNER}/${REPO_NAME}/actions/workflows/${WORKFLOW_ID}/runs \ | |
| jq -r --arg sha "${COMMIT_SHA}" '(.workflow_runs | map(select(.head_sha == $sha)) | first) // "null"') | |
if [[ -z "$response" ]] || [[ "$response" == 'null' ]]; then | |
echo "No workflow run found for the commit ${COMMIT_SHA}." | |
exit 1 | |
fi | |
status=$(echo "$response" | jq -r '.status') | |
echo "Current status: $status" | |
if contains "$status" "${final_states[@]}"; then | |
echo "Final status reached: $status" | |
conclusion=$(echo "$response" | jq -r '.conclusion') | |
echo "Workflow conclusion: $conclusion" | |
if [[ "$conclusion" == "success" ]]; then | |
exit 0 | |
else | |
exit 1 | |
fi | |
fi | |
if [[ $elapsed_time -ge $MAX_DURATION ]]; then | |
echo "Maximum polling duration of ${MAX_DURATION} seconds exceeded." | |
exit 1 | |
fi | |
echo "Status not final. Polling again in $POLL_INTERVAL seconds..." | |
sleep $POLL_INTERVAL | |
elapsed_time=$((elapsed_time + POLL_INTERVAL)) | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment