Skip to content

Commit ff65435

Browse files
committed
Fix CI: generate proper SPDX SBOM, opt into Node.js 24
Replace Anchore/Syft (which can't detect C++ FetchContent deps) with our own generate-sbom.py that produces a correct SPDX 2.3 JSON with all four dependencies and their relationships. Set FORCE_JAVASCRIPT_ACTIONS_TO_NODE24 to silence the deprecation warning.
1 parent c153c47 commit ff65435

3 files changed

Lines changed: 118 additions & 8 deletions

File tree

.github/workflows/build.yml

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ on:
66
pull_request:
77
branches: [main]
88

9+
env:
10+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
11+
912
jobs:
1013
build:
1114
strategy:
@@ -32,16 +35,11 @@ jobs:
3235
sbom:
3336
runs-on: ubuntu-latest
3437
needs: build
35-
permissions:
36-
contents: read
3738
steps:
3839
- uses: actions/checkout@v4
3940

40-
- name: Generate SBOM
41-
uses: anchore/sbom-action@v0
42-
with:
43-
format: spdx-json
44-
output-file: sbom.spdx.json
41+
- name: Generate SPDX SBOM
42+
run: python3 scripts/generate-sbom.py > sbom.spdx.json
4543

4644
- name: Upload SBOM
4745
uses: actions/upload-artifact@v4

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ how what time is it in Tokyo # same result
117117

118118
## SBOM
119119

120-
Third-party dependencies and their licenses are listed in [SBOM.md](SBOM.md). CI generates a machine-readable SPDX artifact as well.
120+
Third-party dependencies and their licenses are listed in [SBOM.md](SBOM.md). CI generates a machine-readable SPDX JSON artifact from [scripts/generate-sbom.py](scripts/generate-sbom.py).
121121

122122
## License
123123

scripts/generate-sbom.py

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
#!/usr/bin/env python3
2+
"""Generate an SPDX 2.3 SBOM for the how project."""
3+
4+
import json
5+
import uuid
6+
from datetime import datetime, timezone
7+
8+
sbom = {
9+
"spdxVersion": "SPDX-2.3",
10+
"dataLicense": "CC0-1.0",
11+
"SPDXID": "SPDXRef-DOCUMENT",
12+
"name": "how",
13+
"documentNamespace": f"https://github.com/matlimatli/how/spdx/{uuid.uuid4()}",
14+
"creationInfo": {
15+
"created": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
16+
"creators": ["Tool: scripts/generate-sbom.py"],
17+
"licenseListVersion": "3.25",
18+
},
19+
"packages": [
20+
{
21+
"SPDXID": "SPDXRef-Package-how",
22+
"name": "how",
23+
"versionInfo": "1.0.0",
24+
"supplier": "Person: Mattias Lindblad",
25+
"downloadLocation": "https://github.com/matlimatli/how",
26+
"filesAnalyzed": False,
27+
"licenseConcluded": "MIT",
28+
"licenseDeclared": "MIT",
29+
"copyrightText": "Copyright (c) 2026 Mattias Lindblad",
30+
"primaryPackagePurpose": "APPLICATION",
31+
},
32+
{
33+
"SPDXID": "SPDXRef-Package-libcurl",
34+
"name": "libcurl",
35+
"versionInfo": "system",
36+
"supplier": "Organization: curl project",
37+
"downloadLocation": "https://curl.se/",
38+
"filesAnalyzed": False,
39+
"licenseConcluded": "curl",
40+
"licenseDeclared": "curl",
41+
"copyrightText": "Copyright (c) Daniel Stenberg",
42+
"externalRefs": [
43+
{
44+
"referenceCategory": "PACKAGE-MANAGER",
45+
"referenceType": "purl",
46+
"referenceLocator": "pkg:generic/libcurl",
47+
}
48+
],
49+
},
50+
{
51+
"SPDXID": "SPDXRef-Package-nlohmann-json",
52+
"name": "nlohmann-json",
53+
"versionInfo": "3.12.0",
54+
"supplier": "Person: Niels Lohmann",
55+
"downloadLocation": "https://github.com/nlohmann/json/archive/refs/tags/v3.12.0.tar.gz",
56+
"filesAnalyzed": False,
57+
"licenseConcluded": "MIT",
58+
"licenseDeclared": "MIT",
59+
"copyrightText": "Copyright (c) 2013-2025 Niels Lohmann",
60+
"externalRefs": [
61+
{
62+
"referenceCategory": "PACKAGE-MANAGER",
63+
"referenceType": "purl",
64+
"referenceLocator": "pkg:github/nlohmann/json@v3.12.0",
65+
}
66+
],
67+
},
68+
{
69+
"SPDXID": "SPDXRef-Package-googletest",
70+
"name": "googletest",
71+
"versionInfo": "1.17.0",
72+
"supplier": "Organization: Google LLC",
73+
"downloadLocation": "https://github.com/google/googletest/archive/refs/tags/v1.17.0.tar.gz",
74+
"filesAnalyzed": False,
75+
"licenseConcluded": "BSD-3-Clause",
76+
"licenseDeclared": "BSD-3-Clause",
77+
"copyrightText": "Copyright 2008 Google Inc.",
78+
"comment": "Build-time only dependency (unit tests).",
79+
"externalRefs": [
80+
{
81+
"referenceCategory": "PACKAGE-MANAGER",
82+
"referenceType": "purl",
83+
"referenceLocator": "pkg:github/google/googletest@v1.17.0",
84+
}
85+
],
86+
},
87+
],
88+
"relationships": [
89+
{
90+
"spdxElementId": "SPDXRef-DOCUMENT",
91+
"relatedSpdxElement": "SPDXRef-Package-how",
92+
"relationshipType": "DESCRIBES",
93+
},
94+
{
95+
"spdxElementId": "SPDXRef-Package-how",
96+
"relatedSpdxElement": "SPDXRef-Package-libcurl",
97+
"relationshipType": "DEPENDS_ON",
98+
},
99+
{
100+
"spdxElementId": "SPDXRef-Package-how",
101+
"relatedSpdxElement": "SPDXRef-Package-nlohmann-json",
102+
"relationshipType": "DEPENDS_ON",
103+
},
104+
{
105+
"spdxElementId": "SPDXRef-Package-how",
106+
"relatedSpdxElement": "SPDXRef-Package-googletest",
107+
"relationshipType": "DEV_DEPENDENCY_OF",
108+
},
109+
],
110+
}
111+
112+
print(json.dumps(sbom, indent=2))

0 commit comments

Comments
 (0)