-
Notifications
You must be signed in to change notification settings - Fork 21
188 lines (180 loc) · 8.49 KB
/
Copy pathverify.yml
File metadata and controls
188 lines (180 loc) · 8.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
name: verify
on:
workflow_call:
inputs:
builder-outputs:
type: string
description: "JSON build outputs from Docker GitHub Builder reusable workflows"
required: true
registry-identities:
type: string
description: "Keyless registry identity configuration as YAML objects"
required: false
secrets:
registry-auths:
description: "Registry authentication details as YAML objects"
required: false
env:
RUNTIME_MODULE: "@docker/github-builder-runtime@0.94.0"
RUNTIME_INSTALL_ARGS: |
--loglevel=error
--no-save
--package-lock=false
--ignore-scripts
--omit=dev
--prefer-offline
--fund=false
--audit=false
NPM_CONFIG_FETCH_RETRIES: "5"
jobs:
registry-identities:
uses: ./.github/workflows/setup-registry-identities.yml
with:
registry-identities: ${{ inputs.registry-identities }}
verify:
runs-on: ubuntu-24.04
needs:
- registry-identities
env:
REGISTRY_AUTHS_PRESENT: ${{ secrets.registry-auths != '' }}
steps:
-
name: Extract builder outputs
id: vars
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
INPUT_BUILDER-OUTPUTS: ${{ inputs.builder-outputs }}
with:
script: |
const builderOutputs = JSON.parse(core.getInput('builder-outputs'));
core.info(JSON.stringify(builderOutputs, null, 2));
const cosignVersion = builderOutputs['cosign-version'];
const cosignVerifyCommands = builderOutputs['cosign-verify-commands'];
const artifactName = builderOutputs['artifact-name'];
const outputType = builderOutputs['output-type'];
const signed = builderOutputs['signed'] === 'true';
if (!signed) {
core.warning('No signatures to verify, skipping verification steps');
} else if (!cosignVersion || !cosignVerifyCommands || !outputType || (outputType === 'local' && !artifactName)) {
core.setFailed('Missing required builder outputs for signature verification');
return;
}
core.setOutput('cosign-version', cosignVersion);
core.setOutput('cosign-verify-commands', cosignVerifyCommands);
core.setOutput('artifact-name', artifactName);
core.setOutput('output-type', outputType);
core.setOutput('signed', signed);
-
name: Install @docker/github-builder-runtime
if: ${{ steps.vars.outputs.signed == 'true' }}
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
INPUT_RUNTIME-MODULE: ${{ env.RUNTIME_MODULE }}
INPUT_RUNTIME-INSTALL-ARGS: ${{ env.RUNTIME_INSTALL_ARGS }}
with:
script: |
const npmArgs = ['install', ...core.getMultilineInput('runtime-install-args'), core.getInput('runtime-module')];
const maxAttempts = 3;
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
const exitCode = await exec.exec('npm', npmArgs, {ignoreReturnCode: true});
if (exitCode === 0) {
return;
}
if (attempt === maxAttempts) {
core.setFailed(`npm install failed after ${maxAttempts} attempts`);
return;
}
const retryDelayMs = attempt * 50;
core.info(`npm install failed with exit code ${exitCode}; retrying in ${retryDelayMs}ms`);
await new Promise(resolve => setTimeout(resolve, retryDelayMs));
}
-
name: Install Cosign
if: ${{ steps.vars.outputs.signed == 'true' }}
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
INPUT_COSIGN-VERSION: ${{ steps.vars.outputs.cosign-version }}
with:
script: |
const { Cosign } = require('@docker/github-builder-runtime/lib/cosign/cosign');
const { Install } = require('@docker/github-builder-runtime/lib/cosign/install');
const cosignInstall = new Install();
const cosignBinPath = await cosignInstall.download({
version: core.getInput('cosign-version'),
ghaNoCache: true,
skipState: true,
verifySignature: true
});
await cosignInstall.install(cosignBinPath);
const cosign = new Cosign();
await cosign.printVersion();
-
name: Configure AWS credentials
if: ${{ steps.vars.outputs.signed == 'true' && steps.vars.outputs.output-type == 'image' && needs.registry-identities.outputs.aws-ecr-enabled == 'true' }}
uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6.2.3
with:
role-to-assume: ${{ needs.registry-identities.outputs.aws-ecr-role-to-assume }}
aws-region: ${{ needs.registry-identities.outputs.aws-ecr-region }}
-
name: Login to Amazon ECR
if: ${{ steps.vars.outputs.signed == 'true' && steps.vars.outputs.output-type == 'image' && needs.registry-identities.outputs.aws-ecr-enabled == 'true' }}
uses: docker/login-action@abd2ef45e78c5afb21d64d4ca52ee8550d9572c7 # v4.5.1
with:
registry-auth: |
- registry: ${{ needs.registry-identities.outputs.aws-ecr-registry }}
-
name: Authenticate to Google Cloud
id: gcp-wif-auth
if: ${{ steps.vars.outputs.signed == 'true' && steps.vars.outputs.output-type == 'image' && needs.registry-identities.outputs.gcp-wif-enabled == 'true' }}
uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0
with:
token_format: access_token
workload_identity_provider: ${{ needs.registry-identities.outputs.gcp-wif-workload-identity-provider }}
service_account: ${{ needs.registry-identities.outputs.gcp-wif-service-account }}
project_id: ${{ needs.registry-identities.outputs.gcp-wif-project-id }}
create_credentials_file: false
export_environment_variables: false
-
name: Login to Google Artifact Registry
if: ${{ steps.vars.outputs.signed == 'true' && steps.vars.outputs.output-type == 'image' && needs.registry-identities.outputs.gcp-wif-enabled == 'true' }}
uses: docker/login-action@abd2ef45e78c5afb21d64d4ca52ee8550d9572c7 # v4.5.1
with:
registry-auth: |
- registry: ${{ needs.registry-identities.outputs.gcp-wif-registry }}
username: oauth2accesstoken
password: ${{ steps.gcp-wif-auth.outputs.access_token }}
-
name: Login to Docker Hub with OIDC
if: ${{ steps.vars.outputs.signed == 'true' && steps.vars.outputs.output-type == 'image' && needs.registry-identities.outputs.dockerhub-oidc-enabled == 'true' }}
uses: docker/login-action@abd2ef45e78c5afb21d64d4ca52ee8550d9572c7 # v4.5.1
env:
DOCKERHUB_OIDC_CONNECTIONID: ${{ needs.registry-identities.outputs.dockerhub-oidc-connection-id }}
with:
registry-auth: |
- registry: ${{ needs.registry-identities.outputs.dockerhub-oidc-registry }}
username: ${{ needs.registry-identities.outputs.dockerhub-oidc-username }}
-
name: Login to registry
if: ${{ steps.vars.outputs.signed == 'true' && steps.vars.outputs.output-type == 'image' && env.REGISTRY_AUTHS_PRESENT == 'true' }}
uses: docker/login-action@abd2ef45e78c5afb21d64d4ca52ee8550d9572c7 # v4.5.1
with:
registry-auth: ${{ secrets.registry-auths }}
env:
DOCKER_LOGIN_SCOPE_DISABLED: true # make sure the scope feature is disabled to avoid interfering with cosign OIDC login
-
name: Download artifacts
if: ${{ steps.vars.outputs.signed == 'true' && steps.vars.outputs.output-type == 'local' }}
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: ${{ steps.vars.outputs.artifact-name }}
-
name: Verify signatures
if: ${{ steps.vars.outputs.signed == 'true' }}
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
INPUT_COSIGN-VERIFY-COMMANDS: ${{ steps.vars.outputs.cosign-verify-commands }}
with:
script: |
for (const cmd of core.getMultilineInput('cosign-verify-commands')) {
await exec.exec(cmd);
}