Skip to content

Commit e095ed8

Browse files
committed
Add release provenance attestations
1 parent 3487489 commit e095ed8

6 files changed

Lines changed: 44 additions & 2 deletions

File tree

.github/workflows/release.yml

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ on:
66
- "v*.*.*"
77

88
permissions:
9-
contents: write
10-
packages: write
9+
contents: read
1110

1211
jobs:
1312
verify:
@@ -55,6 +54,15 @@ jobs:
5554
name: Publish GHCR Images
5655
needs: verify
5756
runs-on: ubuntu-latest
57+
permissions:
58+
contents: read
59+
packages: write
60+
id-token: write
61+
attestations: write
62+
artifact-metadata: write
63+
outputs:
64+
backend-attestation-url: ${{ steps.attest-backend.outputs.attestation-url }}
65+
frontend-attestation-url: ${{ steps.attest-frontend.outputs.attestation-url }}
5866
steps:
5967
- name: Checkout
6068
uses: actions/checkout@v4
@@ -97,6 +105,7 @@ jobs:
97105
type=semver,pattern={{major}}
98106
99107
- name: Build and push backend image
108+
id: push-backend
100109
uses: docker/build-push-action@v6
101110
with:
102111
context: ./backend
@@ -108,7 +117,16 @@ jobs:
108117
cache-from: type=gha
109118
cache-to: type=gha,mode=max
110119

120+
- name: Generate backend provenance attestation
121+
id: attest-backend
122+
uses: actions/attest@v4
123+
with:
124+
subject-name: ghcr.io/${{ steps.vars.outputs.owner }}/nextjs-python-computer-vision-kit-backend
125+
subject-digest: ${{ steps.push-backend.outputs.digest }}
126+
push-to-registry: true
127+
111128
- name: Build and push frontend image
129+
id: push-frontend
112130
uses: docker/build-push-action@v6
113131
with:
114132
context: ./frontend
@@ -120,10 +138,20 @@ jobs:
120138
cache-from: type=gha
121139
cache-to: type=gha,mode=max
122140

141+
- name: Generate frontend provenance attestation
142+
id: attest-frontend
143+
uses: actions/attest@v4
144+
with:
145+
subject-name: ghcr.io/${{ steps.vars.outputs.owner }}/nextjs-python-computer-vision-kit-frontend
146+
subject-digest: ${{ steps.push-frontend.outputs.digest }}
147+
push-to-registry: true
148+
123149
github-release:
124150
name: Publish GitHub Release
125151
needs: publish-images
126152
runs-on: ubuntu-latest
153+
permissions:
154+
contents: write
127155
steps:
128156
- name: Set lowercase owner
129157
id: vars
@@ -140,3 +168,8 @@ jobs:
140168
141169
- `ghcr.io/${{ steps.vars.outputs.owner }}/nextjs-python-computer-vision-kit-backend:${{ github.ref_name }}`
142170
- `ghcr.io/${{ steps.vars.outputs.owner }}/nextjs-python-computer-vision-kit-frontend:${{ github.ref_name }}`
171+
172+
## Provenance Attestations
173+
174+
- Backend image: ${{ needs.publish-images.outputs.backend-attestation-url }}
175+
- Frontend image: ${{ needs.publish-images.outputs.frontend-attestation-url }}

CONTRIBUTING.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ If you modify request or response shapes:
133133
5. Wait for the release workflow to verify the repo, publish GHCR images, and create the GitHub Release.
134134
6. Confirm the release smoke workflow passes against the published images, or dispatch it manually for a tag if you need to re-check a release.
135135

136+
The release notes will also include links to the image provenance attestations generated during the publish workflow.
137+
136138
The component labels used by Release Drafter are synced from `.github/labels.json`, and most of the common ones are applied automatically from changed paths.
137139

138140
To run the same image smoke check locally, set `BACKEND_IMAGE` and `FRONTEND_IMAGE`, then run `npm run check:release-smoke`.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ An SBOM workflow also publishes SPDX artifacts for the repository source plus th
138138
- Release Drafter defaults to a patch bump unless a maintainer applies `minor` or `major` to the pull request.
139139
- Pushing a tag like `v0.1.0` triggers the release workflow.
140140
- That workflow verifies the tagged commit, publishes backend/frontend images to GHCR, and creates a GitHub Release with generated notes.
141+
- The release workflow also generates build-provenance attestations for the published GHCR images and links them from the release notes.
141142
- A follow-up smoke workflow pulls those published GHCR images and checks backend health, a real inference request, and the frontend shell before you treat the release as healthy.
142143
- Maintainers can re-run the same check manually with `BACKEND_IMAGE=... FRONTEND_IMAGE=... npm run check:release-smoke`.
143144

SECURITY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ The repository also uses automated scanning to help catch common security issues
3434
- GitHub dependency review on pull requests for newly introduced vulnerable dependency changes
3535
- GitHub license-report artifacts for npm and Python dependency inventories
3636
- GitHub SBOM artifacts for the repository source and runner images
37+
- GitHub build-provenance attestations for published release images
3738

3839
Dependency review is also configured with an allowlist that matches the current dependency tree, so changes that introduce new license types are surfaced deliberately instead of silently drifting in.
3940

future-reference-feature.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ The template-grade layer is the part worth reusing almost anywhere:
2424
- security scanning
2525
- license reporting
2626
- SBOM generation
27+
- provenance attestations
2728
- repo governance
2829
- image/build verification
2930
- smoke testing after release
@@ -175,6 +176,7 @@ What it covers here:
175176
- semver bump guidance through labels
176177
- tag-triggered release workflow
177178
- GHCR publishing
179+
- build-provenance attestations for published container images
178180
- release smoke test against published images
179181
- synced repository labels
180182

@@ -189,6 +191,7 @@ Generic takeaway:
189191

190192
- if the repo is public and meant to last, release automation is worth it
191193
- release smoke tests are especially valuable because they test the thing users actually consume
194+
- provenance attestations strengthen trust in published artifacts without requiring manual signing steps
192195

193196
### 7. Repo Governance and Maintainer UX
194197

template-playbook.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ If a template only has code and no repo workflow, it is usually still a prototyp
5252
- semver labels
5353
- label sync
5454
- publish workflow
55+
- provenance attestations for published artifacts when possible
5556
- release smoke test
5657

5758
### Repo Governance
@@ -159,6 +160,7 @@ If you want the version that scales better for open source or long-term reuse, a
159160
- dependency changes should be reviewed on pull requests
160161
- dependency licenses should be reportable without manual digging
161162
- SBOMs should be generated for source trees or release artifacts when supply-chain visibility matters
163+
- published artifacts should have provenance attestations when the platform supports them
162164
- release steps should be automated
163165
- docs should explain maintainer flow, not just user setup
164166

0 commit comments

Comments
 (0)