I needed to find all the places in our GitHub org that were using a deprecated GitHub Actions runner label. We were migrating from runs-on: self-hosted to runs-on: ${{ vars.RUNNER_STANDARD }}, and I needed to find every workflow file that still used the old pattern. The gh search code command is perfect for this kind of organisation-wide search.

Basic search:

gh search code 'pattern' --owner my-org

Search in a specific path:

gh search code 'runs-on: self-hosted' --owner my-org -- path:.github

Get JSON output:

gh search code 'pattern' --owner my-org --json repository,path

The -- separator is important if your search term has special characters.

Open results in the browser:

gh search code 'pattern' --owner my-org --web

Exclude certain patterns using NOT:

gh search code '"vars.RUNNER" NOT RUNNER_STANDARD' --owner my-org

The quoting is fiddly. Double quotes inside single quotes work for exact matches.

Real example: finding deprecated runner labels Link to heading

Here’s what I actually ran to find all our deprecated runner configurations:

gh search code 'runs-on: self-hosted' --owner my-org -- path:.github/workflows

This found 47 workflow files across 23 repositories. I then refined it to exclude files that had already been migrated:

gh search code '"runs-on: self-hosted" NOT RUNNER_STANDARD' --owner my-org

This narrowed it down to 12 files that still needed updating. Much better than manually checking every repo.

Search syntax tips Link to heading

The search syntax is based on GitHub’s code search, which has some quirks:

Exact phrase matching: Use double quotes

gh search code '"exact phrase"' --owner my-org

Boolean operators: Use AND, OR, NOT (must be uppercase)

gh search code 'kubernetes AND docker' --owner my-org
gh search code 'TODO NOT FIXME' --owner my-org

Path filtering: Use path: or -- path: (the -- separator is recommended)

gh search code 'pattern' --owner my-org -- path:.github/workflows
gh search code 'pattern' --owner my-org -- path:*.py

Language filtering: Search only in specific languages

gh search code 'function' --owner my-org -- language:javascript

File name matching: Use filename:

gh search code 'pattern' -- filename:Dockerfile

JSON output for scripting Link to heading

The --json flag is incredibly useful for automation:

gh search code 'deprecated-function' --owner my-org --json repository,path,url | \
  jq -r '.[] | "\(.repository.name): \(.path)"'

This gives you a clean list of repository and file paths, which you can pipe into other tools or scripts.

Limits and gotchas Link to heading

  • GitHub has rate limits on code search (10 requests per minute for authenticated users)
  • Results are limited to 100 matches by default
  • Private repositories require appropriate permissions
  • Very common terms might timeout or return incomplete results

For very large searches across many repos, you might be better off cloning the repos and using ripgrep locally. But for most cases, gh search code is perfect.