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
FlagFilter
-w, --workflowWorkflow name, filename, or ID
-b, --branchHead branch
-s, --statusqueued, in_progress, completed, success, failure, cancelled, skipped, timed_out, action_required, stale, startup_failure, and more
-e, --eventTriggering event, e.g. push, pull_request, workflow_dispatch, schedule
-u, --userWho triggered it
-c, --commitCommit SHA
--createdDate, with >=, <, or an A..B range
-L, --limitMax runs, default 20
-a, --allInclude 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
FlagMeaning
-f, --raw-fieldkey=value, always a literal string
-F, --fieldkey=value with @file and @- file/stdin syntax
-r, --refBranch or tag holding the workflow version to run
--jsonRead 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.