Skip to content

Commit beb7362

Browse files
authored
Merge branch 'main' into dependabot/pip/backend/pytest-gte-8.3-and-lt-10.0
2 parents ad3c3cd + 458ee34 commit beb7362

11 files changed

Lines changed: 669 additions & 485 deletions

File tree

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,23 @@
11
# Keep the initial policy focused on risky dependency changes first.
2-
# If you want stricter license enforcement later, add allow-licenses here.
2+
# This allowlist is intentionally based on the licenses already present in the
3+
# current dependency tree so normal updates do not become noisy immediately.
34
fail-on-severity: high
45
fail-on-scopes:
56
- runtime
67
- unknown
78
license-check: true
9+
allow-licenses:
10+
- Apache-2.0
11+
- Apache-2.0 AND LGPL-3.0-or-later
12+
- Apache-2.0 OR BSD-2-Clause
13+
- BSD-2-Clause
14+
- BSD-3-Clause
15+
- BlueOak-1.0.0
16+
- CC-BY-4.0
17+
- CC0-1.0
18+
- ISC
19+
- MIT
20+
- MPL-2.0
21+
- PSF-2.0
22+
- Python-2.0
23+
- 0BSD

.github/workflows/release.yml

Lines changed: 100 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,17 @@ 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 }}
66+
backend-digest: ${{ steps.push-backend.outputs.digest }}
67+
frontend-digest: ${{ steps.push-frontend.outputs.digest }}
5868
steps:
5969
- name: Checkout
6070
uses: actions/checkout@v4
@@ -97,6 +107,7 @@ jobs:
97107
type=semver,pattern={{major}}
98108
99109
- name: Build and push backend image
110+
id: push-backend
100111
uses: docker/build-push-action@v6
101112
with:
102113
context: ./backend
@@ -108,7 +119,16 @@ jobs:
108119
cache-from: type=gha
109120
cache-to: type=gha,mode=max
110121

122+
- name: Generate backend provenance attestation
123+
id: attest-backend
124+
uses: actions/attest@v4
125+
with:
126+
subject-name: ghcr.io/${{ steps.vars.outputs.owner }}/nextjs-python-computer-vision-kit-backend
127+
subject-digest: ${{ steps.push-backend.outputs.digest }}
128+
push-to-registry: true
129+
111130
- name: Build and push frontend image
131+
id: push-frontend
112132
uses: docker/build-push-action@v6
113133
with:
114134
context: ./frontend
@@ -120,23 +140,101 @@ jobs:
120140
cache-from: type=gha
121141
cache-to: type=gha,mode=max
122142

143+
- name: Generate frontend provenance attestation
144+
id: attest-frontend
145+
uses: actions/attest@v4
146+
with:
147+
subject-name: ghcr.io/${{ steps.vars.outputs.owner }}/nextjs-python-computer-vision-kit-frontend
148+
subject-digest: ${{ steps.push-frontend.outputs.digest }}
149+
push-to-registry: true
150+
123151
github-release:
124152
name: Publish GitHub Release
125153
needs: publish-images
126154
runs-on: ubuntu-latest
155+
permissions:
156+
contents: write
157+
packages: read
127158
steps:
159+
- name: Checkout
160+
uses: actions/checkout@v4
161+
128162
- name: Set lowercase owner
129163
id: vars
130164
run: echo "owner=${GITHUB_REPOSITORY_OWNER,,}" >> "$GITHUB_OUTPUT"
131165
shell: bash
132166

