From d5e779ecca2a70925600b3ebd45f94fbe7f2cf41 Mon Sep 17 00:00:00 2001 From: Anjali Trace Date: Fri, 6 Feb 2026 16:23:00 +0000 Subject: [PATCH 01/14] NRL-1928 Generate bill of materials in a dedicated release pipeline --- .github/workflows/daily-build.yml | 15 ------- .github/workflows/release.yml | 67 ++++++++++++++++++++++++++++++- scripts/sbom-create.sh | 9 +++++ scripts/sbom-update.py | 21 ++++++++++ 4 files changed, 96 insertions(+), 16 deletions(-) create mode 100644 scripts/sbom-create.sh create mode 100644 scripts/sbom-update.py diff --git a/.github/workflows/daily-build.yml b/.github/workflows/daily-build.yml index c0b61d867..f7c84d787 100644 --- a/.github/workflows/daily-build.yml +++ b/.github/workflows/daily-build.yml @@ -67,18 +67,3 @@ jobs: with: key: ${{ github.run_id }}-nrlf-permissions path: dist/nrlf_permissions.zip - - sbom: - name: Generate SBOM - ${{ github.ref }} - runs-on: ubuntu-latest - - steps: - - name: Git clone - ${{ github.ref }} - uses: actions/checkout@v4 - with: - ref: ${{ github.ref }} - - - name: Generate SBOM - uses: nhs-england-tools/trivy-action/sbom-scan@v1.4.0 - with: - repo-path: "./" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 05ace11ec..9088989e1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,6 +5,9 @@ permissions: contents: read actions: write +env: + SYFT_VERSION: "1.27.1" + on: release: types: [published] @@ -15,7 +18,7 @@ on: jobs: sbom: - name: Generate SBOM - ${{ github.ref }} + name: Generate Software Bill of Materials - ${{ github.event.release.name }} runs-on: ubuntu-latest steps: @@ -23,3 +26,65 @@ jobs: uses: actions/checkout@v4 with: ref: ${{ github.ref }} + + - name: Set architecture variable + id: os-arch + run: | + case "${{ runner.arch }}" in + X64) ARCH="amd64" ;; + ARM64) ARCH="arm64" ;; + esac + echo "arch=${ARCH}" >> $GITHUB_OUTPUT + + - name: Download and setup Syft + run: | + DOWNLOAD_URL="https://github.com/anchore/syft/releases/download/v${{ env.SYFT_VERSION }}/syft_${{ env.SYFT_VERSION }}_linux_${{ steps.os-arch.outputs.arch }}.tar.gz" + echo "Downloading: ${DOWNLOAD_URL}" + curl -L -o syft.tar.gz "${DOWNLOAD_URL}" + tar -xzf syft.tar.gz + chmod +x syft + # Add to PATH for subsequent steps + echo "$(pwd)" >> $GITHUB_PATH + + - name: Create SBOM + run: bash scripts/sbom-create.sh + + - name: Upload SBOM artifact + uses: actions/upload-artifact@v4 + with: + name: sbom-${{ github.sha }} + path: sbom.spdx.json + + - name: Append SBOM inventory to summary + if: always() + shell: bash + run: | + cat > sbom_to_summary.jq <<'JQ' + def clean: (.|tostring) | gsub("\\|"; "\\|") | gsub("\r?\n"; " "); + def purl: ((.externalRefs[]? | select(.referenceType=="purl") | .referenceLocator) // ""); + def license: (.licenseConcluded // .licenseDeclared // ""); + def supplier: ((.supplier // "") | sub("^Person: *|^Organization: *";"")); + if (has("spdxVersion") | not) then + "### SBOM Inventory (SPDX)\n\nSBOM is not SPDX JSON." + else + .packages as $pkgs + | "### SBOM Inventory (SPDX)\n\n" + + "| Metric | Value |\n|---|---|\n" + + "| Packages | " + ($pkgs|length|tostring) + " |\n\n" + + "
Full inventory\n\n" + + "| Package | Version | Supplier | License | PURL |\n|---|---|---|---|---|\n" + + ( + $pkgs + | map("| " + + ((.name // .SPDXID) | clean) + + " | " + ((.versionInfo // "") | clean) + + " | " + (supplier | clean) + + " | " + (license | clean) + + " | " + (purl | clean) + + " |") + | join("\n") + ) + + "\n\n
\n" + end + JQ + jq -r -f sbom_to_summary.jq sbom.spdx.json >> "$GITHUB_STEP_SUMMARY" diff --git a/scripts/sbom-create.sh b/scripts/sbom-create.sh new file mode 100644 index 000000000..eb541ba70 --- /dev/null +++ b/scripts/sbom-create.sh @@ -0,0 +1,9 @@ +REPO_ROOT=$(git rev-parse --show-toplevel) + +syft -o spdx-json . > sbom.spdx.json + +# for tool in "$@"; do +# echo "Creating SBOM for $tool and merging" +# # syft -q -o spdx-json "$(which "$tool")" | python "$REPO_ROOT/scripts/sbom-update.py" +# syft -q -o spdx-json "$(which "$tool")" +# done diff --git a/scripts/sbom-update.py b/scripts/sbom-update.py new file mode 100644 index 000000000..cf370e1bb --- /dev/null +++ b/scripts/sbom-update.py @@ -0,0 +1,21 @@ +import json +import sys +from pathlib import Path + + +def main() -> None: + with Path("sbom.spdx.json").open("r") as f: + sbom = json.load(f) + + tool = json.loads(sys.stdin.read()) + + sbom.setdefault("packages", []).extend(tool.setdefault("packages", [])) + sbom.setdefault("files", []).extend(tool.setdefault("files", [])) + sbom.setdefault("relationships", []).extend(tool.setdefault("relationships", [])) + + with Path("sbom.spdx.json").open("w") as f: + json.dump(sbom, f) + + +if __name__ == "__main__": + main() From db833d8b365164506c1d7517e5ce4a776df04ac0 Mon Sep 17 00:00:00 2001 From: Anjali Trace Date: Fri, 6 Feb 2026 16:25:55 +0000 Subject: [PATCH 02/14] NRL-1928 Use NRL runner --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9088989e1..0a348368d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -19,7 +19,7 @@ on: jobs: sbom: name: Generate Software Bill of Materials - ${{ github.event.release.name }} - runs-on: ubuntu-latest + runs-on: codebuild-nhsd-nrlf-ci-build-project-${{ github.run_id }}-${{ github.run_attempt }} steps: - name: Git clone - ${{ github.ref }} From 44510398d55a45428a10e676e8eb7b81969520cc Mon Sep 17 00:00:00 2001 From: Anjali Trace Date: Fri, 6 Feb 2026 16:30:47 +0000 Subject: [PATCH 03/14] NRL-1928 Just poetry deps --- .github/workflows/release.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0a348368d..f3d40b1e5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,6 +27,11 @@ jobs: with: ref: ${{ github.ref }} + - name: Setup environment + run: | + echo "${HOME}/.asdf/bin" >> $GITHUB_PATH + poetry install --no-root + - name: Set architecture variable id: os-arch run: | From ae695079529eb973c81cbc7f617bf150103b1878 Mon Sep 17 00:00:00 2001 From: Anjali Trace Date: Fri, 6 Feb 2026 16:34:35 +0000 Subject: [PATCH 04/14] NRL-1928 Init terraform --- .github/workflows/release.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f3d40b1e5..96acf474e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,6 +32,18 @@ jobs: echo "${HOME}/.asdf/bin" >> $GITHUB_PATH poetry install --no-root + - name: Configure Management Credentials + uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a #v4.3.1 + with: + aws-region: eu-west-2 + role-to-assume: ${{ secrets.MGMT_ROLE_ARN }} + role-session-name: github-actions-ci-release-tag-${{ github.run_id }} + + - name: Terraform Init + env: + ENVIRONMENT: dev + run: terraform -chdir=terraform/infrastructure init + - name: Set architecture variable id: os-arch run: | From 29b9dc85bd7b47f475d4fd783833b1aa57efc110 Mon Sep 17 00:00:00 2001 From: Anjali Trace Date: Fri, 6 Feb 2026 16:45:14 +0000 Subject: [PATCH 05/14] NRL-1928 Init terraform with modules setup instead --- .github/workflows/release.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 96acf474e..ad68499f1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,9 +40,8 @@ jobs: role-session-name: github-actions-ci-release-tag-${{ github.run_id }} - name: Terraform Init - env: - ENVIRONMENT: dev - run: terraform -chdir=terraform/infrastructure init + run: | + terraform -chdir=terraform/backup-infrastructure init - name: Set architecture variable id: os-arch From cc196c770471277cd0ae9dc1a36d55737507c1f0 Mon Sep 17 00:00:00 2001 From: Anjali Trace Date: Fri, 6 Feb 2026 16:58:36 +0000 Subject: [PATCH 06/14] NRL-1928 Init terraform with modules setup instead (per env) --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ad68499f1..805e0d4ac 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -41,7 +41,7 @@ jobs: - name: Terraform Init run: | - terraform -chdir=terraform/backup-infrastructure init + terraform -chdir=terraform/backup-infrastructure/test init - name: Set architecture variable id: os-arch From ba07f6ee2647183b6b5d2cb4d0e92572ea12531d Mon Sep 17 00:00:00 2001 From: Anjali Trace Date: Fri, 6 Feb 2026 17:04:20 +0000 Subject: [PATCH 07/14] NRL-1928 Init terraform with modules setup instead (per env) for all tf folders --- .github/workflows/release.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 805e0d4ac..398205d9f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -41,7 +41,14 @@ jobs: - name: Terraform Init run: | + terraform -chdir=terraform/account-wide-infrastructure/mgmt init + terraform -chdir=terraform/account-wide-infrastructure/dev init + terraform -chdir=terraform/account-wide-infrastructure/test init + terraform -chdir=terraform/account-wide-infrastructure/prod init terraform -chdir=terraform/backup-infrastructure/test init + terraform -chdir=terraform/backup-infrastructure/prod init + terraform -chdir=terraform/bastion init + terraform -chdir=terraform/infrastructure init - name: Set architecture variable id: os-arch From 19eb1e1326ee9de4bf3e3ffa39dc67733728633b Mon Sep 17 00:00:00 2001 From: Anjali Trace Date: Mon, 9 Feb 2026 10:37:10 +0000 Subject: [PATCH 08/14] NRL-1928 Generate asdf SBOM and merge into big python + tf one --- .github/workflows/release.yml | 4 + .gitignore | 3 + scripts/sbom-create.sh | 6 +- scripts/sbom_from_asdf.py | 105 +++++++++++++++++++++ scripts/{sbom-update.py => sbom_update.py} | 10 +- 5 files changed, 119 insertions(+), 9 deletions(-) create mode 100644 scripts/sbom_from_asdf.py rename scripts/{sbom-update.py => sbom_update.py} (68%) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 398205d9f..1a13f07a1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -72,6 +72,10 @@ jobs: - name: Create SBOM run: bash scripts/sbom-create.sh + - name: Generate ASDF SBOM + working-directory: ./main-repo + run: poetry run python scripts/asdf_to_sbom.py + - name: Upload SBOM artifact uses: actions/upload-artifact@v4 with: diff --git a/.gitignore b/.gitignore index 7ee6f3701..0ce0f1dc2 100644 --- a/.gitignore +++ b/.gitignore @@ -84,3 +84,6 @@ producer-internal-*.json producer-public-*.json consumer-internal-*.json consumer-public-*.json + +# SBOM files +sbom*.spdx.json diff --git a/scripts/sbom-create.sh b/scripts/sbom-create.sh index eb541ba70..97e732944 100644 --- a/scripts/sbom-create.sh +++ b/scripts/sbom-create.sh @@ -2,8 +2,4 @@ REPO_ROOT=$(git rev-parse --show-toplevel) syft -o spdx-json . > sbom.spdx.json -# for tool in "$@"; do -# echo "Creating SBOM for $tool and merging" -# # syft -q -o spdx-json "$(which "$tool")" | python "$REPO_ROOT/scripts/sbom-update.py" -# syft -q -o spdx-json "$(which "$tool")" -# done +poetry run python "$REPO_ROOT/scripts/sbom_from_asdf.py" | poetry run python "$REPO_ROOT/scripts/sbom_update.py" diff --git a/scripts/sbom_from_asdf.py b/scripts/sbom_from_asdf.py new file mode 100644 index 000000000..dd0913753 --- /dev/null +++ b/scripts/sbom_from_asdf.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python3 +"""Generate an SBOM-looking document for our asdf dependencies""" + +import json +import re +from pathlib import Path + + +def parse_tool_versions(file_path=".tool-versions"): + tools = [] + + if not Path(file_path).exists(): + return tools + + with open(file_path, "r") as f: + for line in f: + line = line.strip() + if not line or line.startswith("#"): + continue + + parts = line.split() + if len(parts) >= 2: + tool_name = parts[0] + version = parts[1] + tools.append({"name": tool_name, "version": version}) + + return tools + + +# def create_spdx_package(tool, index): +# package_id = f"SPDXRef-Package-asdf-{tool['name']}-{index}" + +# return { +# "name": tool["name"], +# "SPDXID": package_id, +# "versionInfo": tool["version"], +# "supplier": "NOASSERTION", +# "downloadLocation": "NOASSERTION", +# "filesAnalyzed": False, +# "sourceInfo": "ASDF-managed tool: acquired package info from /.tool-versions", +# "licenseConcluded": "NOASSERTION", +# "licenseDeclared": "NOASSERTION", +# "copyrightText": "NOASSERTION", +# "externalRefs": [ +# { +# "referenceCategory": "PACKAGE-MANAGER", +# "referenceType": "purl", +# "referenceLocator": f"pkg:generic/{tool['name']}@{tool['version']}", +# } +# ], +# } + + +def generate_asdf_sbom(output_file="sbom-asdf.spdx.json"): + tools = parse_tool_versions() + + print(f"Found {len(tools)} ASDF-managed tools") + + sbom = { + "spdxVersion": "SPDX-2.3", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT", + "name": "asdf-tools", + "packages": [ + { + "name": tool["name"], + "SPDXID": f"SPDXRef-Package-asdf-{tool['name']}-{index}", + "versionInfo": tool["version"], + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": False, + "sourceInfo": "ASDF-managed tool: acquired package info from /.tool-versions", + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": f"pkg:generic/{tool['name']}@{tool['version']}", + } + ], + } + for index, tool in enumerate(tools) + ], + # "packages": [create_spdx_package(tool, idx) for idx, tool in enumerate(tools)], + "relationships": [ + { + "spdxElementId": "SPDXRef-DOCUMENT", + "relationshipType": "DESCRIBES", + "relatedSpdxElement": f"SPDXRef-Package-asdf-{tool['name']}-{index}", + } + for index, tool in enumerate(tools) + ], + } + + with open(output_file, "w") as f: + json.dump(sbom, f, indent=2) + + print(f"Generated SBOM with {len(tools)} ASDF-managed tools") + return output_file + + +if __name__ == "__main__": + generate_asdf_sbom() diff --git a/scripts/sbom-update.py b/scripts/sbom_update.py similarity index 68% rename from scripts/sbom-update.py rename to scripts/sbom_update.py index cf370e1bb..7177d9be8 100644 --- a/scripts/sbom-update.py +++ b/scripts/sbom_update.py @@ -2,9 +2,11 @@ import sys from pathlib import Path +import fire -def main() -> None: - with Path("sbom.spdx.json").open("r") as f: + +def update_sbom(existing_sbom="sbom.spdx.json") -> None: + with Path(existing_sbom).open("r") as f: sbom = json.load(f) tool = json.loads(sys.stdin.read()) @@ -13,9 +15,9 @@ def main() -> None: sbom.setdefault("files", []).extend(tool.setdefault("files", [])) sbom.setdefault("relationships", []).extend(tool.setdefault("relationships", [])) - with Path("sbom.spdx.json").open("w") as f: + with Path(existing_sbom).open("w") as f: json.dump(sbom, f) if __name__ == "__main__": - main() + fire.Fire(update_sbom) From 56077fee341a0222ad45cedef7cee3320bbbe929 Mon Sep 17 00:00:00 2001 From: Anjali Trace Date: Mon, 9 Feb 2026 14:26:10 +0000 Subject: [PATCH 09/14] NRL-1928 Merge SBOMs better --- .github/workflows/release.yml | 4 ---- scripts/sbom-create.sh | 8 +++++++- scripts/sbom_from_asdf.py | 26 -------------------------- scripts/sbom_update.py | 21 ++++++++++++++------- 4 files changed, 21 insertions(+), 38 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1a13f07a1..398205d9f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -72,10 +72,6 @@ jobs: - name: Create SBOM run: bash scripts/sbom-create.sh - - name: Generate ASDF SBOM - working-directory: ./main-repo - run: poetry run python scripts/asdf_to_sbom.py - - name: Upload SBOM artifact uses: actions/upload-artifact@v4 with: diff --git a/scripts/sbom-create.sh b/scripts/sbom-create.sh index 97e732944..1b2ba07f5 100644 --- a/scripts/sbom-create.sh +++ b/scripts/sbom-create.sh @@ -1,5 +1,11 @@ REPO_ROOT=$(git rev-parse --show-toplevel) +echo REPO_ROOT: $REPO_ROOT + syft -o spdx-json . > sbom.spdx.json -poetry run python "$REPO_ROOT/scripts/sbom_from_asdf.py" | poetry run python "$REPO_ROOT/scripts/sbom_update.py" +ASDF_SBOM="sbom-asdf.spdx.json" + +poetry run python "$REPO_ROOT/scripts/sbom_from_asdf.py" $ASDF_SBOM + +poetry run python "$REPO_ROOT/scripts/sbom_update.py" $ASDF_SBOM "sbom.spdx.json" diff --git a/scripts/sbom_from_asdf.py b/scripts/sbom_from_asdf.py index dd0913753..7e2e62819 100644 --- a/scripts/sbom_from_asdf.py +++ b/scripts/sbom_from_asdf.py @@ -2,7 +2,6 @@ """Generate an SBOM-looking document for our asdf dependencies""" import json -import re from pathlib import Path @@ -27,30 +26,6 @@ def parse_tool_versions(file_path=".tool-versions"): return tools -# def create_spdx_package(tool, index): -# package_id = f"SPDXRef-Package-asdf-{tool['name']}-{index}" - -# return { -# "name": tool["name"], -# "SPDXID": package_id, -# "versionInfo": tool["version"], -# "supplier": "NOASSERTION", -# "downloadLocation": "NOASSERTION", -# "filesAnalyzed": False, -# "sourceInfo": "ASDF-managed tool: acquired package info from /.tool-versions", -# "licenseConcluded": "NOASSERTION", -# "licenseDeclared": "NOASSERTION", -# "copyrightText": "NOASSERTION", -# "externalRefs": [ -# { -# "referenceCategory": "PACKAGE-MANAGER", -# "referenceType": "purl", -# "referenceLocator": f"pkg:generic/{tool['name']}@{tool['version']}", -# } -# ], -# } - - def generate_asdf_sbom(output_file="sbom-asdf.spdx.json"): tools = parse_tool_versions() @@ -83,7 +58,6 @@ def generate_asdf_sbom(output_file="sbom-asdf.spdx.json"): } for index, tool in enumerate(tools) ], - # "packages": [create_spdx_package(tool, idx) for idx, tool in enumerate(tools)], "relationships": [ { "spdxElementId": "SPDXRef-DOCUMENT", diff --git a/scripts/sbom_update.py b/scripts/sbom_update.py index 7177d9be8..b40d0e440 100644 --- a/scripts/sbom_update.py +++ b/scripts/sbom_update.py @@ -1,19 +1,26 @@ +#!/usr/bin/env python3 +""" +Merge two SBOMs together + +packages, files, and relationships from new_sbom will be merged into existing_sbom +""" + import json -import sys from pathlib import Path import fire -def update_sbom(existing_sbom="sbom.spdx.json") -> None: +def update_sbom(new_sbom, existing_sbom="sbom.spdx.json") -> None: + with Path(new_sbom).open("r") as f: + updates = json.load(f) + with Path(existing_sbom).open("r") as f: sbom = json.load(f) - tool = json.loads(sys.stdin.read()) - - sbom.setdefault("packages", []).extend(tool.setdefault("packages", [])) - sbom.setdefault("files", []).extend(tool.setdefault("files", [])) - sbom.setdefault("relationships", []).extend(tool.setdefault("relationships", [])) + sbom.setdefault("packages", []).extend(updates.setdefault("packages", [])) + sbom.setdefault("files", []).extend(updates.setdefault("files", [])) + sbom.setdefault("relationships", []).extend(updates.setdefault("relationships", [])) with Path(existing_sbom).open("w") as f: json.dump(sbom, f) From 5389e6ce5ba9f670f552671c22d4df0cd87ce013 Mon Sep 17 00:00:00 2001 From: Anjali Trace Date: Tue, 10 Feb 2026 09:19:41 +0000 Subject: [PATCH 10/14] NRL-1928 make reference less generic for asdf sbom entries --- scripts/sbom_from_asdf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/sbom_from_asdf.py b/scripts/sbom_from_asdf.py index 7e2e62819..51dba66c4 100644 --- a/scripts/sbom_from_asdf.py +++ b/scripts/sbom_from_asdf.py @@ -52,7 +52,7 @@ def generate_asdf_sbom(output_file="sbom-asdf.spdx.json"): { "referenceCategory": "PACKAGE-MANAGER", "referenceType": "purl", - "referenceLocator": f"pkg:generic/{tool['name']}@{tool['version']}", + "referenceLocator": f"pkg:asdf/{tool['name']}@{tool['version']}", } ], } From 6ad69259e4fc9876c8db2c8caf70f6eb6fd73362 Mon Sep 17 00:00:00 2001 From: Anjali Trace Date: Tue, 10 Feb 2026 09:28:03 +0000 Subject: [PATCH 11/14] NRL-1928 Upload SBOM to release if triggered by one --- .github/workflows/release.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 398205d9f..0da492e0c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -111,3 +111,17 @@ jobs: end JQ jq -r -f sbom_to_summary.jq sbom.spdx.json >> "$GITHUB_STEP_SUMMARY" + + # - name: Upload SBOM to release + # run: | + # gh release upload ${{ github.event.release.tag_name }} sbom.spdx.json + # env: + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Upload SBOM to release but better + if: ${{ github.event.release.tag_name }} + uses: svenstaro/upload-release-action@v2 + with: + file: sbom.spdx.json + asset_name: sbom-${{ github.ref }} + tag: ${{ github.ref }} From bc232f995116d6b890cc2c1f01f74130db232346 Mon Sep 17 00:00:00 2001 From: Anjali Trace Date: Tue, 10 Feb 2026 14:11:48 +0000 Subject: [PATCH 12/14] NRL-1928 Allow pipeline to auth with github to upload sbom to release --- .github/workflows/release.yml | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0da492e0c..f447182d0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,8 +1,8 @@ -name: Release +name: Release Published run-name: Release NRL ${{ github.event.release.name }} permissions: id-token: write - contents: read + contents: write actions: write env: @@ -112,16 +112,11 @@ jobs: JQ jq -r -f sbom_to_summary.jq sbom.spdx.json >> "$GITHUB_STEP_SUMMARY" - # - name: Upload SBOM to release - # run: | - # gh release upload ${{ github.event.release.tag_name }} sbom.spdx.json - # env: - # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Upload SBOM to release but better + - name: Upload SBOM to release if: ${{ github.event.release.tag_name }} uses: svenstaro/upload-release-action@v2 with: file: sbom.spdx.json - asset_name: sbom-${{ github.ref }} + asset_name: sbom-${{ github.event.release.tag_name }} tag: ${{ github.ref }} + repo_token: ${{ secrets.GITHUB_TOKEN }} From 6e083fe6e21ede80505d8ae284e1530a477cced6 Mon Sep 17 00:00:00 2001 From: Anjali Trace Date: Tue, 10 Feb 2026 14:56:08 +0000 Subject: [PATCH 13/14] NRL-1928 Use fire and remove prints --- scripts/sbom-create.sh | 2 -- scripts/sbom_from_asdf.py | 4 +++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/sbom-create.sh b/scripts/sbom-create.sh index 1b2ba07f5..16a547472 100644 --- a/scripts/sbom-create.sh +++ b/scripts/sbom-create.sh @@ -1,7 +1,5 @@ REPO_ROOT=$(git rev-parse --show-toplevel) -echo REPO_ROOT: $REPO_ROOT - syft -o spdx-json . > sbom.spdx.json ASDF_SBOM="sbom-asdf.spdx.json" diff --git a/scripts/sbom_from_asdf.py b/scripts/sbom_from_asdf.py index 51dba66c4..d2ecafc0d 100644 --- a/scripts/sbom_from_asdf.py +++ b/scripts/sbom_from_asdf.py @@ -4,6 +4,8 @@ import json from pathlib import Path +import fire + def parse_tool_versions(file_path=".tool-versions"): tools = [] @@ -76,4 +78,4 @@ def generate_asdf_sbom(output_file="sbom-asdf.spdx.json"): if __name__ == "__main__": - generate_asdf_sbom() + fire.Fire(generate_asdf_sbom) From d6630330ba81019740a71ad342ca6fc277786820 Mon Sep 17 00:00:00 2001 From: Anjali Trace Date: Tue, 10 Feb 2026 15:12:11 +0000 Subject: [PATCH 14/14] NRL-1928 Make socar qube happy by getting specific with action version --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f447182d0..fa7dc4d8b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -114,7 +114,7 @@ jobs: - name: Upload SBOM to release if: ${{ github.event.release.tag_name }} - uses: svenstaro/upload-release-action@v2 + uses: svenstaro/upload-release-action@v2.11.3 with: file: sbom.spdx.json asset_name: sbom-${{ github.event.release.tag_name }}