Skip to content

Commit fb8256f

Browse files
committed
feat: add github-cli auth-on-setup option
1 parent b5b41d8 commit fb8256f

21 files changed

+1064
-344
lines changed

src/github-cli/NOTES.md

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,38 @@ This Feature should work on recent versions of Debian/Ubuntu-based distributions
44

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

7+
## Authentication
8+
9+
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`.
10+
11+
Example:
12+
13+
```json
14+
{
15+
"features": {
16+
"ghcr.io/devcontainers/features/github-cli:1": {
17+
"authOnSetup": true,
18+
"extensions": "dlvhdr/gh-dash,github/gh-copilot"
19+
}
20+
},
21+
"remoteEnv": {
22+
"GITHUB_TOKEN": "${localEnv:GITHUB_TOKEN}"
23+
}
24+
}
25+
```
26+
27+
If you already authenticate on the host with GitHub CLI, export a token before opening the dev container:
28+
29+
```bash
30+
export GITHUB_TOKEN="$(gh auth token)"
31+
```
32+
33+
Then the `remoteEnv` example above will pass that token into the container's post-start auth flow.
34+
735
## Extensions
836

9-
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`.
37+
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.
38+
39+
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`.
40+
41+
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.

src/github-cli/README.md

Lines changed: 77 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,91 @@ Installs the GitHub CLI. Auto-detects latest version and installs needed depende
44

55
## Example Usage
66

7+
### Basic usage
8+
79
```json
810
"features": {
911
"ghcr.io/devcontainers/features/github-cli:1": {}
1012
}
1113
```
1214

15+
### Authenticate to GitHub
16+
17+
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.
18+
19+
**Option 1: interactive authentication on setup**
20+
21+
```json
22+
{
23+
"features": {
24+
"ghcr.io/devcontainers/features/github-cli:1": {
25+
"authOnSetup": true
26+
}
27+
}
28+
}
29+
```
30+
31+
**Option 2: pass an authentication token from the host**
32+
33+
If you already authenticate on the host with GitHub CLI, export a token before opening the dev container:
34+
35+
```bash
36+
export GITHUB_TOKEN="$(gh auth token)"
37+
```
38+
39+
Then the `remoteEnv` example above will pass that token into the container's post-start auth flow.
40+
41+
```json
42+
{
43+
"features": {
44+
"ghcr.io/devcontainers/features/github-cli:1": {
45+
"authOnSetup": true
46+
}
47+
},
48+
"remoteEnv": {
49+
"GITHUB_TOKEN": "${localEnv:GITHUB_TOKEN}"
50+
}
51+
}
52+
```
53+
54+
### Install GitHub CLI extensions
55+
56+
```json
57+
{
58+
"features": {
59+
"ghcr.io/devcontainers/features/github-cli:1": {
60+
"extensions": "dlvhdr/gh-dash,github/gh-copilot"
61+
}
62+
}
63+
}
64+
```
65+
66+
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.
67+
68+
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.
69+
70+
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.
71+
72+
```json
73+
{
74+
"features": {
75+
"ghcr.io/devcontainers/features/github-cli:1": {
76+
"extensions": "dlvhdr/gh-dash,github/gh-copilot",
77+
"installExtensionsFromGit": true
78+
}
79+
}
80+
}
81+
```
82+
1383
## Options
1484

15-
| Options Id | Description | Type | Default Value |
16-
| -------------------------------- | --------------------------------------------------------------------------------------------------- | ------- | ------------- |
17-
| version | Select version of the GitHub CLI, if not latest. | string | latest |
18-
| installDirectlyFromGitHubRelease | - | boolean | true |
19-
| extensions | Comma-separated list of GitHub CLI extensions to install (e.g. 'dlvhdr/gh-dash,github/gh-copilot'). | string | |
85+
| Options Id | Description | Type | Default Value |
86+
| -------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ------- | ------------- |
87+
| version | Select version of the GitHub CLI, if not latest. | string | latest |
88+
| installDirectlyFromGitHubRelease | - | boolean | true |
89+
| 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 |
90+
| 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 | |
91+
| 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 |
2092

2193
## OS Support
2294

src/github-cli/devcontainer-feature.json

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"id": "github-cli",
3-
"version": "1.1.0",
3+
"version": "1.3.0",
44
"name": "GitHub CLI",
55
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/github-cli",
66
"description": "Installs the GitHub CLI. Auto-detects latest version and installs needed dependencies.",
@@ -21,7 +21,17 @@
2121
"extensions": {
2222
"type": "string",
2323
"default": "",
24-
"description": "Comma-separated list of GitHub CLI extensions to install (e.g. 'dlvhdr/gh-dash,github/gh-copilot')."
24+
"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."
25+
},
26+
"installExtensionsFromGit": {
27+
"type": "boolean",
28+
"default": false,
29+
"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."
30+
},
31+
"authOnSetup": {
32+
"type": "boolean",
33+
"default": false,
34+
"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."
2535
}
2636
},
2737
"customizations": {

0 commit comments

Comments
 (0)