167+
- name: Log in to GHCR
168+
uses: docker/login-action@v3
169+
with:
170+
registry: ghcr.io
171+
username: ${{ github.actor }}
172+
password: ${{ secrets.GITHUB_TOKEN }}
173+
174+
- name: Prepare release asset directory
175+
run: mkdir -p dist/release-assets
176+
shell: bash
177+
178+
- name: Generate source SBOM asset
179+
uses: anchore/sbom-action@v0.20.9
180+
with:
181+
path: .
182+
format: spdx-json
183+
syft-version: v1.41.2
184+
output-file: dist/release-assets/repo-source-${{ github.ref_name }}.spdx.json
185+
upload-artifact: false
186+
upload-release-assets: false
187+
188+
- name: Generate backend image SBOM asset
189+
uses: anchore/sbom-action@v0.20.9
190+
with:
191+
image: ghcr.io/${{ steps.vars.outputs.owner }}/nextjs-python-computer-vision-kit-backend@${{ needs.publish-images.outputs.backend-digest }}
192+
format: spdx-json
193+
syft-version: v1.41.2
194+
output-file: dist/release-assets/backend-runner-${{ github.ref_name }}.spdx.json
195+
upload-artifact: false
196+
upload-release-assets: false
197+
198+
- name: Generate frontend image SBOM asset
199+
uses: anchore/sbom-action@v0.20.9
200+
with:
201+
image: ghcr.io/${{ steps.vars.outputs.owner }}/nextjs-python-computer-vision-kit-frontend@${{ needs.publish-images.outputs.frontend-digest }}
202+
format: spdx-json
203+
syft-version: v1.41.2
204+
output-file: dist/release-assets/frontend-runner-${{ github.ref_name }}.spdx.json
205+
upload-artifact: false
206+
upload-release-assets: false
207+
133208
- name: Publish release
134209
uses: softprops/action-gh-release@v2
135210
with:
136211
generate_release_notes: true
137212
append_body: true
213+
files: |
214+
dist/release-assets/repo-source-${{ github.ref_name }}.spdx.json
215+
dist/release-assets/backend-runner-${{ github.ref_name }}.spdx.json
216+
dist/release-assets/frontend-runner-${{ github.ref_name }}.spdx.json
138217
body: |
139218
## Published Images
140219
141220
- `ghcr.io/${{ steps.vars.outputs.owner }}/nextjs-python-computer-vision-kit-backend:${{ github.ref_name }}`
142221
- `ghcr.io/${{ steps.vars.outputs.owner }}/nextjs-python-computer-vision-kit-frontend:${{ github.ref_name }}`
222+
223+
## Provenance Attestations
224+
225+
- Backend image: ${{ needs.publish-images.outputs.backend-attestation-url }}
226+
- Frontend image: ${{ needs.publish-images.outputs.frontend-attestation-url }}
227+
228+
## Attached SBOM Assets
229+
230+
- `repo-source-${{ github.ref_name }}.spdx.json`
231+
- `backend-runner-${{ github.ref_name }}.spdx.json`
232+
- `frontend-runner-${{ github.ref_name }}.spdx.json`
233+
234+
## Verification
235+
236+
```bash
237+
docker login ghcr.io
238+
gh attestation verify oci://ghcr.io/${{ steps.vars.outputs.owner }}/nextjs-python-computer-vision-kit-backend:${{ github.ref_name }} -R ${{ github.repository }}
239+
gh attestation verify oci://ghcr.io/${{ steps.vars.outputs.owner }}/nextjs-python-computer-vision-kit-frontend:${{ github.ref_name }} -R ${{ github.repository }}
240+
```

.github/workflows/sbom.yml

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
name: SBOM
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
schedule:
8+
- cron: "24 3 * * 3"
9+
workflow_dispatch:
10+
11+
permissions:
12+
contents: read
13+
14+
jobs:
15+
source-sbom:
16+
name: Source SBOM
17+
runs-on: ubuntu-latest
18+
steps:
19+
- name: Checkout
20+
uses: actions/checkout@v4
21+
22+
- name: Generate repository source SBOM
23+
uses: anchore/sbom-action@v0.20.9
24+
with:
25+
path: .
26+
format: spdx-json
27+
artifact-name: repo-source.spdx.json
28+
syft-version: v1.41.2
29+
upload-release-assets: false
30+
31+
image-sbom:
32+
name: Image SBOM (${{ matrix.name }})
33+
runs-on: ubuntu-latest
34+
strategy:
35+
fail-fast: false
36+
matrix:
37+
include:
38+
- name: backend
39+
context: ./backend
40+
dockerfile: ./backend/Dockerfile
41+
target: runner
42+
image: cv-kit-backend:sbom
43+
artifact: backend-runner.spdx.json
44+
- name: frontend
45+
context: ./frontend
46+
dockerfile: ./frontend/Dockerfile
47+
target: runner
48+
image: cv-kit-frontend:sbom
49+
artifact: frontend-runner.spdx.json
50+
steps:
51+
- name: Checkout
52+
uses: actions/checkout@v4
53+
54+
- name: Build runner image
55+
run: >
56+
docker build
57+
--file ${{ matrix.dockerfile }}
58+
--target ${{ matrix.target }}
59+
--tag ${{ matrix.image }}
60+
${{ matrix.context }}
61+
62+
- name: Generate image SBOM
63+
uses: anchore/sbom-action@v0.20.9
64+
with:
65+
image: ${{ matrix.image }}
66+
format: spdx-json
67+
artifact-name: ${{ matrix.artifact }}
68+
syft-version: v1.41.2
69+
upload-release-assets: false

