mirror of
https://github.com/docker/build-push-action
synced 2024-11-10 05:21:40 +00: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
|
||||
|
||||
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:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
@ -36,6 +81,7 @@ jobs:
|
|||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: action
|
||||
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
|
|
@ -105,6 +105,10 @@ inputs:
|
|||
description: "GitHub Token used to authenticate against a repository for Git context"
|
||||
default: ${{ github.token }}
|
||||
required: false
|
||||
sign:
|
||||
description: "If true, sign the image with the GitHub Actions identity using Cosign."
|
||||
default: 'false'
|
||||
required: false
|
||||
|
||||
outputs:
|
||||
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;
|
||||
ulimit: string[];
|
||||
githubToken: string;
|
||||
sign: boolean;
|
||||
}
|
||||
|
||||
export async function getInputs(): Promise<Inputs> {
|
||||
|
@ -72,7 +73,8 @@ export async function getInputs(): Promise<Inputs> {
|
|||
tags: Util.getInputList('tags'),
|
||||
target: core.getInput('target'),
|
||||
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 stateHelper from './state-helper';
|
||||
import * as core from '@actions/core';
|
||||
import * as io from '@actions/io';
|
||||
import * as actionsToolkit from '@docker/actions-toolkit';
|
||||
import {Context} from '@docker/actions-toolkit/lib/context';
|
||||
import {Docker} from '@docker/actions-toolkit/lib/docker/docker';
|
||||
|
@ -104,6 +105,48 @@ actionsToolkit.run(
|
|||
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
|
||||
async () => {
|
||||
|
|
Loading…
Reference in a new issue