Expose Git secret token if default context used

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
CrazyMax 2020-09-22 20:49:18 +02:00
parent 3a24abd18b
commit 86856eb412
No known key found for this signature in database
GPG key ID: 3248E46B6BB8C7F7
4 changed files with 158 additions and 147 deletions

258
README.md
View file

@ -45,10 +45,7 @@ build-secrets, remote cache, etc. and different builder deployment/namespacing o
The default behavior of this action is to use the [Git context invoked by your workflow](https://github.com/docker/build-push-action/blob/master/src/context.ts#L35). The default behavior of this action is to use the [Git context invoked by your workflow](https://github.com/docker/build-push-action/blob/master/src/context.ts#L35).
<details> ```yaml
<summary><b>Show workflow</b></summary>
```yaml
name: ci name: ci
on: on:
@ -81,11 +78,10 @@ jobs:
- -
name: Image digest name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }} run: echo ${{ steps.docker_build.outputs.digest }}
``` ```
</details>
If you use this action in a private repository, you have to pass the [GitHub Token](https://help.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token) If you want to authenticate against a private repository, you have to use a secret named `GIT_AUTH_TOKEN` to be able
as a secret named `GIT_AUTH_TOKEN` to be able to authenticate against it with buildx: to authenticate against it with buildx:
```yaml ```yaml
- -
@ -96,7 +92,7 @@ as a secret named `GIT_AUTH_TOKEN` to be able to authenticate against it with bu
push: true push: true
tags: user/app:latest tags: user/app:latest
secrets: | secrets: |
GIT_AUTH_TOKEN=${{ github.token }} GIT_AUTH_TOKEN=${{ secrets.MYTOKEN }}
``` ```
> :warning: Subdir for Git context is [not yet supported](https://github.com/docker/build-push-action/issues/120). > :warning: Subdir for Git context is [not yet supported](https://github.com/docker/build-push-action/issues/120).
@ -106,140 +102,128 @@ as a secret named `GIT_AUTH_TOKEN` to be able to authenticate against it with bu
You can also use the `PATH` context alongside the [`actions/checkout`](https://github.com/actions/checkout/) action. You can also use the `PATH` context alongside the [`actions/checkout`](https://github.com/actions/checkout/) action.
<details> ```yaml
<summary><b>Show workflow</b></summary> name: ci
```yaml on:
name: ci push:
branches: master
on: jobs:
push: path-context:
branches: master runs-on: ubuntu-latest
steps:
jobs: -
path-context: name: Checkout
runs-on: ubuntu-latest uses: actions/checkout@v2
steps: -
- name: Set up QEMU
name: Checkout uses: docker/setup-qemu-action@v1
uses: actions/checkout@v2 -
- name: Set up Docker Buildx
name: Set up QEMU uses: docker/setup-buildx-action@v1
uses: docker/setup-qemu-action@v1 -
- name: Login to DockerHub
name: Set up Docker Buildx uses: docker/login-action@v1
uses: docker/setup-buildx-action@v1 with:
- username: ${{ secrets.DOCKERHUB_USERNAME }}
name: Login to DockerHub password: ${{ secrets.DOCKERHUB_TOKEN }}
uses: docker/login-action@v1 -
with: name: Build and push
username: ${{ secrets.DOCKERHUB_USERNAME }} uses: docker/build-push-action@v2
password: ${{ secrets.DOCKERHUB_TOKEN }} with:
- context: .
name: Build and push file: ./Dockerfile
uses: docker/build-push-action@v2 platforms: linux/amd64,linux/arm64,linux/386
with: push: true
context: . tags: user/app:latest
file: ./Dockerfile ```
platforms: linux/amd64,linux/arm64,linux/386
push: true
tags: user/app:latest
```
</details>
### Isolated builders ### Isolated builders
<details> ```yaml
<summary><b>Show workflow</b></summary> name: ci
```yaml on:
name: ci push:
branches: master
on: jobs:
push: multi-builders:
branches: master runs-on: ubuntu-latest
steps:
jobs: -
multi-builders: uses: docker/setup-buildx-action@v1
runs-on: ubuntu-latest id: builder1
steps: -
- uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v1 id: builder2
id: builder1 -
- name: Builder 1 name
uses: docker/setup-buildx-action@v1 run: echo ${{ steps.builder1.outputs.name }}
id: builder2 -
- name: Builder 2 name
name: Builder 1 name run: echo ${{ steps.builder2.outputs.name }}
run: echo ${{ steps.builder1.outputs.name }} -
- name: Build against builder1
name: Builder 2 name uses: docker/build-push-action@v2
run: echo ${{ steps.builder2.outputs.name }} with:
- builder: ${{ steps.builder1.outputs.name }}
name: Build against builder1 target: mytarget1
uses: docker/build-push-action@v2 -
with: name: Build against builder2
builder: ${{ steps.builder1.outputs.name }} uses: docker/build-push-action@v2
target: mytarget1 with:
- builder: ${{ steps.builder2.outputs.name }}
name: Build against builder2 target: mytarget2
uses: docker/build-push-action@v2 ```
with:
builder: ${{ steps.builder2.outputs.name }}
target: mytarget2
```
</details>
### Multi-platform image ### Multi-platform image
<details> ```yaml
<summary><b>Show workflow</b></summary> name: ci
```yaml on:
name: ci push:
branches: master
on: jobs:
push: multi:
branches: master runs-on: ubuntu-latest
steps:
jobs: -
multi: name: Checkout
runs-on: ubuntu-latest uses: actions/checkout@v2
steps: -
- name: Set up QEMU
name: Checkout uses: docker/setup-qemu-action@v1
uses: actions/checkout@v2 -
- name: Set up Docker Buildx
name: Set up QEMU uses: docker/setup-buildx-action@v1
uses: docker/setup-qemu-action@v1 -
- name: Login to DockerHub
name: Set up Docker Buildx uses: docker/login-action@v1
uses: docker/setup-buildx-action@v1 with:
- username: ${{ secrets.DOCKERHUB_USERNAME }}
name: Login to DockerHub password: ${{ secrets.DOCKERHUB_TOKEN }}
uses: docker/login-action@v1 -
with: name: Build and push
username: ${{ secrets.DOCKERHUB_USERNAME }} uses: docker/build-push-action@v2
password: ${{ secrets.DOCKERHUB_TOKEN }} with:
- context: .
name: Build and push file: ./Dockerfile
uses: docker/build-push-action@v2 platforms: linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x
with: push: true
context: . tags: |
file: ./Dockerfile user/app:latest
platforms: linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x user/app:1.0.0
push: true ```
tags: |
user/app:latest
user/app:1.0.0
```
</details>
## Advanced usage ## Advanced usage
### Local registry ### Local registry
For testing purposes you may need to create a [local registry](https://hub.docker.com/_/registry) to push images into. For testing purposes you may need to create a [local registry](https://hub.docker.com/_/registry) to push images into:
<details> <details>
<summary><b>Show workflow</b></summary> <summary><b>Show workflow</b></summary>
@ -284,7 +268,7 @@ For testing purposes you may need to create a [local registry](https://hub.docke
### Leverage GitHub cache ### Leverage GitHub cache
You can leverage [GitHub cache](https://docs.github.com/en/actions/configuring-and-managing-workflows/caching-dependencies-to-speed-up-workflows) You can leverage [GitHub cache](https://docs.github.com/en/actions/configuring-and-managing-workflows/caching-dependencies-to-speed-up-workflows)
using [actions/cache](https://github.com/actions/cache) with this action. using [actions/cache](https://github.com/actions/cache) with this action:
<details> <details>
<summary><b>Show workflow</b></summary> <summary><b>Show workflow</b></summary>
@ -338,15 +322,6 @@ The following workflow with the `Prepare` step will generate some [outputs](http
to handle tags and labels based on GitHub actions events. This is just an example to show many cases that you to handle tags and labels based on GitHub actions events. This is just an example to show many cases that you
might want to use: might want to use:
| Event | Ref | Commit SHA | Docker Tag | Pushed |
|-----------------|-------------------------------|------------|------------------------------------|--------|
| `schedule` | | | `nightly` | Yes |
| `pull_request` | `refs/pull/2/merge` | `a123b57` | `pr-2` | No |
| `push` | `refs/heads/<default_branch>` | `676cae2` | `sha-676cae2`, `edge` | Yes |
| `push` | `refs/heads/dev` | `cf20257` | `sha-cf20257`, `dev` | Yes |
| `push` | `refs/heads/my/branch` | `a5df687` | `sha-a5df687`, `my-branch` | Yes |
| `push tag` | `refs/tags/v1.2.3` | | `v1.2.3`, `v1.2`, `v1`, `latest` | Yes |
<details> <details>
<summary><b>Show workflow</b></summary> <summary><b>Show workflow</b></summary>
@ -434,11 +409,20 @@ might want to use:
``` ```
</details> </details>
| Event | Ref | Commit SHA | Docker Tag | Pushed |
|-----------------|-------------------------------|------------|------------------------------------|--------|
| `schedule` | | | `nightly` | Yes |
| `pull_request` | `refs/pull/2/merge` | `a123b57` | `pr-2` | No |
| `push` | `refs/heads/<default_branch>` | `676cae2` | `sha-676cae2`, `edge` | Yes |
| `push` | `refs/heads/dev` | `cf20257` | `sha-cf20257`, `dev` | Yes |
| `push` | `refs/heads/my/branch` | `a5df687` | `sha-a5df687`, `my-branch` | Yes |
| `push tag` | `refs/tags/v1.2.3` | | `v1.2.3`, `v1.2`, `v1`, `latest` | Yes |
### Update DockerHub repo description ### Update DockerHub repo description
You can update the [Docker Hub repository description](https://docs.docker.com/docker-hub/repos/) using You can update the [Docker Hub repository description](https://docs.docker.com/docker-hub/repos/) using
a third-party action called [Docker Hub Description](https://github.com/peter-evans/dockerhub-description) a third-party action called [Docker Hub Description](https://github.com/peter-evans/dockerhub-description)
with this action. with this action:
<details> <details>
<summary><b>Show workflow</b></summary> <summary><b>Show workflow</b></summary>

View file

@ -64,6 +64,10 @@ inputs:
secrets: secrets:
description: "List of secrets to expose to the build (eg. key=value, GIT_AUTH_TOKEN=mytoken)" description: "List of secrets to expose to the build (eg. key=value, GIT_AUTH_TOKEN=mytoken)"
required: false required: false
github-token:
description: "GitHub Token used to authenticate against a repository for Git context"
default: ${{ github.token }}
required: false
outputs: outputs:
digest: digest:

25
dist/index.js generated vendored
View file

@ -7955,6 +7955,12 @@ function convertBody(buffer, headers) {
// html4 // html4
if (!res && str) { if (!res && str) {
res = /<meta[\s]+?http-equiv=(['"])content-type\1[\s]+?content=(['"])(.+?)\2/i.exec(str); res = /<meta[\s]+?http-equiv=(['"])content-type\1[\s]+?content=(['"])(.+?)\2/i.exec(str);
if (!res) {
res = /<meta[\s]+?content=(['"])(.+?)\1[\s]+?http-equiv=(['"])content-type\3/i.exec(str);
if (res) {
res.pop(); // drop last quote
}
}
if (res) { if (res) {
res = /charset=(.*)/i.exec(res.pop()); res = /charset=(.*)/i.exec(res.pop());
@ -8962,7 +8968,7 @@ function fetch(url, opts) {
// HTTP fetch step 5.5 // HTTP fetch step 5.5
switch (request.redirect) { switch (request.redirect) {
case 'error': case 'error':
reject(new FetchError(`redirect mode is set to error: ${request.url}`, 'no-redirect')); reject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect'));
finalize(); finalize();
return; return;
case 'manual': case 'manual':
@ -9001,7 +9007,8 @@ function fetch(url, opts) {
method: request.method, method: request.method,
body: request.body, body: request.body,
signal: request.signal, signal: request.signal,
timeout: request.timeout timeout: request.timeout,
size: request.size
}; };
// HTTP-redirect fetch step 9 // HTTP-redirect fetch step 9
@ -13640,11 +13647,11 @@ const buildx = __importStar(__webpack_require__(295));
const core = __importStar(__webpack_require__(186)); const core = __importStar(__webpack_require__(186));
const github = __importStar(__webpack_require__(438)); const github = __importStar(__webpack_require__(438));
exports.tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-build-push-')); exports.tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-build-push-'));
const defaultContext = `https://github.com/${github.context.repo.owner}/${github.context.repo.repo}#${github.context.ref}`;
function getInputs() { function getInputs() {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
return { return {
context: core.getInput('context') || context: core.getInput('context') || defaultContext,
`https://github.com/${github.context.repo.owner}/${github.context.repo.repo}#${github.context.ref}`,
file: core.getInput('file') || 'Dockerfile', file: core.getInput('file') || 'Dockerfile',
buildArgs: yield getInputList('build-args'), buildArgs: yield getInputList('build-args'),
labels: yield getInputList('labels'), labels: yield getInputList('labels'),
@ -13660,7 +13667,8 @@ function getInputs() {
outputs: yield getInputList('outputs', true), outputs: yield getInputList('outputs', true),
cacheFrom: yield getInputList('cache-from', true), cacheFrom: yield getInputList('cache-from', true),
cacheTo: yield getInputList('cache-to', true), cacheTo: yield getInputList('cache-to', true),
secrets: yield getInputList('secrets', true) secrets: yield getInputList('secrets', true),
githubToken: core.getInput('github-token')
}; };
}); });
} }
@ -13708,9 +13716,16 @@ function getBuildArgs(inputs, buildxVersion) {
yield exports.asyncForEach(inputs.cacheTo, (cacheTo) => __awaiter(this, void 0, void 0, function* () { yield exports.asyncForEach(inputs.cacheTo, (cacheTo) => __awaiter(this, void 0, void 0, function* () {
args.push('--cache-to', cacheTo); args.push('--cache-to', cacheTo);
})); }));
let hasGitAuthToken = false;
yield exports.asyncForEach(inputs.secrets, (secret) => __awaiter(this, void 0, void 0, function* () { yield exports.asyncForEach(inputs.secrets, (secret) => __awaiter(this, void 0, void 0, function* () {
if (secret.startsWith('GIT_AUTH_TOKEN=')) {
hasGitAuthToken = true;
}
args.push('--secret', yield buildx.getSecret(secret)); args.push('--secret', yield buildx.getSecret(secret));
})); }));
if (inputs.githubToken && !hasGitAuthToken && inputs.context == defaultContext) {
args.push('--secret', yield buildx.getSecret(`GIT_AUTH_TOKEN=${inputs.githubToken}`));
}
if (inputs.file) { if (inputs.file) {
args.push('--file', inputs.file); args.push('--file', inputs.file);
} }

View file

@ -6,7 +6,8 @@ import * as buildx from './buildx';
import * as core from '@actions/core'; import * as core from '@actions/core';
import * as github from '@actions/github'; import * as github from '@actions/github';
export const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-build-push-')); export const tmpDir: string = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-build-push-'));
const defaultContext: string = `https://github.com/${github.context.repo.owner}/${github.context.repo.repo}#${github.context.ref}`;
export interface Inputs { export interface Inputs {
context: string; context: string;
@ -26,13 +27,12 @@ export interface Inputs {
cacheFrom: string[]; cacheFrom: string[];
cacheTo: string[]; cacheTo: string[];
secrets: string[]; secrets: string[];
githubToken: string;
} }
export async function getInputs(): Promise<Inputs> { export async function getInputs(): Promise<Inputs> {
return { return {
context: context: core.getInput('context') || defaultContext,
core.getInput('context') ||
`https://github.com/${github.context.repo.owner}/${github.context.repo.repo}#${github.context.ref}`,
file: core.getInput('file') || 'Dockerfile', file: core.getInput('file') || 'Dockerfile',
buildArgs: await getInputList('build-args'), buildArgs: await getInputList('build-args'),
labels: await getInputList('labels'), labels: await getInputList('labels'),
@ -48,7 +48,8 @@ export async function getInputs(): Promise<Inputs> {
outputs: await getInputList('outputs', true), outputs: await getInputList('outputs', true),
cacheFrom: await getInputList('cache-from', true), cacheFrom: await getInputList('cache-from', true),
cacheTo: await getInputList('cache-to', true), cacheTo: await getInputList('cache-to', true),
secrets: await getInputList('secrets', true) secrets: await getInputList('secrets', true),
githubToken: core.getInput('github-token')
}; };
} }
@ -92,9 +93,16 @@ async function getBuildArgs(inputs: Inputs, buildxVersion: string): Promise<Arra
await asyncForEach(inputs.cacheTo, async cacheTo => { await asyncForEach(inputs.cacheTo, async cacheTo => {
args.push('--cache-to', cacheTo); args.push('--cache-to', cacheTo);
}); });
let hasGitAuthToken: boolean = false;
await asyncForEach(inputs.secrets, async secret => { await asyncForEach(inputs.secrets, async secret => {
if (secret.startsWith('GIT_AUTH_TOKEN=')) {
hasGitAuthToken = true;
}
args.push('--secret', await buildx.getSecret(secret)); args.push('--secret', await buildx.getSecret(secret));
}); });
if (inputs.githubToken && !hasGitAuthToken && inputs.context == defaultContext) {
args.push('--secret', await buildx.getSecret(`GIT_AUTH_TOKEN=${inputs.githubToken}`));
}
if (inputs.file) { if (inputs.file) {
args.push('--file', inputs.file); args.push('--file', inputs.file);
} }