Skip to content

Ship CycloneDX SBOM with every GitHub release - #2195

Merged
Widthdom merged 2 commits into
mainfrom
fix-issue1553
May 16, 2026
Merged

Ship CycloneDX SBOM with every GitHub release#2195
Widthdom merged 2 commits into
mainfrom
fix-issue1553

Conversation

@Widthdom

Copy link
Copy Markdown
Owner

Summary

  • Generate a CycloneDX 1.x JSON SBOM (cdidx.sbom.cdx.json) once per release on the linux-x64 matrix lane via the pinned dotnet-CycloneDX global tool (--version 6.2.0, --output-format Json, --exclude-test-projects), upload it as the CodeIndex-sbom artifact, copy it into release-files/ so sha256sums.txt covers its hash, and ship it as a release asset alongside the per-RID tarballs/zips. Extend the asset-collection glob in create-release to also match *.cdx.json.
  • The SBOM enumerates every NuGet dependency (including the bundled Microsoft.Data.Sqlite / SQLitePCLRaw graph and the native e_sqlite3 asset), so SOC2 / FedRAMP-style compliance reviews and supply-chain scanners (Snyk, Trivy, Grype) can audit transitive dependencies without re-deriving them from the .NET-specific .deps.json. The CycloneDX tool only runs on the CI release runner and never lands in the shipped binary, so the production runtime-dependency policy is unchanged.
  • Append $HOME/.dotnet/tools to $GITHUB_PATH in the install step because actions/setup-dotnet@v4 does not put the global-tools directory on PATH for subsequent steps on GitHub-hosted runners.

Validation

  • dotnet test tests/CodeIndex.Tests/CodeIndex.Tests.csproj --filter "FullyQualifiedName~ReleaseWorkflowTests" — passes (2/2).
  • New test ReleaseWorkflow_GeneratesCycloneDxSbomAndShipsItAsReleaseAsset asserts the pinned --version 6.2.0, the dotnet-CycloneDX src/CodeIndex/CodeIndex.csproj invocation, the modern --output-format Json and --exclude-test-projects flag surface, the stable filename cdidx.sbom.cdx.json, the CodeIndex-sbom artifact name, the matrix.rid == 'linux-x64' gate, and the *.cdx.json glob clause in create-release, so accidental flag drift (e.g. --json--output-format Json between CycloneDX majors) or removal of the SBOM step fails CI loudly.
  • End-to-end SBOM generation is exercised only by the release workflow itself (it requires the GitHub Actions runner environment); the actual artifact will appear on the next v* tag.

Documentation / Changelog

  • Changelog fragment: changelog.d/unreleased/1553.added.md (bilingual added category).
  • README.md (English + Japanese): new "Verifying releases / リリース成果物の検証" section documenting the SBOM location, intended consumers, and a sha256sum --check quick-verify command.
  • DEVELOPER_GUIDE.md (English + Japanese): release "moving parts" table extended with the SBOM row alongside the existing per-RID binaries and sha256sums.txt.

Follow-up candidates

  • None identified for this PR. (Future work could add an SPDX SBOM in addition to CycloneDX, or sign release assets via Sigstore / cosign, but those are out of scope for No SBOM shipped with releases (CycloneDX/SPDX) #1553 which asks specifically for a CycloneDX or SPDX SBOM.)

Fixes #1553

Widthdom added 2 commits May 16, 2026 03:49
Generate a CycloneDX 1.x JSON Software Bill of Materials once per
release on the linux-x64 lane via the pinned `dotnet-CycloneDX`
global tool (`--version 6.2.0`, run with `--output-format Json`,
`--exclude-test-projects`, and a stable filename of
`cdidx.sbom.cdx.json`), upload it as a `CodeIndex-sbom` build
artifact, copy it into `release-files/` alongside the tarballs/zips
so the existing `sha256sums.txt` covers it, and ship it as a release
asset. Extend the asset-collection glob in `create-release` to also
match `*.cdx.json` so the SBOM gets included.

The SBOM lists every NuGet dependency including the bundled
`Microsoft.Data.Sqlite` / `SQLitePCLRaw` graph and the native
`e_sqlite3` asset, so SOC2 / FedRAMP-style compliance reviews and
supply-chain scanners (Snyk, Trivy, Grype) can audit transitive
dependencies without re-deriving them from the .NET-specific
`.deps.json`. The CycloneDX tool runs only on the CI release runner
and never lands in the shipped binary, so the production
runtime-dependency policy is unchanged.

Add a "Verifying releases" section to `README.md` (English and
Japanese) covering the SBOM location, intended consumers, and a
`sha256sum --check` quick-verify command, and extend the
`DEVELOPER_GUIDE.md` release "moving parts" table to document the
SBOM alongside the existing per-RID binaries and `sha256sums.txt`.

Cover the workflow contract with two release-workflow assertions
(`Install CycloneDX SBOM tool`, `dotnet-CycloneDX` invocation with
the modern flag surface, `--exclude-test-projects`,
`cdidx.sbom.cdx.json`, `CodeIndex-sbom`, the `linux-x64`-only
gate, and the `*.cdx.json` glob clause) so accidental flag drift
(e.g. `--json` to `--output-format Json` between CycloneDX majors)
or removal of the SBOM step fails CI loudly.
actions/setup-dotnet@v4 does not put $HOME/.dotnet/tools on PATH for
subsequent steps, so `dotnet tool install --global CycloneDX` succeeds
but the next step invoking `dotnet-CycloneDX` would fail with
"command not found" on GitHub-hosted runners. Append the directory to
$GITHUB_PATH in the same step so the SBOM-generation step can resolve
the binary.

actions/setup-dotnet@v4 は $HOME/.dotnet/tools を後続 step の PATH に
自動では含めないため、`dotnet tool install --global CycloneDX` は
成功するが、次の step での `dotnet-CycloneDX` 呼び出しが
`command not found` で失敗してしまう。インストールと同じ step 内で
$GITHUB_PATH に当該ディレクトリを追記し、SBOM 生成 step から
コマンドを解決できるようにする。
@Widthdom
Widthdom merged commit 7cabd15 into main May 16, 2026
8 checks passed
@Widthdom
Widthdom deleted the fix-issue1553 branch May 16, 2026 04:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

No SBOM shipped with releases (CycloneDX/SPDX)

1 participant