fix(sbom): parse SPDX JSON format for LTS changelog card version chips#756
Conversation
LTS SBOMs are published as spdx-json (the ISO/IEC 5962:2021 standard),
while regular Bluefin uses syft-json (Syft-native/proprietary format).
extractPackageVersions() only handled Syft JSON (artifacts[]), causing
packageVersions to silently return null for every LTS release — so the
changelog card at docs.projectbluefin.io showed no version chips
(Kernel, GNOME, Mesa, Podman, bootc) for LTS releases.
Changes:
- fetch-github-sbom.js: detect SPDX JSON via spdxVersion field, normalise
packages[] filtered by pkg:rpm/ PURL into the same {name,version,type}
shape that the existing RPM extraction loop expects
- fetch-github-sbom.js: fix cache-hit logic for key-based (LTS/GDX) streams
— attestation.verified is always false for these because verifyAttestation()
uses OIDC keyless; treat populated packageVersions as a valid cache hit
- fetch-github-sbom.js: update stale 'no SBOMs yet' comment for LTS/GDX
- FirehoseFeed.tsx: update enrichLtsFromHistory comment to reflect that LTS
does have an SBOM pipeline; the function is now a fallback for older releases
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Code Review
This pull request introduces support for SPDX-formatted SBOMs, specifically for LTS and GDX streams, allowing the extraction of RPM package versions from these sources. The update includes logic to detect the SBOM format and normalize data into a consistent structure, while also adjusting the cache hit criteria to accommodate key-based signing methods where OIDC verification is not applicable. A review comment suggests improving the robustness of the SPDX package mapping by using optional chaining to prevent potential runtime errors.
| artifacts = (sbom.packages || []) | ||
| .filter((pkg) => { | ||
| const refs = pkg?.externalRefs || []; | ||
| return refs.some( | ||
| (r) => | ||
| r?.referenceCategory === "PACKAGE-MANAGER" && | ||
| r?.referenceLocator?.startsWith("pkg:rpm/"), | ||
| ); | ||
| }) | ||
| .map((pkg) => ({ | ||
| name: pkg.name, | ||
| version: pkg.versionInfo, | ||
| type: "rpm", | ||
| })); |
There was a problem hiding this comment.
The mapping logic for SPDX packages assumes that pkg is always an object. While the preceding filter uses optional chaining (pkg?.externalRefs), the map function directly accesses pkg.name and pkg.versionInfo. If the packages array contains null or undefined elements, this will throw a TypeError. Although the filter currently excludes such elements (because undefined?.externalRefs is falsy), it is safer and more robust to use optional chaining in the map as well, or ensure the filter explicitly removes non-object entries.
| artifacts = (sbom.packages || []) | |
| .filter((pkg) => { | |
| const refs = pkg?.externalRefs || []; | |
| return refs.some( | |
| (r) => | |
| r?.referenceCategory === "PACKAGE-MANAGER" && | |
| r?.referenceLocator?.startsWith("pkg:rpm/"), | |
| ); | |
| }) | |
| .map((pkg) => ({ | |
| name: pkg.name, | |
| version: pkg.versionInfo, | |
| type: "rpm", | |
| })); | |
| artifacts = (sbom.packages || []) | |
| .filter((pkg) => { | |
| const refs = pkg?.externalRefs || []; | |
| return refs.some( | |
| (r) => | |
| r?.referenceCategory === "PACKAGE-MANAGER" && | |
| r?.referenceLocator?.startsWith("pkg:rpm/"), | |
| ); | |
| }) | |
| .map((pkg) => ({ | |
| name: pkg?.name, | |
| version: pkg?.versionInfo, | |
| type: "rpm", | |
| })); |
LTS SBOMs are published as spdx-json (the ISO/IEC 5962:2021 standard), while regular Bluefin uses syft-json (Syft-native/proprietary format). extractPackageVersions() only handled Syft JSON (artifacts[]), causing packageVersions to silently return null for every LTS release — so the changelog card at docs.projectbluefin.io showed no version chips (Kernel, GNOME, Mesa, Podman, bootc) for LTS releases.
Changes: