forked from NVIDIA/aicr
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path.goreleaser.yaml
More file actions
328 lines (307 loc) · 12.8 KB
/
Copy path.goreleaser.yaml
File metadata and controls
328 lines (307 loc) · 12.8 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
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
# Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
version: 2
project_name: aicr
builds:
- id: aicr
binary: aicr
mod_timestamp: &build-timestamp '{{ .CommitTimestamp }}'
dir: cmd/aicr
env:
- CGO_ENABLED=0
- GOFLAGS=-mod=vendor
flags:
- -trimpath
ldflags: &build-ldflags |
-w
-s
-extldflags "-static"
-X github.com/NVIDIA/aicr/pkg/cli.version={{.Version}}
-X github.com/NVIDIA/aicr/pkg/cli.commit={{.FullCommit}}
-X github.com/NVIDIA/aicr/pkg/cli.date={{.Date}}
hooks:
post:
## cosign attestation (Rekor v2) with slsa provenance v1.
## NOTE: below aicrd currently attests via github attestation
##
## Signs to Rekor v2 via the SigningConfig fetched from TUF into
## $AICR_SIGNING_CONFIG by the go-build-release action (see #1650).
## Rekor v2 emits no inline signed timestamp, so the config also
## carries a timestamp authority the bundle uses for trusted time.
##
## Wrap cosign in a 3-attempt bash retry loop with 5s/10s backoffs
## (no sleep after the final failed attempt — that would just
## delay the exit) to absorb transient Sigstore Rekor flakes.
## cosign attest-blob has no native --retry flag (Rekor retry
## behavior is internal to the rekor-go client and not exposed
## via the cosign CLI). The AICR-side `aicr recipe sign-catalog`
## post-hook uses pkg/bundler/attestation/signWithRetry which
## has equivalent retry semantics at the Go level; this loop is
## the equivalent mitigation for the binary-attestation step.
## See issue #1249.
- cmd: >-
bash -c '[ -z "${SLSA_PREDICATE:-}" ] && exit 0;
[ -z "${AICR_SIGNING_CONFIG:-}" ] && { echo "AICR_SIGNING_CONFIG unset while signing; refusing to fall back to Rekor v1" >&2; exit 1; };
for n in 1 2 3; do
cosign attest-blob
--predicate "${SLSA_PREDICATE}"
--type https://slsa.dev/provenance/v1
--signing-config "${AICR_SIGNING_CONFIG}"
--bundle "$(dirname "{{ .Path }}")/aicr-attestation.sigstore.json"
--yes "{{ .Path }}" && exit 0;
echo "cosign attest-blob attempt $n failed; retrying" >&2;
if [ "$n" -lt 3 ]; then sleep $((n * 5)); fi;
done;
echo "cosign attest-blob failed after 3 attempts" >&2;
exit 1'
output: true
## Sign the embedded recipe catalog (registry.yaml + validators/catalog.yaml).
##
## Two-axis filter: SLSA_PREDICATE presence (set only by the release
## workflow — local goreleaser runs skip the OIDC flow), AND linux/amd64
## (the binary-attestation hook above runs once per goos/goarch combination;
## this one pins to a single combination so the catalog is signed exactly
## once per release). The bundle is then published two ways: as a loose
## release asset (release.extra_files) for easy curl-and-verify, and inside
## every archive (archives.files — the signature is arch-independent).
- cmd: >-
bash -c 'if [ "{{ .Os }}/{{ .Arch }}" != "linux/amd64" ]; then exit 0; fi;
if [ -z "${SLSA_PREDICATE:-}" ]; then exit 0; fi;
if [ -z "${AICR_SIGNING_CONFIG:-}" ]; then echo "AICR_SIGNING_CONFIG unset while signing; refusing to fall back to Rekor v1" >&2; exit 1; fi;
"{{ .Path }}" recipe sign-catalog
--signing-config "${AICR_SIGNING_CONFIG}"
--output "$(dirname "{{ .Path }}")/recipe-catalog.sigstore.json"'
output: true
goos:
- darwin
- linux
goarch:
- amd64
- arm64
- id: aicrd
binary: aicrd
mod_timestamp: *build-timestamp
dir: cmd/aicrd
env:
- CGO_ENABLED=0
- GOFLAGS=-mod=vendor
flags:
- -trimpath
ldflags: &build-ldflags |
-w
-s
-extldflags "-static"
-X github.com/NVIDIA/aicr/pkg/server.version={{.Version}}
-X github.com/NVIDIA/aicr/pkg/server.commit={{.FullCommit}}
-X github.com/NVIDIA/aicr/pkg/server.date={{.Date}}
hooks:
post:
## Binary attestation for the aicrd server binary. Same cosign attest-blob
## flow as the aicr CLI build above (Rekor v2 via SLSA_PREDICATE +
## AICR_SIGNING_CONFIG; skipped when SLSA_PREDICATE is unset, e.g. local
## snapshot builds). Writes the bundle next to the binary AND copies it into
## cmd/aicrd/kodata/ with a per-arch name so ko ships it at KO_DATA_PATH for
## the multi-arch image. The server (pkg/server/signing.go
## resolveBinaryAttestationPath) reads KO_DATA_PATH/aicrd-<GOARCH>-attestation.sigstore.json;
## keep the filename in sync with defaults.BinaryAttestationKoDataNameFormat.
- cmd: >-
bash -c '[ -z "${SLSA_PREDICATE:-}" ] && exit 0;
[ -z "${AICR_SIGNING_CONFIG:-}" ] && { echo "AICR_SIGNING_CONFIG unset while signing; refusing to fall back to Rekor v1" >&2; exit 1; };
for n in 1 2 3; do
cosign attest-blob
--predicate "${SLSA_PREDICATE}"
--type https://slsa.dev/provenance/v1
--signing-config "${AICR_SIGNING_CONFIG}"
--bundle "$(dirname "{{ .Path }}")/aicrd-attestation.sigstore.json"
--yes "{{ .Path }}" && break;
echo "cosign attest-blob attempt $n failed; retrying" >&2;
if [ "$n" -lt 3 ]; then sleep $((n * 5)); else echo "cosign attest-blob failed after 3 attempts" >&2; exit 1; fi;
done;
mkdir -p cmd/aicrd/kodata;
cp "$(dirname "{{ .Path }}")/aicrd-attestation.sigstore.json" "cmd/aicrd/kodata/aicrd-{{ .Arch }}-attestation.sigstore.json"'
output: true
goos:
- linux
goarch:
- amd64
- arm64
gomod:
proxy: false
sboms:
- artifacts: binary
# Attest every binary SBOM with the same Rekor v2 cosign flow the binaries
# themselves use, so an SBOM asset is no longer the one unsigned link in the
# release (NVIDIA/aicr#1957). Produces
# dist/aicr_<version>_<os>_<arch>.sbom.json.sigstore.json next to each SPDX
# document; GoReleaser uploads it as a release asset.
#
# The shell lives in .github/scripts/sign-sbom.sh rather than inline `args`
# because GoReleaser os.Expand's every sign argument and would erase `$n`,
# `${VAR:-}` and `$((...))`; see the header comment in that script.
#
# `signs` only runs under `goreleaser release`; `goreleaser build` (make build,
# tools/e2e) skips it, and the snapshot release workflows (build-attested.yaml,
# packaging.yaml) pass --skip=sbom, which leaves this stanza with no matching
# artifacts.
signs:
- id: sbom
artifacts: sbom
cmd: .github/scripts/sign-sbom.sh
args:
- "${artifact}"
- "${signature}"
signature: "${artifact}.sigstore.json"
output: true
checksum:
name_template: "{{ .ProjectName }}_checksums.txt"
algorithm: sha256
snapshot:
version_template: "{{ .Tag }}-next"
report_sizes: true
metadata:
mod_timestamp: "{{ .CommitTimestamp }}"
release:
github:
owner: NVIDIA
name: aicr
prerelease: auto
draft: true
# A reused partial draft must receive release notes generated from the
# current tagged source, never retain stale or manually supplied notes.
mode: replace
# A failed upload can leave a partial exact-tag draft. Reuse that draft and
# replace only same-named artifacts; the workflow rejects a public release
# for this tag immediately before invoking GoReleaser.
use_existing_draft: true
replace_existing_artifacts: true
# Upload supplementary release artifacts that live outside dist/.
# THIRD_PARTY_NOTICES.md is generated by 'make notices' (a prerequisite of
# 'make release') at the repo root, so it survives 'goreleaser --clean'.
extra_files:
- glob: ./THIRD_PARTY_NOTICES.md
# Recipe catalog Sigstore bundle. Published as a loose release asset so
# `aicr recipe verify-catalog` users can curl the signature directly
# without downloading and extracting a tarball. Authority comes from the
# Sigstore signature (Fulcio cert + Rekor inclusion proof), not from the
# checksums manifest, so the loose-asset placement is intentional even
# though `checksums.txt` does not cover it.
- glob: ./dist/aicr_linux_amd64*/recipe-catalog.sigstore.json
kos:
- id: aicr
build: aicr
repositories:
- ghcr.io/nvidia/aicr
# NVIDIA's static distroless base (replaces ko's chainguard default). The
# aicr CLI/agent is pure Go and discovers the GPU SKU driver-free via
# NFD/PCI, so it no longer needs nvidia-smi or the CUDA base image (and its
# CVE surface).
base_image: nvcr.io/nvidia/distroless/static:v4.0.0@sha256:d90158b69e250d2018f32622b5c622925202ee97224a990a54b63811cb1e3d69
platforms:
- linux/amd64
- linux/arm64
tags:
- "{{ .Env.AICR_CANDIDATE_TAG }}"
labels:
org.opencontainers.image.version: "{{ .Tag }}"
org.opencontainers.image.revision: "{{ .FullCommit }}"
preserve_import_paths: false
bare: true
- id: aicrd
build: aicrd
repositories:
- ghcr.io/nvidia/aicrd
# NVIDIA's static distroless base, same as aicr above. ko stamps its default
# nonroot user (UID 65532) numerically, preserving the unprivileged security
# posture of the previous gcr.io/distroless/static:nonroot base (also UID
# 65532); the base image's own nvs (UID 1000) account is unused here.
base_image: nvcr.io/nvidia/distroless/static:v4.0.0@sha256:d90158b69e250d2018f32622b5c622925202ee97224a990a54b63811cb1e3d69
platforms:
- linux/amd64
- linux/arm64
tags:
- "{{ .Env.AICR_CANDIDATE_TAG }}"
labels:
org.opencontainers.image.version: "{{ .Tag }}"
org.opencontainers.image.revision: "{{ .FullCommit }}"
preserve_import_paths: false
bare: true
archives:
- id: aicr
ids:
- aicr
formats:
- tar.gz
name_template: "{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
files:
- src: "dist/aicr_{{ .Os }}_{{ .Arch }}*/aicr-attestation.sigstore.json"
strip_parent: true
# The catalog signature is produced once (linux/amd64 build hook) but the
# signed artifact is arch-independent (it covers the embedded recipe data,
# not the binary). Ship the same bundle in every archive so users on any
# platform can verify the catalog without a second download.
- src: "dist/aicr_linux_amd64*/recipe-catalog.sigstore.json"
strip_parent: true
changelog:
sort: asc
use: github
filters:
exclude:
- "^build:"
- "^docs:"
- "^test:"
- "^lint:"
- "^chore: readme"
- "^chore: bump version"
groups:
- title: "New Features"
regexp: '^.*?feat(\([[:word:]]+\))??!?:.+$'
order: 0
- title: "Bug Fixes"
regexp: '^.*?(fix|bug)(\([[:word:]]+\))??!?:.+$'
order: 1
- title: "Other Tasks"
order: 999
brews:
- ids:
- aicr
repository:
owner: NVIDIA
name: homebrew-aicr
git:
url: "ssh://git@github.com/NVIDIA/homebrew-aicr.git"
skip_upload: true
commit_author:
name: github-actions
email: github-actions@github.com
commit_msg_template: "Brew formula update for {{ .ProjectName }} version {{ .Tag }}"
directory: Formula
homepage: "https://github.com/NVIDIA/aicr"
description: "Tooling for deploying optimized, validated, and reproducible GPU-accelerated AI runtime in Kubernetes."
license: "Apache-2.0"
install: |
bin.install "aicr"
bin.install "aicr-attestation.sigstore.json" if File.exist? "aicr-attestation.sigstore.json"
generate_completions_from_executable(bin/"aicr", "completion")
test: |
assert_match version.to_s, shell_output("#{bin}/aicr version")
caveats: |
To verify supply-chain provenance (requires cosign):
cosign verify-blob-attestation \\
--bundle #{opt_bin}/aicr-attestation.sigstore.json \\
--type https://slsa.dev/provenance/v1 \\
--certificate-oidc-issuer https://token.actions.githubusercontent.com \\
--certificate-identity-regexp "https://github.com/NVIDIA/aicr/.github/workflows/on-tag\\.yaml@refs/tags/.*" \\
#{opt_bin}/aicr
To update the trust root for bundle attestation:
aicr trust update