CONTRIBUTING.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ That command writes generated reports into `reports/licenses/`.
9797

9898
Dependency review also runs automatically on pull requests to catch newly introduced vulnerable dependency changes.
9999

100+
That dependency review config also includes an allowlist for the licenses already present in the current dependency tree. If you intentionally add a dependency under a new acceptable license, update `.github/dependency-review-config.yml` in the same pull request.
101+
100102
## Changing the API Contract
101103

102104
If you modify request or response shapes:
@@ -131,6 +133,9 @@ If you modify request or response shapes:
131133
5. Wait for the release workflow to verify the repo, publish GHCR images, and create the GitHub Release.
132134
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.
133135

136+
The release notes will also include links to the image provenance attestations generated during the publish workflow.
137+
The release itself will also carry attached SPDX SBOM files for the source tree and the published runner images.
138+
134139
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.
135140

136141
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: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,13 +127,19 @@ Pull requests also run GitHub dependency review so new vulnerable dependency cha
127127

128128
A separate GitHub workflow generates license-report artifacts for the root workspace, frontend workspace, and backend Python environment.
129129

130+
The dependency-review config also keeps a conservative allowlist of licenses already present in the current dependency tree, so tightening policy does not start by breaking routine updates.
131+
132+
An SBOM workflow also publishes SPDX artifacts for the repository source plus the frontend and backend runner images.
133+
130134
## Releases
131135

132136
- Release Drafter keeps a draft release updated from merged pull requests on `main` and can auto-label incoming pull requests by path.
133137
- Path-based labels help sort PRs into frontend, backend, CI/CD, docs, and maintenance categories automatically.
134138
- Release Drafter defaults to a patch bump unless a maintainer applies `minor` or `major` to the pull request.
135139
- Pushing a tag like `v0.1.0` triggers the release workflow.
136140
- 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.
142+
- The GitHub Release also includes attached SPDX SBOM assets for the source tree and both runner images.
137143
- 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.
138144
- Maintainers can re-run the same check manually with `BACKEND_IMAGE=... FRONTEND_IMAGE=... npm run check:release-smoke`.
139145

SECURITY.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ The repository also uses automated scanning to help catch common security issues
3333
- CodeQL code scanning on GitHub for JavaScript/TypeScript, Python, and workflow files
3434
- GitHub dependency review on pull requests for newly introduced vulnerable dependency changes
3535
- GitHub license-report artifacts for npm and Python dependency inventories
36+
- GitHub SBOM artifacts for the repository source and runner images
37+
- GitHub build-provenance attestations for published release images
38+
39+
Tagged releases also include attached SPDX SBOM files and release-note verification snippets for the published container images.
40+
41+
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.
3642

3743
Those checks do not replace private disclosure. If you believe a vulnerability is real or
3844
exploitable, please still report it through a private advisory.

backend/pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ build-backend = "hatchling.build"
66
name = "nextjs-python-computer-vision-kit-backend"
77
version = "0.1.0"
88
description = "FastAPI backend for the computer vision starter kit."
9+
license = "MIT"
910
readme = "README.md"
1011
requires-python = ">=3.12"
1112
dependencies = [

frontend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"name": "frontend",
33
"version": "0.1.0",
44
"private": true,
5+
"license": "MIT",
56
"scripts": {
67
"dev": "next dev",
78
"build": "next build",

0 commit comments

Comments
 (0)