Skip to content

Commit 836cd5b

Browse files
committed
feat: fallback to GITHUB_TOKEN for ghcr.io
1 parent a877155 commit 836cd5b

File tree

3 files changed

+40
-9
lines changed

3 files changed

+40
-9
lines changed

README.md

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
# Docker Credentials from the Environment
22

3-
A docker credential helper to streamline repository interactions in CI/CD pipelines, particularly Jenkins declarative Pipelines, where dynamic credentials are used.
3+
A [Docker credential helper](https://docs.docker.com/engine/reference/commandline/login/#credential-helpers) to streamline repository interactions in scenarios where the cacheing of credentials to `~/.docker/config.json` is undesirable, including CI/CD pipelines, or anywhere ephemeral credentials are used.
44

5-
In addition to handling simple credentials, it also fully support private AWS ECR repositories, including full automatic cross-account sts:AssumeRole support.
5+
All OCI registry clients that support `~/.docker/config.json` are supported, including [`oras`](https://oras.land/), [`crane`](https://github.com/google/go-containerregistry/blob/main/cmd/crane/README.md), [`grype`](https://github.com/anchore/grype), etc.
6+
7+
In addition to handling basic username:password credentials, the credential helper also includes special support for:
8+
9+
* Amazon Elastic Container Registry (ECR) repositories using [standard AWS credentials](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html), including automatic cross-account role assumption.
10+
* [GitHub Packages](https://ghcr.io/) via the common `GITHUB_TOKEN` environment variable.
611

712
## Environment Variables
813

@@ -21,7 +26,7 @@ Hyphens within DNS labels are transformed to underscores (`s/-/_/g`) for the pur
2126

2227
## Configuration
2328

24-
The `docker-credential-env` binary must be installed to `$PATH`, configured via `~/.docker/config.json`:
29+
The `docker-credential-env` binary must be installed to `$PATH`, and is enabled via `~/.docker/config.json`:
2530

2631
* Handle all docker authentication:
2732

@@ -49,25 +54,25 @@ By default, attempts to explicitly `docker {login,logout}` will generate an erro
4954

5055
```groovy
5156
stages {
52-
stage("Push Image to Artifactory") {
57+
stage('Push Image to Artifactory') {
5358
environment {
5459
DOCKER_artifactory_example_com = credentials('jenkins.artifactory') // (Vault) Username-Password credential
5560
}
5661
steps {
57-
sh "docker push artifactory.example.com/example/example-image:1.0"
62+
sh 'docker push artifactory.example.com/example/example-image:1.0'
5863
}
5964
}
6065
61-
stage("Push Image to Docker Hub") {
66+
stage('Push Image to Docker Hub') {
6267
environment {
6368
DOCKER_docker_com = credentials('hub.docker.com') // Username-Password credential, exploiting domain search
6469
}
6570
steps {
66-
sh "docker push hub.docker.com/example/example-image:1.0"
71+
sh 'docker push hub.docker.com/example/example-image:1.0'
6772
}
6873
}
6974
70-
stage("Push Image to AWS-ECR") {
75+
stage('Push Image to AWS-ECR') {
7176
environment {
7277
// any standard AWS authentication mechanisms are supported
7378
AWS_ROLE_ARN = 'arn:aws:iam::123456789:role/jenkins-user' // triggers automatic sts:AssumeRole
@@ -77,8 +82,18 @@ stages {
7782
AWS_SECRET_ACCESS_KEY = credentials('AWS_SECRET_ACCESS_KEY') // String credential
7883
}
7984
steps {
80-
sh "docker push 123456789.dkr.ecr.us-east-1.amazonaws.com/example/example-image:1.0"
85+
sh 'docker push 123456789.dkr.ecr.us-east-1.amazonaws.com/example/example-image:1.0'
8186
}
8287
}
88+
89+
stage('Push Image to GHCR') {
90+
environment {
91+
GITHUB_TOKEN = credentials('github') // String credential
92+
}
93+
steps {
94+
sh 'docker push ghcr.io/example/example-image:1.0'
95+
}
96+
}
97+
8398
}
8499
```

env.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
)
2020

2121
var ecrHostname = regexp.MustCompile(`^[0-9]+\.dkr\.ecr\.[-a-z0-9]+\.amazonaws\.com$`)
22+
var ghcrHostname = regexp.MustCompile(`^ghcr\.io$`)
2223

2324
const (
2425
defaultScheme = "https://"
@@ -85,6 +86,15 @@ func (e *Env) Get(serverURL string) (username string, password string, err error
8586
return
8687
}
8788

89+
if ghcrHostname.MatchString(hostname) {
90+
// This is a GitHub Container Registry: ghcr.io
91+
if token, found := os.LookupEnv("GITHUB_TOKEN"); found {
92+
username = "github"
93+
password = token
94+
}
95+
return
96+
}
97+
8898
return
8999
}
90100

env_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,11 @@ func TestEnvGet(t *testing.T) {
204204
input: "https://other-example.com",
205205
expected: output{username: "", password: "", err: nil},
206206
},
207+
{
208+
name: "GitHub Container Registry",
209+
input: "https://ghcr.io",
210+
expected: output{username: "", password: "t1", err: nil},
211+
},
207212
}
208213

209214
e := Env{}
@@ -212,6 +217,7 @@ func TestEnvGet(t *testing.T) {
212217
t.Setenv("DOCKER_example_com_PSW", "p1")
213218
t.Setenv("DOCKER_repo_example_com_USR", "u2")
214219
t.Setenv("DOCKER_repo_example_com_PSW", "p2")
220+
t.Setenv("GITHUB_TOKEN", "t1")
215221

216222
for _, tt := range tests {
217223
t.Run(tt.name, func(t *testing.T) {

0 commit comments

Comments
 (0)