Skip to content
Back to skills

Gh Workflow Monitoring

ASecurity

`gh run watch` — block until a GitHub Actions run finishes, no polling loop. Use when waiting for CI after a push or following a triggered workflow to completion.

  • 58 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added February 8, 2026
devopsbashexpressdebugginggitdatabase

Works with

  • cli

Security analysis

A100/100

Scanned September 3, 2026

npx -y skills add laurigates/claude-plugins --skill gh-workflow-monitoring --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Gh Workflow Monitoring?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Gh Workflow Monitoring
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/laurigates-gh-workflow-monitoring/badge)](https://www.skillsdirectory.com/skills/laurigates-gh-workflow-monitoring)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: gh-workflow-monitoring
description: "`gh run watch` — block until a GitHub Actions run finishes, no polling loop. Use when waiting for CI after a push or following a triggered workflow to completion."
user-invocable: false
allowed-tools: Bash(gh run *), Bash(gh workflow *), Bash(gh pr *), Read
created: 2025-01-16
modified: 2026-08-15
reviewed: 2026-04-25
---

# GitHub Workflow Monitoring

## When to Use This Skill

| 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 |
| Chaining on a run's outcome with `gh run watch --exit-status` | Use `github-actions-plugin:github-actions-inspection` to read a finished run's logs and stack traces |
| 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.

## Core Commands

### Watch a Run Until Completion

```bash
# 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) |

### Find Runs to Monitor

```bash
# 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`

### View Run Details

```bash
# 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
```

### Extract One Step's Bare Output from `--log`

`gh 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:

```bash
# 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:

```bash
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.

## Workflow Patterns

### Trigger and Watch

```bash
# 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
```

### Wait for PR Checks

```bash
# 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
```

### Monitor Multiple Runs

```bash
# 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'
```

## Agentic Patterns

### Find and Watch Latest Run

```bash
# 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
```

### Diagnose Failures

```bash
# 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
```

### CI Integration Flow

```bash
# 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
```

## Agentic Optimizations

| 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` |

## Why `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`**:
- **Blocking**: Waits until run completes - no timeout management needed
- **Live updates**: Shows progress during execution
- **Exit codes**: Returns 0 on success, non-zero on failure
- **Compact mode**: `--compact` reduces output to relevant steps only
- **Chain-friendly**: Use with `&&` for conditional next steps

## Error Handling

```bash
# 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
```

## Context Expressions

Use in command frontmatter:

```markdown
- 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`
```

## See Also

- **gh-cli-agentic** - General GitHub CLI patterns
- **git-branch-pr-workflow** - PR and branch workflows

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.