Skip to content

Commit b15769c

Browse files
authored
[codex] Add release artifact checksum manifest
Add deterministic SHA256 checksum manifest generation and release upload for sbom-diff-and-risk release artifacts, with reviewer verification docs and no CLI, TestPyPI, production PyPI, package version, or release tag changes.
1 parent f89cf3f commit b15769c

5 files changed

Lines changed: 457 additions & 346 deletions

File tree

Lines changed: 179 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -1,164 +1,208 @@
1-
name: sbom-diff-and-risk-ci
2-
run-name: sbom-diff-and-risk ci / ${{ github.event_name }} / ${{ github.ref_name }}
3-
4-
on:
5-
workflow_dispatch:
6-
push:
7-
# Version tags provide a minimal release-build scaffold without changing publishing.
8-
tags:
9-
- "v*"
10-
paths:
11-
- ".github/workflows/sbom-diff-and-risk-ci.yml"
12-
- "tools/sbom-diff-and-risk/**"
13-
pull_request:
14-
paths:
15-
- ".github/workflows/sbom-diff-and-risk-ci.yml"
16-
- "tools/sbom-diff-and-risk/**"
17-
18-
permissions: {}
19-
20-
env:
1+
name: sbom-diff-and-risk-ci
2+
run-name: sbom-diff-and-risk ci / ${{ github.event_name }} / ${{ github.ref_name }}
3+
4+
on:
5+
workflow_dispatch:
6+
push:
7+
# Version tags provide a minimal release-build scaffold without changing publishing.
8+
tags:
9+
- "v*"
10+
paths:
11+
- ".github/workflows/sbom-diff-and-risk-ci.yml"
12+
- "tools/sbom-diff-and-risk/**"
13+
pull_request:
14+
paths:
15+
- ".github/workflows/sbom-diff-and-risk-ci.yml"
16+
- "tools/sbom-diff-and-risk/**"
17+
18+
permissions: {}
19+
20+
env:
2121
SBOM_DIFF_RISK_PYTHON_VERSION: "3.11"
2222
SBOM_DIFF_RISK_DIST_ARTIFACT_NAME: sbom-diff-and-risk-dist
23+
SBOM_DIFF_RISK_CHECKSUM_MANIFEST: sbom-diff-and-risk-SHA256SUMS.txt
2324
SBOM_DIFF_RISK_RELEASE_TITLE_PREFIX: sbom-diff-and-risk
25+
26+
jobs:
27+
test:
28+
runs-on: ubuntu-latest
29+
permissions:
30+
contents: read
31+
defaults:
32+
run:
33+
working-directory: tools/sbom-diff-and-risk
34+
steps:
35+
- name: Check out repository
36+
uses: actions/checkout@v6
37+
38+
- name: Set up Python
39+
uses: actions/setup-python@v6
40+
with:
41+
python-version: ${{ env.SBOM_DIFF_RISK_PYTHON_VERSION }}
42+
43+
- name: Upgrade pip
44+
run: python -m pip install --upgrade pip
45+
46+
- name: Install project
47+
run: python -m pip install -e .[dev]
48+
49+
- name: Run test suite
50+
run: python -m pytest
51+
52+
- name: CLI smoke test
53+
shell: bash
54+
run: |
55+
tmpdir="$(mktemp -d)"
56+
python -m sbom_diff_risk.cli compare \
57+
--before examples/cdx_before.json \
58+
--after examples/cdx_after.json \
59+
--format auto \
60+
--out-json "$tmpdir/report.json" \
61+
--out-md "$tmpdir/report.md"
62+
test -f "$tmpdir/report.json"
63+
test -f "$tmpdir/report.md"
64+
diff -u examples/sample-report.json "$tmpdir/report.json"
65+
diff -u examples/sample-report.md "$tmpdir/report.md"
66+
67+
build-and-attest:
68+
# Keep provenance publication on trusted non-PR runs so consumers verify
69+
# workflow-produced wheel/sdist artifacts from this repository workflow.
70+
if: github.event_name != 'pull_request'
71+
needs: test
72+
runs-on: ubuntu-latest
73+
permissions:
74+
contents: read
75+
id-token: write
76+
attestations: write
77+
defaults:
78+
run:
79+
working-directory: tools/sbom-diff-and-risk
80+
steps:
81+
- name: Check out repository
82+
uses: actions/checkout@v6
83+
84+
- name: Set up Python
85+
uses: actions/setup-python@v6
86+
with:
87+
python-version: ${{ env.SBOM_DIFF_RISK_PYTHON_VERSION }}
88+
89+
- name: Upgrade pip
90+
run: python -m pip install --upgrade pip
91+
92+
- name: Install build tooling
93+
run: python -m pip install build
94+
95+
- name: Build distributable artifacts
96+
run: python -m build
2497

