GitHub CLI Cheatsheet
Workflow Runs
Use this GitHub CLI reference while you build software engineering projects, review code, or refresh the syntax you reach for most.
Listing Runs
gh run list # 20 most recent runs gh run list --limit 100 gh run list --workflow ci.yml gh run list --workflow "Deploy" # by name or by filename gh run list --branch main gh run list --status failure gh run list --status in_progress gh run list --event pull_request gh run list --user monalisa gh run list --commit 9a3f21c gh run list --created ">=2026-01-01" gh run list --created "2026-01-01..2026-02-01" gh run list --all # include disabled workflows gh run list --json databaseId,name,conclusion,headBranch
| Flag | Filter |
|---|---|
-w, --workflow | Workflow name, filename, or ID |
-b, --branch | Head branch |
-s, --status | queued, in_progress, completed, success, failure, cancelled, skipped, timed_out, action_required, stale, startup_failure, and more |
-e, --event | Triggering event, e.g. push, pull_request, workflow_dispatch, schedule |
-u, --user | Who triggered it |
-c, --commit | Commit SHA |
--created | Date, with >=, <, or an A..B range |
-L, --limit | Max runs, default 20 |
-a, --all | Include disabled workflows |
Note that --status mixes statuses and conclusions in one flag, so --status failure and --status completed both work.
Inspecting a Run
With no run ID, gh prompts you to pick from the recent list.
gh run view # interactive picker gh run view 12345678 gh run view 12345678 --verbose # show every job's steps gh run view 12345678 --job 98765 # one job gh run view 12345678 --log # the full log, all jobs gh run view 12345678 --log-failed # only the failing steps gh run view 12345678 --job 98765 --log gh run view 12345678 --attempt 2 # a specific re-run attempt gh run view 12345678 --exit-status # non-zero if the run failed gh run view 12345678 --web gh run view 12345678 --json jobs \ --jq '.jobs[] | select(.conclusion=="failure") | .name'
--log-failed is the debugging entry point. It skips every passing job and prints just the steps that broke, which is usually a few dozen lines instead of a few thousand.
gh run view --log-failed | grep -i "error" gh run view 12345678 --log | less
Watching, Rerunning, Cancelling
gh run watch # pick a run, follow it live gh run watch 12345678 gh run watch 12345678 --interval 5 # poll every 5s, default 3 gh run watch 12345678 --compact # only relevant and failed steps gh run watch 12345678 --exit-status # non-zero if the run fails
gh run rerun 12345678 # rerun everything gh run rerun 12345678 --failed # only failed jobs plus dependencies gh run rerun 12345678 --job 98765 gh run rerun 12345678 --debug # rerun with debug logging enabled gh run cancel 12345678 gh run cancel 12345678 --force gh run delete 12345678
--exit-status is what makes watch scriptable, and it composes with a desktop notification:
gh run watch 12345678 --exit-status && echo "green" || echo "red" gh run list --limit 1 --json databaseId --jq '.[0].databaseId' \ | xargs gh run watch --exit-status
--failed reuses the successful jobs instead of burning minutes redoing them, so prefer it over a blind rerun on a flaky suite.
Artifacts
gh run download # pick a run interactively gh run download 12345678 # every artifact into ./ gh run download 12345678 --dir ./out gh run download 12345678 --name build-linux gh run download 12345678 --name a --name b gh run download 12345678 --pattern "coverage-*" gh run download 12345678 --pattern "*.zip" --dir /tmp/art
Each artifact lands in its own subdirectory unless you download exactly one by --name. Artifacts expire (90 days by default, less if the repo lowers it), and a run whose artifacts expired downloads nothing rather than erroring loudly.
Workflows
gh workflow list # active workflows gh workflow list --all # include disabled ones gh workflow list --limit 100 gh workflow list --json id,name,state,path gh workflow view ci.yml gh workflow view "CI" # by display name gh workflow view ci.yml --yaml # print the YAML source gh workflow view ci.yml --ref develop gh workflow view ci.yml --web gh workflow enable ci.yml gh workflow disable ci.yml
A workflow disabled for 60 days of repository inactivity comes back with gh workflow enable, and scheduled workflows are the usual victims.
Dispatching a Workflow
gh workflow run fires a workflow_dispatch event, so the workflow file must declare that trigger.
gh workflow run deploy.yml gh workflow run deploy.yml --ref release-2.x gh workflow run deploy.yml -f environment=staging -f dry_run=true gh workflow run deploy.yml -F version=1.2.3 -F notes=@notes.md gh workflow run deploy.yml --json < inputs.json echo '{"environment":"prod"}' | gh workflow run deploy.yml --json gh workflow run deploy.yml # prompts for declared inputs
| Flag | Meaning |
|---|---|
-f, --raw-field | key=value, always a literal string |
-F, --field | key=value with @file and @- file/stdin syntax |
-r, --ref | Branch or tag holding the workflow version to run |
--json | Read the whole inputs object as JSON from stdin |
Dispatch returns immediately with no run ID, so to follow the run you list first:
gh workflow run deploy.yml -f environment=staging sleep 5 gh run list --workflow deploy.yml --limit 1 gh run watch "$(gh run list --workflow deploy.yml --limit 1 \ --json databaseId --jq '.[0].databaseId')" --exit-status
Actions Cache
Cache entries count against a repository quota, and a poisoned cache is a classic cause of "it fails only in CI".
gh cache list gh cache list --limit 100 gh cache list --key node-modules- # key prefix match gh cache list --ref refs/heads/main gh cache list --ref refs/pull/123/merge gh cache list --sort size_in_bytes --order desc gh cache list --json id,key,sizeInBytes,lastAccessedAt gh cache delete 1234567890 # by ID gh cache delete node-modules-abc123 # by exact key gh cache delete --all gh cache delete --all --ref refs/heads/stale-branch gh cache delete --all --succeed-on-no-caches
--sort accepts created_at, last_accessed_at (the default), or size_in_bytes. --succeed-on-no-caches only works with --all, and exists so a cleanup step in CI does not fail on an already-empty cache.