# gh extension install: Add gh Extensions in CI

> gh extension install adds a third-party or local gh extension. Reference for --pin, gh ext list, the already-installed case, and the auth errors in CI.

Source: https://latchkey.dev/learn/command-reference/gh-extension-install  
Updated: 2026-06-30

gh extension install adds a gh CLI extension from a repository, extending gh with new subcommands.

Workflows that depend on a community gh extension install it as a setup step, ideally pinned to a release for reproducibility.

## What it does

gh extension install adds an extension hosted in a GitHub repository, making its gh-prefixed commands available as gh subcommands. --pin locks the extension to a specific tag or commit so the version is reproducible.

## Common usage

```Terminal
gh extension install owner/gh-myext
gh extension install owner/gh-myext --pin v1.4.0
gh extension list
gh extension install .
```

## Flags

| Flag | What it does |
| --- | --- |
| <owner/repo> | Extension repository to install |
| --pin <tag|sha> | Pin to a specific release tag or commit |
| --force | Force a (re)install |
| . | Install the extension in the current directory |

## In CI

Set GH_TOKEN so installs from private extension repos authenticate. Always --pin a version in CI; tracking the default branch makes builds non-reproducible. Run gh extension list to confirm the install, and remember the extension binary must support the runner OS and architecture.

## Common errors in CI

"there is already an installed extension that provides the X command" means it is installed; use --force or skip. "gh: To use GitHub CLI in a GitHub Actions workflow, set the GH_TOKEN environment variable" appears when a private extension repo needs auth. "X is not a gh extension" means the repo is missing a gh-X executable.

## 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.

```.github/workflows/ci.yml
- 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
```

> `git rev-parse --abbrev-ref HEAD` returns the literal string `HEAD` on a detached checkout rather than a branch name. On GitHub Actions read `github.ref_name` instead; the git command cannot know what it was checked out for.

## FAQ

### gh extension install: Add gh Extensions in CI?

Workflows that depend on a community gh extension install it as a setup step, ideally pinned to a release for reproducibility.

### What it does?

gh extension install adds an extension hosted in a GitHub repository, making its gh-prefixed commands available as gh subcommands. --pin locks the extension to a specific tag or commit so the version is reproducible.

### In CI?

Set GH_TOKEN so installs from private extension repos authenticate. Always --pin a version in CI; tracking the default branch makes builds non-reproducible. Run gh extension list to confirm the install, and remember the extension binary must support the runner OS and architecture.

### Common errors in CI?

"there is already an installed extension that provides the X command" means it is installed; use --force or skip. "gh: To use GitHub CLI in a GitHub Actions workflow, set the GH_TOKEN environment variable" appears when a private extension repo needs auth. "X is not a gh extension" means the repo is missing a gh-X executable.

---

Latchkey runs CI/CD that repairs its own failures. Agent entry points: https://latchkey.dev/agent.txt, https://latchkey.dev/openapi.json, https://latchkey.dev/llms.txt