25-
jobs:
26-
test:
27-
runs-on: ubuntu-latest
28-
permissions:
29-
contents: read
30-
defaults:
31-
run:
32-
working-directory: tools/sbom-diff-and-risk
33-
steps:
34-
- name: Check out repository
35-
uses: actions/checkout@v6
36-
37-
- name: Set up Python
38-
uses: actions/setup-python@v6
39-
with:
40-
python-version: ${{ env.SBOM_DIFF_RISK_PYTHON_VERSION }}
41-
42-
- name: Upgrade pip
43-
run: python -m pip install --upgrade pip
44-
45-
- name: Install project
46-
run: python -m pip install -e .[dev]
47-
48-
- name: Run test suite
49-
run: python -m pytest
50-
51-
- name: CLI smoke test
98+
- name: Generate SHA256 checksum manifest
5299
shell: bash
53100
run: |
54-
tmpdir="$(mktemp -d)"
55-
python -m sbom_diff_risk.cli compare \
56-
--before examples/cdx_before.json \
57-
--after examples/cdx_after.json \
58-
--format auto \
59-
--out-json "$tmpdir/report.json" \
60-
--out-md "$tmpdir/report.md"
61-
test -f "$tmpdir/report.json"
62-
test -f "$tmpdir/report.md"
63-
diff -u examples/sample-report.json "$tmpdir/report.json"
64-
diff -u examples/sample-report.md "$tmpdir/report.md"
65-
66-
build-and-attest:
67-
# Keep provenance publication on trusted non-PR runs so consumers verify
68-
# workflow-produced wheel/sdist artifacts from this repository workflow.
69-
if: github.event_name != 'pull_request'
70-
needs: test
71-
runs-on: ubuntu-latest
72-
permissions:
73-
contents: read
74-
id-token: write
75-
attestations: write
76-
defaults:
77-
run:
78-
working-directory: tools/sbom-diff-and-risk
79-
steps:
80-
- name: Check out repository
81-
uses: actions/checkout@v6
82-
83-
- name: Set up Python
84-
uses: actions/setup-python@v6
85-
with:
86-
python-version: ${{ env.SBOM_DIFF_RISK_PYTHON_VERSION }}
101+
set -euo pipefail
102+
shopt -s nullglob
87103
88-
- name: Upgrade pip
89-
run: python -m pip install --upgrade pip
104+
cd dist
105+
artifacts=( *.tar.gz *.whl )
106+
IFS=$'\n'
107+
artifacts=( $(printf '%s\n' "${artifacts[@]}" | LC_ALL=C sort) )
108+
unset IFS
90109
91-
- name: Install build tooling
92-
run: python -m pip install build
110+
if [ "${#artifacts[@]}" -ne 2 ]; then
111+
echo "Expected exactly one source distribution and one wheel in dist/." >&2
112+
printf 'Found %s artifact(s):\n' "${#artifacts[@]}" >&2
113+
printf ' %s\n' "${artifacts[@]}" >&2
114+
exit 1
115+
fi
93116
94-
- name: Build distributable artifacts
95-
run: python -m build
117+
sha256sum "${artifacts[@]}" > "${SBOM_DIFF_RISK_CHECKSUM_MANIFEST}"
118+
grep -E ' sbom_diff_and_risk-.+\.tar\.gz$' "${SBOM_DIFF_RISK_CHECKSUM_MANIFEST}"
119+
grep -E ' sbom_diff_and_risk-.+\.whl$' "${SBOM_DIFF_RISK_CHECKSUM_MANIFEST}"
120+
cat "${SBOM_DIFF_RISK_CHECKSUM_MANIFEST}"
96121
97-
- name: Upload wheel and source distribution artifact
122+
- name: Upload distribution artifact and checksum manifest
98123
uses: actions/upload-artifact@v7
99124
with:
100125
name: ${{ env.SBOM_DIFF_RISK_DIST_ARTIFACT_NAME }}
101126
path: |
102127
tools/sbom-diff-and-risk/dist/*.whl
103128
tools/sbom-diff-and-risk/dist/*.tar.gz
129+
tools/sbom-diff-and-risk/dist/${{ env.SBOM_DIFF_RISK_CHECKSUM_MANIFEST }}
104130
if-no-files-found: error
105131

106132
- name: Generate artifact attestation for built distributions
107133
uses: actions/attest@v4
108134
with:
109-
subject-path: ${{ github.workspace }}/tools/sbom-diff-and-risk/dist/*
110-
111-
publish-release-assets:
112-
# Publish the exact built wheel/sdist bytes from this run as release assets.
113-
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
114-
needs: build-and-attest
115-
runs-on: ubuntu-latest
116-
permissions:
117-
contents: write
118-
steps:
119-
- name: Check out repository
120-
uses: actions/checkout@v6
121-
with:
122-
fetch-depth: 0
123-
124-
- name: Download built distribution artifact
125-
uses: actions/download-artifact@v8
126-
with:
127-
name: ${{ env.SBOM_DIFF_RISK_DIST_ARTIFACT_NAME }}
128-
path: release-assets
129-
130-
- name: Publish release assets from CI-built distributions
131-
shell: bash
132-
env:
133-
GH_TOKEN: ${{ github.token }}
134-
GH_REPO: ${{ github.repository }}
135-
RELEASE_TAG: ${{ github.ref_name }}
136-
RELEASE_TITLE_PREFIX: ${{ env.SBOM_DIFF_RISK_RELEASE_TITLE_PREFIX }}
137-
run: |
135+
subject-path: |
136+
${{ github.workspace }}/tools/sbom-diff-and-risk/dist/*.whl
137+
${{ github.workspace }}/tools/sbom-diff-and-risk/dist/*.tar.gz
138+
139+
publish-release-assets:
140+
# Publish the exact built wheel/sdist bytes and checksum manifest from this run.
141+
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
142+
needs: build-and-attest
143+
runs-on: ubuntu-latest
144+
permissions:
145+
contents: write
146+
steps:
147+
- name: Check out repository
148+
uses: actions/checkout@v6
149+
with:
150+
fetch-depth: 0
151+
152+
- name: Download built distribution artifact and checksum manifest
153+
uses: actions/download-artifact@v8
154+
with:
155+
name: ${{ env.SBOM_DIFF_RISK_DIST_ARTIFACT_NAME }}
156+
path: release-assets
157+
158+
- name: Publish release assets from CI-built distributions
159+
shell: bash
160+
env:
161+
GH_TOKEN: ${{ github.token }}
162+
GH_REPO: ${{ github.repository }}
163+
RELEASE_TAG: ${{ github.ref_name }}
164+
RELEASE_TITLE_PREFIX: ${{ env.SBOM_DIFF_RISK_RELEASE_TITLE_PREFIX }}
165+
run: |
138166
set -euo pipefail
139167
shopt -s nullglob
140168
assets=(release-assets/*.whl release-assets/*.tar.gz)
141-
if [ "${#assets[@]}" -eq 0 ]; then
142-
echo "No release assets found in release-assets/" >&2
169+
IFS=$'\n'
170+
assets=( $(printf '%s\n' "${assets[@]}" | LC_ALL=C sort) )
171+
unset IFS
172+
checksum_manifest="release-assets/${SBOM_DIFF_RISK_CHECKSUM_MANIFEST}"
173+
174+
if [ "${#assets[@]}" -ne 2 ]; then
175+
echo "Expected exactly one wheel and one source distribution in release-assets/." >&2
176+
printf 'Found %s artifact(s):\n' "${#assets[@]}" >&2
177+
printf ' %s\n' "${assets[@]}" >&2
143178
exit 1
144179
fi
145180
146-
title="${RELEASE_TITLE_PREFIX} ${RELEASE_TAG}"
147-
148-
if gh release view "${RELEASE_TAG}" --repo "${GH_REPO}" >/dev/null 2>&1; then
149-
is_draft="$(gh release view "${RELEASE_TAG}" --repo "${GH_REPO}" --json isDraft -q .isDraft)"
150-
if [ "${is_draft}" != "true" ]; then
151-
echo "Release ${RELEASE_TAG} already exists and is published; leaving assets unchanged."
152-
exit 0
153-
fi
154-
else
155-
gh release create "${RELEASE_TAG}" \
156-
--repo "${GH_REPO}" \
157-
--draft \
158-
--verify-tag \
159-
--title "${title}" \
160-
--notes "Release assets for ${RELEASE_TAG}. See docs/release-provenance.md for provenance verification guidance."
181+
if [ ! -f "${checksum_manifest}" ]; then
182+
echo "Missing checksum manifest: ${checksum_manifest}" >&2
183+
exit 1
161184
fi
162185
163-
gh release upload "${RELEASE_TAG}" "${assets[@]}" --repo "${GH_REPO}" --clobber
164-
gh release edit "${RELEASE_TAG}" --repo "${GH_REPO}" --draft=false --title "${title}"
186+
grep -E ' sbom_diff_and_risk-.+\.tar\.gz$' "${checksum_manifest}"
187+
grep -E ' sbom_diff_and_risk-.+\.whl$' "${checksum_manifest}"
188+
assets+=( "${checksum_manifest}" )
189+
190+
title="${RELEASE_TITLE_PREFIX} ${RELEASE_TAG}"
191+
192+
if gh release view "${RELEASE_TAG}" --repo "${GH_REPO}" >/dev/null 2>&1; then
193+
is_draft="$(gh release view "${RELEASE_TAG}" --repo "${GH_REPO}" --json isDraft -q .isDraft)"
194+
if [ "${is_draft}" != "true" ]; then
195+
echo "Release ${RELEASE_TAG} already exists and is published; leaving assets unchanged."
196+
exit 0
197+
fi
198+
else
199+
gh release create "${RELEASE_TAG}" \
200+
--repo "${GH_REPO}" \
201+
--draft \
202+
--verify-tag \
203+
--title "${title}" \
204+
--notes "Release assets for ${RELEASE_TAG}. See docs/release-provenance.md for provenance verification guidance."
205+
fi
206+
207+
gh release upload "${RELEASE_TAG}" "${assets[@]}" --repo "${GH_REPO}"
208+
gh release edit "${RELEASE_TAG}" --repo "${GH_REPO}" --draft=false --title "${title}"

tools/sbom-diff-and-risk/README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -239,9 +239,10 @@ This section is about verifying `sbom-diff-and-risk` itself. If you want the sho
239239
This repository also records provenance for `sbom-diff-and-risk` itself by generating GitHub artifact attestations for the wheel and source distribution produced by the `sbom-diff-and-risk-ci` workflow.
240240

241241
- the attested files are the wheel and source distribution built by `python -m build` from `tools/sbom-diff-and-risk`
242-
- the build files are uploaded together as the `sbom-diff-and-risk-dist` workflow artifact
243-
- version-tag runs also publish those same built files as GitHub Release assets for the matching tag
244-
- only trusted non-PR runs publish the attestation
242+
- the build files are uploaded together as the `sbom-diff-and-risk-dist` workflow artifact
243+
- version-tag runs also publish those same built files as GitHub Release assets for the matching tag
244+
- releases produced by the updated workflow include `sbom-diff-and-risk-SHA256SUMS.txt` for local SHA256 verification of downloaded wheel and source distribution files
245+
- only trusted non-PR runs publish the attestation
245246
- consumers can verify workflow-built artifacts with `gh attestation verify`
246247
- consumers can verify immutable releases and downloaded release assets with `gh release verify` and `gh release verify-asset`
247248
- this complements the tool's analysis of third-party supply-chain inputs, but it does not replace that analysis

0 commit comments

Comments
 (0)