Skip to content

Instantly share code, notes, and snippets.

@serpro69
Last active November 28, 2024 07:12
Show Gist options
  • Save serpro69/405d3032246e26923c7c7d61551ac525 to your computer and use it in GitHub Desktop.
Save serpro69/405d3032246e26923c7c7d61551ac525 to your computer and use it in GitHub Desktop.
github workflow result polling
#!/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