From git-plugin
Monitors GitHub Actions workflow runs using blocking `gh run watch` instead of polling loops. Use when waiting for CI after push, following a workflow to completion, or diagnosing failed runs with `--log-failed`.
How this skill is triggered — by the user, by Claude, or both
Slash command
/git-plugin:gh-workflow-monitoringThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
| Use this skill when... | Use the alternative when... |
| Use this skill when... | Use the alternative when... |
|---|---|
Watching a workflow run until it completes via blocking gh run watch | Use gh-cli-agentic for one-shot JSON queries of run/PR check state |
| Waiting for CI after a push, or triggering a workflow and following progress | Use git-fix-pr to diagnose AND auto-correct failing checks on a PR |
Diagnosing a failed run with gh run view --log-failed | Use git-pr-feedback to address reviewer comments rather than CI failures |
| Finding the latest in-progress run for a workflow | Use gh-cli-agentic to list completed runs by status filter |
Watch and monitor GitHub Actions workflow runs using gh run watch - a blocking command that follows runs until completion without needing timeouts or polling.
# Watch most recent run (interactive selection if multiple)
gh run watch
# Watch specific run ID
gh run watch $RUN_ID
# Compact mode - show only relevant/failed steps (recommended for agents)
gh run watch $RUN_ID --compact
# Exit with non-zero if run fails (useful for chaining)
gh run watch $RUN_ID --exit-status
# Combined: compact output, fail on error
gh run watch $RUN_ID --compact --exit-status
Key Flags:
| Flag | Description |
|---|---|
--compact | Show only relevant/failed steps (less output) |
--exit-status | Exit non-zero if run fails |
-i, --interval | Refresh interval in seconds (default: 3) |
# List in-progress runs
gh run list --status in_progress --json databaseId,name,status,createdAt
# List runs for specific workflow
gh run list -w "CI" --json databaseId,name,status,conclusion -L 5
# List runs for current branch
gh run list --branch $(git branch --show-current) --json databaseId,name,status
# List runs triggered by specific event
gh run list --event push --json databaseId,name,status -L 10
# List failed runs
gh run list --status failure --json databaseId,name,conclusion,createdAt -L 5
Status Values: queued, in_progress, completed, waiting, pending, requested
Conclusion Values (when completed): success, failure, cancelled, skipped, neutral, timed_out
# Get run status with jobs
gh run view $RUN_ID --json status,conclusion,jobs,name,createdAt
# View with step details
gh run view $RUN_ID --verbose
# Get failed logs only (most useful for debugging)
gh run view $RUN_ID --log-failed
# Get full logs
gh run view $RUN_ID --log
# View specific job
gh run view --job $JOB_ID
# Open in browser
gh run view $RUN_ID --web
--loggh run view --log is tab-delimited: every line is
<job>\t<step>\t<timestamp> <log line>. To scrape one step's stdout back to
its bare form — dropping the job and step columns and the per-line
timestamp — filter to the step name (field-2 substring) and strip the
timestamp, which is the first space-delimited token of field 3:
# All lines from the step whose name contains "clean warm run", de-columned
gh run view $RUN_ID --log \
| awk -F'\t' '/clean warm run/ { sub(/^[^ ]* /, "", $3); print $3 }'
This is the durable way to read a succeeded step's output for structured
markers — RESULT …, a PASS/FAIL line, a JSON blob a job printed — when
--log-failed doesn't apply (nothing failed; you just want the output). The
whole job's log is one stream, so narrow to the step first, then grep the
markers:
gh run view $RUN_ID --log \
| awk -F'\t' '/bench \(clean warm/ { sub(/^[^ ]* /, "", $3); print $3 }' \
| grep -E 'RESULT|SANITY'
Notes: match the step name as it appears in the workflow's name: (the awk
/pattern/ is a plain regex over the whole tab-joined line — anchor with a
distinctive substring to avoid matching the same text inside a log line);
[^ ]* matches the timestamp because it never contains a space, so a
mangled first token can't over-strip the line.
# Trigger workflow and immediately watch it
gh workflow run "CI" && sleep 2 && gh run watch --compact --exit-status
# Trigger with inputs
gh workflow run "Deploy" -f environment=staging -f version=1.2.3
# Get the latest run for a PR's head commit
RUN_ID=$(gh run list --branch $(gh pr view $PR --json headRefName --jq '.headRefName') -L 1 --json databaseId --jq '.[0].databaseId')
gh run watch $RUN_ID --compact --exit-status
# List all in-progress runs and watch the first one
gh run list --status in_progress --json databaseId,name --jq '.[0]'
# Get all active run IDs
gh run list --status in_progress --json databaseId --jq '.[].databaseId'
# 1. Find the run
RUN_ID=$(gh run list -L 1 --json databaseId --jq '.[0].databaseId')
# 2. Watch it (blocking - waits until complete)
gh run watch $RUN_ID --compact --exit-status
# 1. Find failed run
gh run list --status failure -L 1 --json databaseId,name,conclusion
# 2. Get failed logs
gh run view $RUN_ID --log-failed
# After pushing, find and watch the triggered run
git push origin HEAD
sleep 5 # Wait for GitHub to register the run
RUN_ID=$(gh run list --branch $(git branch --show-current) -L 1 --json databaseId --jq '.[0].databaseId')
gh run watch $RUN_ID --compact --exit-status
| Context | Command |
|---|---|
| Watch until done | gh run watch $ID --compact --exit-status |
| Find in-progress | gh run list --status in_progress --json databaseId,name |
| Latest run ID | gh run list -L 1 --json databaseId --jq '.[0].databaseId' |
| Failed logs | gh run view $ID --log-failed |
| Scrape a succeeded step's stdout | gh run view $ID --log | awk -F'\t' '/STEP/{sub(/^[^ ]* /,"",$3);print $3}' |
| Trigger + watch | gh workflow run "$NAME" && sleep 2 && gh run watch --compact |
| PR run status | gh pr checks $PR --json name,state,conclusion |
gh run watch Over Polling| Approach | Problem |
|---|---|
sleep + poll | Wastes time, may miss completion, timeout complexity |
| Webhook | Requires infrastructure, not CLI-friendly |
gh run watch | Blocks until complete, shows progress, returns exit code |
Benefits of gh run watch:
--compact reduces output to relevant steps only&& for conditional next steps# Watch with error handling
gh run watch $RUN_ID --compact --exit-status && echo "Success" || echo "Failed"
# Check if run exists before watching
gh run view $RUN_ID --json status 2>/dev/null && gh run watch $RUN_ID --compact
Use in command frontmatter:
- In-progress runs: !`gh run list --status in_progress --json databaseId,name --jq '.[0]'`
- Latest run: !`gh run list -L 1 --json databaseId,name,status,conclusion`
npx claudepluginhub laurigates/claude-plugins --plugin git-pluginManages GitHub Actions workflows via gh CLI: check CI status, list/view/watch/rerun runs and logs.
Monitors GitHub Actions workflow runs, identifies failing jobs, extracts error logs, and summarizes diagnostics. Useful for checking CI status after pushes or investigating failures.
Monitors GitHub Actions CI runs until completion, reporting pass/fail/timeout verdicts per run. Useful after pushing code or checking PR build status.