Attach an SBOM to every release - #86
Open
Maximilian-Nesslauer wants to merge 3 commits into
Open
Conversation
- The publish matrix computed the version in every leg, and the SBOM job needs the same value. - The test job computes it once and exposes it as an output, so every later job reads one value. - A tag that is not a version fails there, before the tests run.
- A new sbom job restores Borea.App in Release and runs the CycloneDX .NET tool on the restored graph, so the list matches the builds and leaves the Debug-only package out. - The tool is pinned in .config/dotnet-tools.json, which Dependabot updates like the other NuGet packages. - The job checks the result: four known packages are in, nothing test-only or Debug-only is, and every package sits in the dependency graph. - The release job adds the file to the checksums and the assets, and actions/attest binds it to each archive; actions/attest-sbom is deprecated and only wraps it. - The release text names the file, says what it lists, and gives the verify command.
- What the file lists, and the verify command with the signer workflow pinned, next to the provenance command.
Collaborator
Coverage Report for CI Build 33956664485Warning No base build found for commit Coverage: 92.638%Details
Uncovered ChangesNo uncovered changes found. Coverage RegressionsRequires a base build to compare against. How to fix this → Coverage Stats💛 - Coveralls |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #81. Stacked on #78, so the base branch is
release-workflow.Every release now ships a software bill of materials next to the builds.
An SBOM is a list of every third-party package inside a program, with the exact version, the license and a hash of each package. With it, anyone can answer "does this Borea build carry the vulnerable version of package X" by reading one file instead of rebuilding Borea.
SHA256SUMS.txtsays the files are unchanged, the provenance attestation says which workflow run built them, and the SBOM says what is inside them.How it works:
sbomjob restoresBorea.Appthe way the builds do and runs the CycloneDX .NET tool on the restored package graph. The tool is pinned in.config/dotnet-tools.json, which Dependabot keeps current with the other NuGet packages.What the user gets: one more release asset,
Borea-<version>.cdx.json, one more row in the checksum table, and a verify command in the release text and the README.The version is now named once in the
testjob and read by every later job, so a bad tag fails before the tests run.Two things differ from the issue text.
actions/attest-sbomis deprecated and only wrapsactions/attest, so the workflow usesactions/attestdirectly. The optional dependency submission is left out: it needscontents: writein a job that restores packages, and once #82 lands a lock file, GitHub's dependency graph reads the transitive closure from it anyway. #82 itself is not needed first, because the SBOM command does not change when the lock file arrives.Tested locally: the tool run on
Borea.App(31 packages, each with license and hash, the Debug-only DiagnosticsSupport excluded), the check script with a failing case, the release body step, andactionlint. GitHub's own dependency graph of the repository lists the same packages plus exactly the 13 test packages and the Debug-only one. Not tested yet: the attestation and the upload, which only run on a real tag, same as #78.One limit: the SBOM lists the NuGet packages, not the .NET runtime that the self-contained builds carry. The runtime version is in
Borea.App.deps.jsoninside each archive.LLM usage disclosure: Claude Fable 5.1 (and Opus 5 for the code review workflow) was used collaboratively with me to create parts of this. I read, reviewed and tested all of it myself and like it.