Audit GitHub Actions Workflows with gh workflow list

A workflow that is missing from gh workflow list may not be gone, just disabled and hidden. You will finish with a repeatable way to see which GitHub Actions workflows a repository exposes, disabled ones included. The examples use GitHub CLI 2.87.3, installed with the gh package on the system used for this guide. Allow about five minutes if gh is already authenticated.

Before you start

You need the gh command and access to the repository you want to inspect. This is a read-only listing command. It does not enable, disable, run or edit a workflow, and it needs no elevated privileges. Authentication and repository permissions still decide whether GitHub returns the workflow data.

Choose the repository explicitly when you are outside a checkout, or when you want to be sure you are not inspecting the wrong remote. Replace the example values with your own owner and repository:

gh workflow list --repo OWNER/REPO

For example:

gh workflow list --repo cli/cli

Warning: The default listing hides disabled workflows. That suits a quick operational view but is an easy audit trap: an absent entry does not prove that a workflow file has been removed.

1. List the workflows currently visible

Run the basic command first. It lists workflow files and, by default, leaves out disabled ones:

gh workflow list --repo OWNER/REPO

Use the output as a quick check that you picked the intended repository. The installed command supports the alias gh workflow ls, but the longer spelling is clearer in scripts and notes.

Checkpoint: If the command reports that the repository cannot be found or accessed, check OWNER/REPO, the GitHub host and your gh login before changing any workflow files.

2. Include disabled workflows for an audit

Add --all when you need the complete set GitHub returns:

gh workflow list --repo OWNER/REPO --all

This changes what is displayed, not the state of any workflow. It is the right form for checking whether an old workflow is still registered but disabled, or for comparing the repository's workflow inventory with a change record.

Do not confuse this option with enabling workflows. The separate gh workflow enable command changes repository state, and nothing in this guide calls it.

3. Request stable JSON fields

Human-readable output is fine at a terminal, but names and spacing make poor script input. Ask for JSON and pick the fields this command supports:

gh workflow list \
  --repo OWNER/REPO \
  --all \
  --json id,name,path,state

The available fields are id, name, path, and state. The response is an array with one JSON object per workflow. For a small, concrete check against the installed CLI, this command was run successfully:

gh workflow list --repo cli/cli --json name,path,state --limit 3

It returned JSON objects containing names such as Unit and Integration Tests, paths such as .github/workflows/go.yml, and states such as active. Repository contents change, so treat those values as an example of the shape, not a permanent inventory.

4. Filter the JSON with jq

Use --jq to pull out selected values. For example, print each workflow name and path as tab-separated text:

gh workflow list \
  --repo OWNER/REPO \
  --all \
  --json name,path,state \
  --jq '.[] | [.name, .path, .state] | @tsv'

To find disabled entries only, filter on the state field:

gh workflow list \
  --repo OWNER/REPO \
  --all \
  --json name,path,state \
  --jq '.[] | select(.state != "active") | [.name, .path, .state] | @tsv'

The --jq option applies a jq expression inside gh; it does not install or invoke a separate system utility. If your expression prints nothing, rerun the same command without --jq first. An empty result may simply mean that no object matched.

5. Control large results

The default maximum is 50 workflows. Set --limit deliberately when a repository or organisation has more entries:

gh workflow list \
  --repo OWNER/REPO \
  --all \
  --limit 200 \
  --json id,name,path,state

A limit is a maximum to fetch, not a promise that many workflows exist. For an inventory that must be complete, pick a value that suits the repository and check that your own limit is not truncating the result. The documented default is 50.

Formatting alternatives and common traps

Done means