gh run watch --exit-status: Gate on a Run
gh run watch --exit-status follows a workflow run and returns a failing exit code if the run did not succeed.
When one job triggers another workflow and must fail if that workflow fails, --exit-status turns the run result into a gating exit code.
What it does
gh run watch streams the live status of a workflow run until it completes. Plain watch always exits 0; adding --exit-status makes the command exit non-zero when the watched run concludes in failure, so the calling step fails too.
Common usage
gh run watch 1234567890 --exit-status
gh run watch 1234567890 --exit-status --interval 10
gh run watch 1234567890 --compact --exit-statusFlags
| Flag | What it does |
|---|---|
| --exit-status | Exit non-zero if the run fails |
| -i, --interval <n> | Refresh interval in seconds (default 3) |
| --compact | Show only failed steps while watching |
| <run-id> | The workflow run to watch |
| -R, --repo <owner/repo> | Target a specific repository |
In CI
Set GH_TOKEN and permissions: { actions: read }. Pass the run ID explicitly; a bare gh run watch needs the interactive picker. Capture the dispatched run ID (for example from gh run list --json databaseId after a workflow run) and feed it to watch.
Common errors in CI
"gh: To use GitHub CLI in a GitHub Actions workflow, set the GH_TOKEN environment variable" means GH_TOKEN is unset. If watch returns 0 even though the run failed, --exit-status was omitted. A headless gh run watch with no ID fails because the picker requires a terminal.
Using this in CI
CI checkouts are shallow and detached by default, which changes the answer this command gives you. Commands that read history, branch names, or tags need the checkout configured for it.
- uses: actions/checkout@v4
with:
fetch-depth: 0 # history, tags, and git describe all need this
- run: |
git rev-parse --is-shallow-repository # expect false
git rev-parse --abbrev-ref HEAD # prints HEAD when detached