Skip to content

Commit b243398

Browse files
authored
feat(build): add SPDX 2.3 SBOM generation for builds (#26731)
1 parent 1d80fc3 commit b243398

16 files changed

+1308
-4
lines changed

.github/workflows/build_all_targets.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,4 +268,5 @@ jobs:
268268
files: |
269269
artifacts/*.px4
270270
artifacts/*.deb
271+
artifacts/**/*.sbom.spdx.json
271272
name: ${{ steps.upload-location.outputs.uploadlocation }}

.github/workflows/checks.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ jobs:
4646
fetch-depth: 0
4747

4848
- name: Building [${{ matrix.check }}]
49+
env:
50+
PX4_SBOM_DISABLE: 1
4951
run: |
5052
cd "$GITHUB_WORKSPACE"
5153
git config --global --add safe.directory "$GITHUB_WORKSPACE"

.github/workflows/mavros_mission_tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ jobs:
3636
px4io/px4-dev-ros-melodic:2021-09-08 \
3737
bash -c '
3838
git config --global --add safe.directory /workspace
39-
make px4_sitl_default
40-
make px4_sitl_default sitl_gazebo-classic
39+
PX4_SBOM_DISABLE=1 make px4_sitl_default
40+
PX4_SBOM_DISABLE=1 make px4_sitl_default sitl_gazebo-classic
4141
./test/rostest_px4_run.sh \
4242
mavros_posix_test_mission.test \
4343
mission:=MC_mission_box \

.github/workflows/mavros_offboard_tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ jobs:
3636
px4io/px4-dev-ros-melodic:2021-09-08 \
3737
bash -c '
3838
git config --global --add safe.directory /workspace
39-
make px4_sitl_default
40-
make px4_sitl_default sitl_gazebo-classic
39+
PX4_SBOM_DISABLE=1 make px4_sitl_default
40+
PX4_SBOM_DISABLE=1 make px4_sitl_default sitl_gazebo-classic
4141
./test/rostest_px4_run.sh \
4242
mavros_posix_tests_offboard_posctl.test \
4343
vehicle:=iris

.github/workflows/ros_integration_tests.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ jobs:
110110
run: ccache -s
111111

112112
- name: Build PX4
113+
env:
114+
PX4_SBOM_DISABLE: 1
113115
run: make px4_sitl_default
114116
- name: ccache post-run px4/firmware
115117
run: ccache -s
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: SBOM License Check
2+
3+
on:
4+
push:
5+
branches:
6+
- 'main'
7+
- 'release/**'
8+
- 'stable'
9+
paths:
10+
- '.gitmodules'
11+
- 'Tools/ci/license-overrides.yaml'
12+
- 'Tools/ci/generate_sbom.py'
13+
pull_request:
14+
branches:
15+
- '**'
16+
paths:
17+
- '.gitmodules'
18+
- 'Tools/ci/license-overrides.yaml'
19+
- 'Tools/ci/generate_sbom.py'
20+
21+
permissions:
22+
contents: read
23+
24+
concurrency:
25+
group: ${{ github.workflow }}-${{ github.ref }}
26+
cancel-in-progress: true
27+
28+
jobs:
29+
verify-licenses:
30+
runs-on: ubuntu-24.04
31+
32+
steps:
33+
- uses: actions/checkout@v4
34+
with:
35+
fetch-depth: 1
36+
submodules: false
37+
38+
- name: Install PyYAML
39+
run: pip install pyyaml --break-system-packages
40+
41+
- name: Verify submodule licenses
42+
run: python3 Tools/ci/generate_sbom.py --verify-licenses --source-dir .
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
name: SBOM Monthly Audit
2+
3+
on:
4+
schedule:
5+
# First Monday of each month at 09:00 UTC
6+
- cron: '0 9 1-7 * 1'
7+
workflow_dispatch:
8+
inputs:
9+
branch:
10+
description: 'Branch to audit (leave empty for current)'
11+
required: false
12+
type: string
13+
14+
permissions:
15+
contents: read
16+
issues: write
17+
18+
jobs:
19+
audit:
20+
runs-on: ubuntu-24.04
21+
22+
steps:
23+
- uses: actions/checkout@v4
24+
with:
25+
ref: ${{ inputs.branch || github.ref }}
26+
fetch-depth: 1
27+
submodules: recursive
28+
29+
- name: Install PyYAML
30+
run: pip install pyyaml --break-system-packages
31+
32+
- name: Run license verification
33+
id: verify
34+
continue-on-error: true
35+
run: |
36+
python3 Tools/ci/generate_sbom.py --verify-licenses --source-dir . 2>&1 | tee /tmp/sbom-verify.txt
37+
echo "exit_code=$?" >> "$GITHUB_OUTPUT"
38+
39+
- name: Check for issues
40+
id: check
41+
run: |
42+
if grep -q "NOASSERTION" /tmp/sbom-verify.txt; then
43+
echo "has_issues=true" >> "$GITHUB_OUTPUT"
44+
# Extract NOASSERTION lines
45+
grep "NOASSERTION" /tmp/sbom-verify.txt | grep -v "skipped" > /tmp/sbom-issues.txt || true
46+
# Extract copyleft lines
47+
sed -n '/Copyleft licenses detected/,/^$/p' /tmp/sbom-verify.txt > /tmp/sbom-copyleft.txt || true
48+
else
49+
echo "has_issues=false" >> "$GITHUB_OUTPUT"
50+
fi
51+
52+
- name: Create issue if problems found
53+
if: steps.check.outputs.has_issues == 'true'
54+
uses: actions/github-script@v7
55+
with:
56+
script: |
57+
const fs = require('fs');
58+
59+
const fullOutput = fs.readFileSync('/tmp/sbom-verify.txt', 'utf8');
60+
let issueLines = '';
61+
try {
62+
issueLines = fs.readFileSync('/tmp/sbom-issues.txt', 'utf8');
63+
} catch (e) {
64+
issueLines = 'No specific NOASSERTION lines captured.';
65+
}
66+
let copyleftLines = '';
67+
try {
68+
copyleftLines = fs.readFileSync('/tmp/sbom-copyleft.txt', 'utf8');
69+
} catch (e) {
70+
copyleftLines = '';
71+
}
72+
73+
const date = new Date().toISOString().split('T')[0];
74+
const branch = '${{ inputs.branch || github.ref_name }}';
75+
76+
// Check for existing open issue to avoid duplicates
77+
const existing = await github.rest.issues.listForRepo({
78+
owner: context.repo.owner,
79+
repo: context.repo.repo,
80+
labels: 'sbom-audit',
81+
state: 'open',
82+
});
83+
84+
if (existing.data.length > 0) {
85+
// Update existing issue with new findings
86+
await github.rest.issues.createComment({
87+
owner: context.repo.owner,
88+
repo: context.repo.repo,
89+
issue_number: existing.data[0].number,
90+
body: `## Monthly audit update (${date})\n\nIssues still present:\n\n\`\`\`\n${issueLines}\n\`\`\`\n${copyleftLines ? `\n### Copyleft warnings\n\`\`\`\n${copyleftLines}\n\`\`\`` : ''}`,
91+
});
92+
return;
93+
}
94+
95+
await github.rest.issues.create({
96+
owner: context.repo.owner,
97+
repo: context.repo.repo,
98+
title: `chore(sbom): license audit found NOASSERTION entries on ${branch} (${date})`,
99+
labels: ['sbom-audit'],
100+
assignees: ['mrpollo'],
101+
body: [
102+
`## SBOM Monthly Audit -- ${branch} -- ${date}`,
103+
'',
104+
'The automated SBOM license audit found submodules with unresolved licenses.',
105+
'',
106+
'### NOASSERTION entries',
107+
'',
108+
'```',
109+
issueLines,
110+
'```',
111+
'',
112+
copyleftLines ? `### Copyleft warnings\n\n\`\`\`\n${copyleftLines}\n\`\`\`\n` : '',
113+
'### How to fix',
114+
'',
115+
'1. Check the submodule repo for a LICENSE file',
116+
'2. Add an override to `Tools/ci/license-overrides.yaml`',
117+
'3. Run `python3 Tools/ci/generate_sbom.py --verify-licenses --source-dir .` to confirm',
118+
'',
119+
'### Full output',
120+
'',
121+
'<details>',
122+
'<summary>Click to expand</summary>',
123+
'',
124+
'```',
125+
fullOutput,
126+
'```',
127+
'',
128+
'</details>',
129+
'',
130+
'cc @mrpollo',
131+
].join('\n'),
132+
});

.github/workflows/sitl_tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ jobs:
7171
- name: Build PX4
7272
env:
7373
PX4_CMAKE_BUILD_TYPE: ${{matrix.config.build_type}}
74+
PX4_SBOM_DISABLE: 1
7475
run: make px4_sitl_default
7576

7677
- name: Cache Post-Run [px4_sitl_default]

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,7 @@ include(bloaty)
484484

485485
include(metadata)
486486
include(package)
487+
include(sbom)
487488

488489
# install python requirements using configured python
489490
add_custom_target(install_python_requirements

0 commit comments

Comments
 (0)