Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 33 additions & 1 deletion src/github-cli/NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,38 @@ This Feature should work on recent versions of Debian/Ubuntu-based distributions

`bash` is required to execute the `install.sh` script.

## Authentication

If you set the `authOnSetup` option, the feature installs a one-time shell startup hook script. When `gh auth status` shows you are not already authenticated, the hook first tries `gh auth login --with-token` if `GH_TOKEN` or `GITHUB_TOKEN` is available in the environment, otherwise it falls back to `gh auth login` in an interactive shell. This happens after the dev container starts, so it can use values injected through runtime environment settings like `remoteEnv`.

Example:

```json
{
"features": {
"ghcr.io/devcontainers/features/github-cli:1": {
"authOnSetup": true,
"extensions": "dlvhdr/gh-dash,github/gh-copilot"
}
},
"remoteEnv": {
"GITHUB_TOKEN": "${localEnv:GITHUB_TOKEN}"
}
}
```

If you already authenticate on the host with GitHub CLI, export a token before opening the dev container:

```bash
export GITHUB_TOKEN="$(gh auth token)"
```

Then the `remoteEnv` example above will pass that token into the container's post-start auth flow.

## Extensions

If you set the `extensions` option, the feature will run `gh extension install` for each entry (comma-separated). Extensions are installed for the most appropriate non-root user (based on `USERNAME` / `_REMOTE_USER`), with a fallback to `root`.
If you set the `extensions` option, the feature requires either `authOnSetup=true` or `installExtensionsFromGit=true`. The unsupported combination `authOnSetup=false` and `installExtensionsFromGit=false` fails during feature setup with a clear error.

When `authOnSetup=true`, extension installation is deferred until that post-start auth flow runs so runtime tokens can be used for authenticated installs, unless `installExtensionsFromGit=true`. Extensions are installed for the most appropriate non-root user (based on `USERNAME` / `_REMOTE_USER`), with a fallback to `root`.

Set `installExtensionsFromGit` to `true` if you want to skip `gh extension install` and always clone extension repositories directly. In that mode, extensions install during feature setup even when `authOnSetup` is enabled.
82 changes: 77 additions & 5 deletions src/github-cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,91 @@ Installs the GitHub CLI. Auto-detects latest version and installs needed depende

## Example Usage

### Basic usage

```json
"features": {
"ghcr.io/devcontainers/features/github-cli:1": {}
}
```

### Authenticate to GitHub

On the first interactive shell after the dev container starts, if you are not already authenticated, the feature tries `gh auth login --with-token` if `GH_TOKEN` or `GITHUB_TOKEN` is available. If those environment variables are not set, it falls back to starting `gh auth login` in an interactive shell.

**Option 1: interactive authentication on setup**

```json
{
"features": {
"ghcr.io/devcontainers/features/github-cli:1": {
"authOnSetup": true
}
}
}
```

**Option 2: pass an authentication token from the host**

If you already authenticate on the host with GitHub CLI, export a token before opening the dev container:

```bash
export GITHUB_TOKEN="$(gh auth token)"
```

Then the `remoteEnv` example above will pass that token into the container's post-start auth flow.

```json
{
"features": {
"ghcr.io/devcontainers/features/github-cli:1": {
"authOnSetup": true
}
},
"remoteEnv": {
"GITHUB_TOKEN": "${localEnv:GITHUB_TOKEN}"
}
}
```

### Install GitHub CLI extensions

```json
{
"features": {
"ghcr.io/devcontainers/features/github-cli:1": {
"extensions": "dlvhdr/gh-dash,github/gh-copilot"
}
}
}
```

When `extensions` are configured together with `authOnSetup`, extension installation is deferred to the same post-start auth flow so that runtime tokens can be used for authenticated installs. The feature prefers `gh extension install` for each entry when `gh auth status` indicates an authenticated session. If GitHub CLI is not authenticated, or if the native install path fails, the feature falls back to cloning the extension repository into the GitHub CLI extensions directory.

If `extensions` are configured, at least one of `authOnSetup` or `installExtensionsFromGit` must be `true`. The unsupported combination `authOnSetup=false` and `installExtensionsFromGit=false` fails fast during feature setup.

If you want to skip `gh extension install` entirely, set `installExtensionsFromGit` to `true`. In that mode, extensions are installed during feature setup even if `authOnSetup` is also enabled.

```json
{
"features": {
"ghcr.io/devcontainers/features/github-cli:1": {
"extensions": "dlvhdr/gh-dash,github/gh-copilot",
"installExtensionsFromGit": true
}
}
}
```

## Options

| Options Id | Description | Type | Default Value |
| -------------------------------- | --------------------------------------------------------------------------------------------------- | ------- | ------------- |
| version | Select version of the GitHub CLI, if not latest. | string | latest |
| installDirectlyFromGitHubRelease | - | boolean | true |
| extensions | Comma-separated list of GitHub CLI extensions to install (e.g. 'dlvhdr/gh-dash,github/gh-copilot'). | string | |
| Options Id | Description | Type | Default Value |
| -------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ------- | ------------- |
| version | Select version of the GitHub CLI, if not latest. | string | latest |
| installDirectlyFromGitHubRelease | - | boolean | true |
| authOnSetup | Automatically authenticate with `gh auth login --with-token` when `GH_TOKEN` or `GITHUB_TOKEN` is available, otherwise start `gh auth login` on the first interactive shell if you are not already authenticated. If `extensions` are configured, this must be true unless `installExtensionsFromGit` is true. | boolean | false |
| extensions | Comma-separated list of GitHub CLI extensions to install (e.g. 'dlvhdr/gh-dash,github/gh-copilot'). Requires either `authOnSetup` or `installExtensionsFromGit` to be true. | string | |
| installExtensionsFromGit | Install `extensions` by cloning their repositories directly instead of using `gh extension install`. Set this to true when `authOnSetup` is false and `extensions` are configured. When `authOnSetup` is enabled, git-based installs happen during feature setup instead of waiting for login. | boolean | false |

## OS Support

Expand Down
14 changes: 12 additions & 2 deletions src/github-cli/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"id": "github-cli",
"version": "1.1.0",
"version": "1.3.0",
"name": "GitHub CLI",
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/github-cli",
"description": "Installs the GitHub CLI. Auto-detects latest version and installs needed dependencies.",
Expand All @@ -21,7 +21,17 @@
"extensions": {
"type": "string",
"default": "",
"description": "Comma-separated list of GitHub CLI extensions to install (e.g. 'dlvhdr/gh-dash,github/gh-copilot')."
"description": "Comma-separated list of GitHub CLI extensions to install (e.g. 'dlvhdr/gh-dash,github/gh-copilot'). Requires either `authOnSetup` or `installExtensionsFromGit` to be true."
},
"installExtensionsFromGit": {
"type": "boolean",
"default": false,
"description": "Install `extensions` by cloning their repositories directly instead of using `gh extension install`. Set this to true when `authOnSetup` is false and `extensions` are configured. When used together with `authOnSetup`, git-based installs happen during feature setup instead of waiting for login."
},
"authOnSetup": {
"type": "boolean",
"default": false,
"description": "Automatically authenticate with `gh auth login --with-token` when `GH_TOKEN` or `GITHUB_TOKEN` is available, otherwise start `gh auth login` on the first interactive shell if you are not already authenticated. If `extensions` are configured, this must be true unless `installExtensionsFromGit` is true."
}
},
"customizations": {
Expand Down
Loading
Loading