mirror of
https://github.com/docker/build-push-action.git
synced 2024-11-06 00:35:53 -05:00
WIP: enable signing with cosign
Signed-off-by: Jason Hall <jason@chainguard.dev>
This commit is contained in:
parent
fdf7f43ecf
commit
898ec8408f
6 changed files with 98 additions and 3 deletions
46
.github/workflows/ci.yml
vendored
46
.github/workflows/ci.yml
vendored
|
@ -28,6 +28,51 @@ env:
|
||||||
BUILDKIT_IMAGE: moby/buildkit:buildx-stable-1
|
BUILDKIT_IMAGE: moby/buildkit:buildx-stable-1
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
minimal-sign:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
id-token: write
|
||||||
|
contents: read
|
||||||
|
services:
|
||||||
|
registry:
|
||||||
|
image: registry:2
|
||||||
|
ports:
|
||||||
|
- 5000:5000
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
path: action
|
||||||
|
|
||||||
|
-
|
||||||
|
name: Set up Cosign
|
||||||
|
uses: sigstore/cosign-installer@v3.2.0
|
||||||
|
|
||||||
|
-
|
||||||
|
name: Set up Docker Buildx
|
||||||
|
id: buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
with:
|
||||||
|
version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
|
||||||
|
driver-opts: |
|
||||||
|
network=host
|
||||||
|
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
|
||||||
|
|
||||||
|
-
|
||||||
|
name: Build and push
|
||||||
|
id: docker_build
|
||||||
|
uses: ./action
|
||||||
|
with:
|
||||||
|
file: ./test/Dockerfile
|
||||||
|
builder: ${{ steps.buildx.outputs.name }}
|
||||||
|
platforms: linux/amd64
|
||||||
|
push: true
|
||||||
|
sign: true
|
||||||
|
tags: |
|
||||||
|
localhost:5000/name/app:latest
|
||||||
|
localhost:5000/name/app:1.0.0
|
||||||
|
|
||||||
minimal:
|
minimal:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
@ -36,6 +81,7 @@ jobs:
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
path: action
|
path: action
|
||||||
|
|
||||||
-
|
-
|
||||||
name: Set up Docker Buildx
|
name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
|
@ -105,6 +105,10 @@ inputs:
|
||||||
description: "GitHub Token used to authenticate against a repository for Git context"
|
description: "GitHub Token used to authenticate against a repository for Git context"
|
||||||
default: ${{ github.token }}
|
default: ${{ github.token }}
|
||||||
required: false
|
required: false
|
||||||
|
sign:
|
||||||
|
description: "If true, sign the image with the GitHub Actions identity using Cosign."
|
||||||
|
default: 'false'
|
||||||
|
required: false
|
||||||
|
|
||||||
outputs:
|
outputs:
|
||||||
imageid:
|
imageid:
|
||||||
|
|
2
dist/index.js
generated
vendored
2
dist/index.js
generated
vendored
File diff suppressed because one or more lines are too long
2
dist/index.js.map
generated
vendored
2
dist/index.js.map
generated
vendored
File diff suppressed because one or more lines are too long
|
@ -38,6 +38,7 @@ export interface Inputs {
|
||||||
target: string;
|
target: string;
|
||||||
ulimit: string[];
|
ulimit: string[];
|
||||||
githubToken: string;
|
githubToken: string;
|
||||||
|
sign: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getInputs(): Promise<Inputs> {
|
export async function getInputs(): Promise<Inputs> {
|
||||||
|
@ -72,7 +73,8 @@ export async function getInputs(): Promise<Inputs> {
|
||||||
tags: Util.getInputList('tags'),
|
tags: Util.getInputList('tags'),
|
||||||
target: core.getInput('target'),
|
target: core.getInput('target'),
|
||||||
ulimit: Util.getInputList('ulimit', {ignoreComma: true}),
|
ulimit: Util.getInputList('ulimit', {ignoreComma: true}),
|
||||||
githubToken: core.getInput('github-token')
|
githubToken: core.getInput('github-token'),
|
||||||
|
sign: core.getBooleanInput('sign')
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
43
src/main.ts
43
src/main.ts
|
@ -2,6 +2,7 @@ import * as fs from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as stateHelper from './state-helper';
|
import * as stateHelper from './state-helper';
|
||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
|
import * as io from '@actions/io';
|
||||||
import * as actionsToolkit from '@docker/actions-toolkit';
|
import * as actionsToolkit from '@docker/actions-toolkit';
|
||||||
import {Context} from '@docker/actions-toolkit/lib/context';
|
import {Context} from '@docker/actions-toolkit/lib/context';
|
||||||
import {Docker} from '@docker/actions-toolkit/lib/docker/docker';
|
import {Docker} from '@docker/actions-toolkit/lib/docker/docker';
|
||||||
|
@ -104,6 +105,48 @@ actionsToolkit.run(
|
||||||
core.setOutput('metadata', metadata);
|
core.setOutput('metadata', metadata);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (inputs.sign) {
|
||||||
|
// TODO: Check if `id-token: write` is specified and ID token is available.
|
||||||
|
|
||||||
|
// Check if cosign is installed.
|
||||||
|
const cosignAvailable = await io
|
||||||
|
.which('cosign', true)
|
||||||
|
.then(res => {
|
||||||
|
core.debug(`cosignAvailable ok: ${res}`);
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
core.debug(`cosignAvailable error: ${error}`);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
if (!cosignAvailable) {
|
||||||
|
core.setFailed(`Cosign is required to sign. See https://github.com/sigstore/cosign-installer to set up cosign.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await core.group(`Cosign version`, async () => {
|
||||||
|
await Exec.getExecOutput('cosign', ['version'], {
|
||||||
|
ignoreReturnCode: true
|
||||||
|
}).then(res => {
|
||||||
|
if (res.stderr.length > 0 && res.exitCode != 0) {
|
||||||
|
throw new Error(`cosign version failed with: ${res.stderr.match(/(.*)\s*$/)?.[0]?.trim() ?? 'unknown error'}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!digest) {
|
||||||
|
throw new Error('Digest is required to sign.');
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const img of inputs.tags) {
|
||||||
|
const ref = `${img}@${digest}`;
|
||||||
|
await core.group(`Signing image ${ref}`, async () => {
|
||||||
|
// TODO: Annotate with workflow run ID, etc, from env vars.
|
||||||
|
await Exec.exec('cosign', ['sign', ref, '--yes']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
// post
|
// post
|
||||||
async () => {
|
async () => {
|
||||||
|
|
Loading…
Reference in a new issue