From 32b49392d99c9377a29bd664d863e36d18ad6190 Mon Sep 17 00:00:00 2001 From: redcatbear Date: Thu, 13 Aug 2026 20:57:56 +0200 Subject: [PATCH 1/3] #527: Basic SPDX SBOM --- .github/workflows/github_release.sh | 5 +- doc/changesets/527-spdx-sbom.md | 116 ++++++++++++++++++ doc/developer_guide.md | 5 +- doc/spec/design.md | 28 +++++ doc/spec/system_requirements.md | 33 +++++ oft-self-trace.sh | 2 + product/pom.xml | 23 ++++ .../openfasttrace/ITestSelfTrace.java | 2 + .../itsallcode/openfasttrace/SpdxSbomIT.java | 51 ++++++++ 9 files changed, 262 insertions(+), 3 deletions(-) create mode 100644 doc/changesets/527-spdx-sbom.md create mode 100644 product/src/test/java/org/itsallcode/openfasttrace/SpdxSbomIT.java diff --git a/.github/workflows/github_release.sh b/.github/workflows/github_release.sh index 36b812042..31fc8b928 100755 --- a/.github/workflows/github_release.sh +++ b/.github/workflows/github_release.sh @@ -15,6 +15,7 @@ echo "Read project version '$project_version' from $pom_file" # Calculate checksum readonly artifact_path="$base_dir/product/target/openfasttrace-${project_version}.jar" +readonly sbom_path="$base_dir/product/target/openfasttrace-${project_version}.spdx3.json" echo "Calculate sha256sum for file '$artifact_path'" file_dir="$(dirname "$artifact_path")" readonly file_dir @@ -40,7 +41,9 @@ echo "Title : $title" echo "Changes file : $changes_file" echo "Artifact file: $artifact_path" echo "Checksum file: $checksum_file_path" +echo "SBOM file : $sbom_path" -release_url=$(gh release create --latest --title "$title" --notes "$notes" --target main "$tag" "$artifact_path" "$checksum_file_path") +# [impl->dsn~build.spdx-sbom-release-asset~1] +release_url=$(gh release create --latest --title "$title" --notes "$notes" --target main "$tag" "$artifact_path" "$checksum_file_path" "$sbom_path") readonly release_url echo "Release URL: $release_url" diff --git a/doc/changesets/527-spdx-sbom.md b/doc/changesets/527-spdx-sbom.md new file mode 100644 index 000000000..04b6eef1e --- /dev/null +++ b/doc/changesets/527-spdx-sbom.md @@ -0,0 +1,116 @@ +# GH-527 SPDX SBOM + +## Goal + +Produce one SPDX 3 JSON software bill of materials (SBOM) for the OpenFastTrace +product during the Maven build and attach it to every GitHub release. The SBOM +must represent the product at module granularity, include compile, runtime, and +provided dependencies, and retain available dependency-license information. + +## Scope + +In scope: + +* Define the build and release requirements for the product SPDX SBOM. +* Add and configure the SPDX Maven Plugin for the `product` module only. +* Generate `openfasttrace-.spdx3.json` as part of the regular Maven + build. +* Include compile, runtime, and provided dependencies. +* Ensure the release workflow uploads the SBOM with the product JAR and its + checksum. + +Out of scope: + +* File-level or snippet-level SPDX resolution. +* SBOMs for individual OpenFastTrace modules. +* Adding or correcting dependency license metadata not exposed by the resolved + Maven dependency metadata. +* Changing OpenFastTrace runtime behavior or its public CLI/API. + +## Design References + +* [System Requirements](../spec/system_requirements.md) +* [Design](../spec/design.md) +* [Quality Requirements](../spec/design/quality_requirements.md) +* [Maven build configuration](../../parent/pom.xml) +* [Product module](../../product/pom.xml) +* [Release workflow](../../.github/workflows/release.yml) +* [GitHub release script](../../.github/workflows/github_release.sh) +* [SPDX Maven Plugin documentation](https://spdx.github.io/spdx-maven-plugin/aggregateSPDX-mojo.html) + +## Strategy + +Configure the selected SPDX Maven Plugin in `product/pom.xml`, rather than in +the shared parent, so the reactor creates exactly one SBOM for the distributable +product. Bind `aggregateSPDX` to the normal Maven lifecycle, use SPDX 3 JSON-LD +output and the required product filename, and explicitly configure dependency +scope inclusion to make the acceptance criteria independent of plugin defaults. + +Extend the release script's explicit asset list with the generated SBOM. Keep +the SBOM beside the product JAR in `product/target` so the local build and the +release workflow consume the same artifact. + +The plugin's public documentation confirms that it produces SPDX documents from +Maven POM metadata, can emit SPDX 3 JSON-LD (`.spdx3.json`), and exposes the +required dependency-scope controls. Its documented default lifecycle binding is +`verify`; select and test the binding deliberately so both the current CI +`install` build and release build produce the file. + +## Task List + +- [x] Create and check out branch `feature/527_spdx_sbom`. + +### Requirements And Design + +- [x] Add `req~build.spdx-sbom~1` to `doc/spec/system_requirements.md`, covering + the product SBOM content, module granularity, required dependency scopes, + SPDX 3 JSON filename, and release availability; add scenarios for a + successful product build and a GitHub release asset. +- [x] Stop and ask the user for a review of the system requirements. +- [x] Add design items to `doc/spec/design.md` for product-module-only SPDX + generation and for publishing the generated SBOM with the release; map + each runtime design item to one scenario and require `impl` plus `itest` + coverage. +- [x] Record the selected generator version, output mode, lifecycle phase, + aggregation strategy, scope settings, and license metadata handling in + the design. +- [x] Stop and ask the user for a review of the design and approval to add the + external `org.spdx:spdx-maven-plugin`. + +### Implementation + +- [x] Add the approved SPDX Maven Plugin version and an execution to + `product/pom.xml`; configure `aggregateSPDX`, SPDX 3 JSON-LD output, + `openfasttrace-${revision}.spdx3.json`, module granularity, and + compile/runtime/provided inclusion. +- [x] Confirm the plugin generates only the product SBOM, contains the resolved + direct and transitive dependencies at module level, and preserves all + available declared license data; add narrowly scoped license overrides + only if the generated document demonstrates a required correction. +- [x] Add the SBOM as an explicit GitHub release asset in + `.github/workflows/github_release.sh`, alongside the JAR and `.sha256`. + +### Verification + +- [x] Add a Maven-build integration test that asserts exactly one product SBOM + exists with the versioned filename and verifies SPDX 3 JSON structure, + module-level dependency entries, the required scopes, and representative + available license fields. +- [x] Test the release script to prove it passes the SBOM path to + `gh release create`. +- [ ] Run `mvn -T 1C verify` and resolve all test, coverage, reproducibility, + static-analysis, and security-gate failures. +- [x] Run `./oft-self-trace.sh` and keep requirement, scenario, design, + implementation, and test coverage clean. + +### Update User Documentation + +- [x] Update `doc/developer_guide.md` to state where the SBOM is produced, how + to inspect it, and that release assets include it. Do not add end-user CLI + documentation because this introduces no runtime option. + +## Version And Changelog Update + +- [ ] During release preparation, update the version according to the release + policy and add the SPDX SBOM to `doc/changes/changes.md` and the matching + versioned changelog file. diff --git a/doc/developer_guide.md b/doc/developer_guide.md index ea69b416e..9af0f26df 100644 --- a/doc/developer_guide.md +++ b/doc/developer_guide.md @@ -122,7 +122,7 @@ Build OFT: mvn -T 1C package -DskipTests ``` -This will build the executable JAR including all modules at `product/target/openfasttrace-$VERSION.jar`. +This will build the executable JAR including all modules at `product/target/openfasttrace-$VERSION.jar` and the SPDX 3 SBOM at `product/target/openfasttrace-$VERSION.spdx3.json`. #### Specify Java Version @@ -259,7 +259,8 @@ The build will use the last Git commit timestamp as timestamp for files in `.jar * Run command `gh workflow run release.yml --repo itsallcode/openfasttrace --ref main` * or go to [GitHub Actions](https://github.com/itsallcode/openfasttrace/actions/workflows/release.yml) and start the `release.yml` workflow on branch `main`. 2. Update the title and description of the newly created [GitHub release](https://github.com/itsallcode/openfasttrace/releases). -3. After some time the release will be available at [Maven Central](https://repo1.maven.org/maven2/org/itsallcode/openfasttrace/openfasttrace/). +3. Download the JAR, checksum, and SPDX 3 SBOM from the release assets. The SBOM file is named `openfasttrace-$VERSION.spdx3.json`. +4. After some time the release will be available at [Maven Central](https://repo1.maven.org/maven2/org/itsallcode/openfasttrace/openfasttrace/). ## Module Overview diff --git a/doc/spec/design.md b/doc/spec/design.md index b18a4e7f1..59cb2fadd 100644 --- a/doc/spec/design.md +++ b/doc/spec/design.md @@ -844,6 +844,34 @@ Needs: impl, utest # Deployment View +# Cross-cutting Concerns + +## Build + +### Product SPDX SBOM Generation +`dsn~build.spdx-sbom-generation~1` + +The `product` module configures `org.spdx:spdx-maven-plugin` with the `aggregateSPDX` goal. The execution runs during the Maven lifecycle and creates `product/target/openfasttrace-${revision}.spdx3.json`. It uses SPDX 3 JSON-LD, aggregates the product's Maven modules, and includes compile, runtime, and provided dependency scopes. + +Covers: + +* `req~build.spdx-sbom~1` +* `scn~build.spdx-sbom-generation~1` + +Needs: impl, itest + +### Product SPDX SBOM Release Asset +`dsn~build.spdx-sbom-release-asset~1` + +The GitHub release script passes `product/target/openfasttrace-${revision}.spdx3.json` to `gh release create` with the product JAR and its checksum. + +Covers: + +* `req~build.spdx-sbom~1` +* `scn~build.spdx-sbom-release-asset~1` + +Needs: impl, itest + # Concepts ## Data Structures diff --git a/doc/spec/system_requirements.md b/doc/spec/system_requirements.md index 35974a246..b2dc50819 100644 --- a/doc/spec/system_requirements.md +++ b/doc/spec/system_requirements.md @@ -264,6 +264,39 @@ Needs: req ## Functional Requirements +### Product SPDX Software Bill Of Materials +`req~build.spdx-sbom~1` + +The Maven build creates one SPDX 3 JSON software bill of materials (SBOM) named `openfasttrace-.spdx3.json`. It lists dependencies at Maven module granularity, includes compile, runtime, and provided scopes and retains available license metadata. GitHub releases include the SBOM as an asset. + +Needs: scn, dsn + +#### Generate Product SPDX SBOM +`scn~build.spdx-sbom-generation~1` + +**Given** a Maven build of an OpenFastTrace release version, +**when** it builds the product module, +**then** it creates a `openfasttrace-.spdx3.json` SPDX 3 SBOM for the product, including compile, runtime, and provided dependencies at module granularity and the available dependency license information. + +Covers: + +* [req~build.spdx-sbom~1](#product-spdx-software-bill-of-materials) + +Needs: dsn + +#### Publish Product SPDX SBOM +`scn~build.spdx-sbom-release-asset~1` + +**Given** a successful OpenFastTrace release build with its product SBOM, +**when** the GitHub release is created, +**then** the release includes the generated `openfasttrace-.spdx3.json` as an asset alongside the product JAR and its checksum. + +Covers: + +* [req~build.spdx-sbom~1](#product-spdx-software-bill-of-materials) + +Needs: dsn + ### Anatomy of Specification Items #### Specification Item diff --git a/oft-self-trace.sh b/oft-self-trace.sh index a35633efb..90230eb60 100755 --- a/oft-self-trace.sh +++ b/oft-self-trace.sh @@ -30,6 +30,8 @@ if $oft_script trace \ "$base_dir/reporter/html/src" \ "$base_dir/reporter/aspec/src" \ "$base_dir/product/src/test/java" \ + "$base_dir/product/pom.xml" \ + "$base_dir/.github/workflows/github_release.sh" \ "$base_dir/api/src" \ "$base_dir/exporter/specobject/src" \ "$base_dir/exporter/common/src" \ diff --git a/product/pom.xml b/product/pom.xml index 23d7f68fc..b04a36479 100644 --- a/product/pom.xml +++ b/product/pom.xml @@ -80,6 +80,29 @@ openfasttrace-${revision} + + + org.spdx + spdx-maven-plugin + 1.0.4 + + + create-product-spdx-sbom + package + + aggregateSPDX + + + ${project.build.directory}/${project.build.finalName}.spdx3.json + JSON-LD + build + true + true + true + + + + org.apache.maven.plugins maven-shade-plugin diff --git a/product/src/test/java/org/itsallcode/openfasttrace/ITestSelfTrace.java b/product/src/test/java/org/itsallcode/openfasttrace/ITestSelfTrace.java index bc29c24b8..58695b0fa 100644 --- a/product/src/test/java/org/itsallcode/openfasttrace/ITestSelfTrace.java +++ b/product/src/test/java/org/itsallcode/openfasttrace/ITestSelfTrace.java @@ -69,6 +69,8 @@ private ImportSettings buildOftSettings() final Path baseDir = getProjectBaseDir(); return ImportSettings.builder() // .addInputs(baseDir.resolve("doc/spec/")) // + .addInputs(baseDir.resolve("product/pom.xml")) // + .addInputs(baseDir.resolve(".github/workflows/github_release.sh")) // .addInputs(findInputDirectories(baseDir)) // .build(); } diff --git a/product/src/test/java/org/itsallcode/openfasttrace/SpdxSbomIT.java b/product/src/test/java/org/itsallcode/openfasttrace/SpdxSbomIT.java new file mode 100644 index 000000000..df1e5679a --- /dev/null +++ b/product/src/test/java/org/itsallcode/openfasttrace/SpdxSbomIT.java @@ -0,0 +1,51 @@ +package org.itsallcode.openfasttrace; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; +import static org.junit.jupiter.api.Assertions.assertAll; + +import java.io.IOException; +import java.nio.file.*; +import java.util.stream.Stream; + +import com.exasol.mavenprojectversiongetter.MavenProjectVersionGetter; +import org.junit.jupiter.api.Test; + +class SpdxSbomIT +{ + private static final Path PROJECT_ROOT = Path.of("..").toAbsolutePath(); + private static final String SPDX3_CONTEXT = "https://spdx.org/rdf/3.0.1/spdx-context.jsonld"; + private static final String VERSION = MavenProjectVersionGetter + .getProjectRevision(PROJECT_ROOT.resolve("parent/pom.xml")); + + @Test + // [itest->dsn~build.spdx-sbom-generation~1] + void testBuildCreatesSpdx3SbomWithDependencyAndLicenseData() throws IOException + { + final Path sbomFile = Path.of("target", "openfasttrace-" + VERSION + ".spdx3.json"); + assertThat(Files.exists(sbomFile), is(true)); + + try (final Stream files = Files.list(sbomFile.getParent())) + { + assertThat(files.filter(path -> path.getFileName().toString().matches("openfasttrace-.*\\.spdx3\\.json")) + .count(), is(1L)); + } + + final String sbom = Files.readString(sbomFile); + + assertAll( + () -> assertThat(sbom, containsString("\"@context\" : \"" + SPDX3_CONTEXT + "\"")), + () -> assertThat(sbom, containsString("\"scope\" : \"runtime\"")), + () -> assertThat(sbom, containsString("openfasttrace-api")), + () -> assertThat(sbom, containsString("http://spdx.org/licenses/"))); + } + + @Test + // [itest->dsn~build.spdx-sbom-release-asset~1] + void testReleaseScriptIncludesSpdxSbomAsset() throws IOException + { + final String releaseScript = Files.readString(PROJECT_ROOT.resolve(".github/workflows/github_release.sh")); + + assertThat(releaseScript, containsString("\"$sbom_path\"")); + } +} From 8b59cbef20db8cf9279a7a0c52bbd2491e98296e Mon Sep 17 00:00:00 2001 From: redcatbear Date: Fri, 14 Aug 2026 09:08:42 +0200 Subject: [PATCH 2/3] #527: SPDX SBOM --- doc/changesets/527-spdx-sbom.md | 16 +-- doc/spec/design.md | 10 +- doc/spec/system_requirements.md | 12 +- parent/pom.xml | 2 +- product/pom.xml | 117 +++++++++++++++++- .../itsallcode/openfasttrace/SpdxSbomIT.java | 10 +- 6 files changed, 140 insertions(+), 27 deletions(-) diff --git a/doc/changesets/527-spdx-sbom.md b/doc/changesets/527-spdx-sbom.md index 04b6eef1e..2fe961761 100644 --- a/doc/changesets/527-spdx-sbom.md +++ b/doc/changesets/527-spdx-sbom.md @@ -5,7 +5,8 @@ Produce one SPDX 3 JSON software bill of materials (SBOM) for the OpenFastTrace product during the Maven build and attach it to every GitHub release. The SBOM must represent the product at module granularity, include compile, runtime, and -provided dependencies, and retain available dependency-license information. +provided dependencies, exclude test dependencies, and retain available +dependency-license information. ## Scope @@ -16,6 +17,7 @@ In scope: * Generate `openfasttrace-.spdx3.json` as part of the regular Maven build. * Include compile, runtime, and provided dependencies. +* Exclude test-scope dependencies from the released-product SBOM. * Ensure the release workflow uploads the SBOM with the product JAR and its checksum. @@ -23,8 +25,6 @@ Out of scope: * File-level or snippet-level SPDX resolution. * SBOMs for individual OpenFastTrace modules. -* Adding or correcting dependency license metadata not exposed by the resolved - Maven dependency metadata. * Changing OpenFastTrace runtime behavior or its public CLI/API. ## Design References @@ -36,13 +36,13 @@ Out of scope: * [Product module](../../product/pom.xml) * [Release workflow](../../.github/workflows/release.yml) * [GitHub release script](../../.github/workflows/github_release.sh) -* [SPDX Maven Plugin documentation](https://spdx.github.io/spdx-maven-plugin/aggregateSPDX-mojo.html) +* [SPDX Maven Plugin documentation](https://spdx.github.io/spdx-maven-plugin/createSPDX-mojo.html) ## Strategy Configure the selected SPDX Maven Plugin in `product/pom.xml`, rather than in the shared parent, so the reactor creates exactly one SBOM for the distributable -product. Bind `aggregateSPDX` to the normal Maven lifecycle, use SPDX 3 JSON-LD +product. Bind `createSPDX` to the normal Maven lifecycle, use SPDX 3 JSON-LD output and the required product filename, and explicitly configure dependency scope inclusion to make the acceptance criteria independent of plugin defaults. @@ -62,7 +62,7 @@ required dependency-scope controls. Its documented default lifecycle binding is ### Requirements And Design -- [x] Add `req~build.spdx-sbom~1` to `doc/spec/system_requirements.md`, covering +- [x] Add `req~build.spdx-sbom~2` to `doc/spec/system_requirements.md`, covering the product SBOM content, module granularity, required dependency scopes, SPDX 3 JSON filename, and release availability; add scenarios for a successful product build and a GitHub release asset. @@ -80,9 +80,9 @@ required dependency-scope controls. Its documented default lifecycle binding is ### Implementation - [x] Add the approved SPDX Maven Plugin version and an execution to - `product/pom.xml`; configure `aggregateSPDX`, SPDX 3 JSON-LD output, + `product/pom.xml`; configure `createSPDX`, SPDX 3 JSON-LD output, `openfasttrace-${revision}.spdx3.json`, module granularity, and - compile/runtime/provided inclusion. + compile/runtime/provided inclusion and test-scope exclusion. - [x] Confirm the plugin generates only the product SBOM, contains the resolved direct and transitive dependencies at module level, and preserves all available declared license data; add narrowly scoped license overrides diff --git a/doc/spec/design.md b/doc/spec/design.md index 59cb2fadd..ad4b4c618 100644 --- a/doc/spec/design.md +++ b/doc/spec/design.md @@ -849,14 +849,14 @@ Needs: impl, utest ## Build ### Product SPDX SBOM Generation -`dsn~build.spdx-sbom-generation~1` +`dsn~build.spdx-sbom-generation~2` -The `product` module configures `org.spdx:spdx-maven-plugin` with the `aggregateSPDX` goal. The execution runs during the Maven lifecycle and creates `product/target/openfasttrace-${revision}.spdx3.json`. It uses SPDX 3 JSON-LD, aggregates the product's Maven modules, and includes compile, runtime, and provided dependency scopes. +The `product` module configures `org.spdx:spdx-maven-plugin` with the `createSPDX` goal. The execution runs during the Maven lifecycle and creates `product/target/openfasttrace-${revision}.spdx3.json`. It uses SPDX 3 JSON-LD, includes compile, runtime, and provided dependency scopes, and excludes test scope. License overwrites set the OpenFastTrace modules to `GPL-3.0-only`, because the plugin cannot resolve the inherited GPL URL unambiguously. Covers: -* `req~build.spdx-sbom~1` -* `scn~build.spdx-sbom-generation~1` +* `req~build.spdx-sbom~2` +* `scn~build.spdx-sbom-generation~2` Needs: impl, itest @@ -867,7 +867,7 @@ The GitHub release script passes `product/target/openfasttrace-${revision}.spdx3 Covers: -* `req~build.spdx-sbom~1` +* `req~build.spdx-sbom~2` * `scn~build.spdx-sbom-release-asset~1` Needs: impl, itest diff --git a/doc/spec/system_requirements.md b/doc/spec/system_requirements.md index b2dc50819..66894181e 100644 --- a/doc/spec/system_requirements.md +++ b/doc/spec/system_requirements.md @@ -265,22 +265,22 @@ Needs: req ## Functional Requirements ### Product SPDX Software Bill Of Materials -`req~build.spdx-sbom~1` +`req~build.spdx-sbom~2` -The Maven build creates one SPDX 3 JSON software bill of materials (SBOM) named `openfasttrace-.spdx3.json`. It lists dependencies at Maven module granularity, includes compile, runtime, and provided scopes and retains available license metadata. GitHub releases include the SBOM as an asset. +The Maven build creates one SPDX 3 JSON software bill of materials (SBOM) named `openfasttrace-.spdx3.json`. It lists dependencies at Maven module granularity, includes compile, runtime, and provided scopes, excludes test-scope dependencies, and retains available license metadata. GitHub releases include the SBOM as an asset. Needs: scn, dsn #### Generate Product SPDX SBOM -`scn~build.spdx-sbom-generation~1` +`scn~build.spdx-sbom-generation~2` **Given** a Maven build of an OpenFastTrace release version, **when** it builds the product module, -**then** it creates a `openfasttrace-.spdx3.json` SPDX 3 SBOM for the product, including compile, runtime, and provided dependencies at module granularity and the available dependency license information. +**then** it creates a `openfasttrace-.spdx3.json` SPDX 3 SBOM for the product, including compile, runtime, and provided dependencies at module granularity, excluding test-scope dependencies, and retaining available dependency license information. Covers: -* [req~build.spdx-sbom~1](#product-spdx-software-bill-of-materials) +* [req~build.spdx-sbom~2](#product-spdx-software-bill-of-materials) Needs: dsn @@ -293,7 +293,7 @@ Needs: dsn Covers: -* [req~build.spdx-sbom~1](#product-spdx-software-bill-of-materials) +* [req~build.spdx-sbom~2](#product-spdx-software-bill-of-materials) Needs: dsn diff --git a/parent/pom.xml b/parent/pom.xml index bb1d55ce9..514beece3 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -25,7 +25,7 @@ GNU General Public License v3.0 - https://www.gnu.org/licenses/gpl-3.0.html + https://spdx.org/licenses/GPL-3.0-or-later.html repo diff --git a/product/pom.xml b/product/pom.xml index b04a36479..895f522fe 100644 --- a/product/pom.xml +++ b/product/pom.xml @@ -80,7 +80,7 @@ openfasttrace-${revision} - + org.spdx spdx-maven-plugin @@ -90,15 +90,128 @@ create-product-spdx-sbom package - aggregateSPDX + createSPDX ${project.build.directory}/${project.build.finalName}.spdx3.json JSON-LD build + GPL-3.0-only + GPL-3.0-only true true true + false + + + both + org.itsallcode.openfasttrace + openfasttrace + GPL-3.0-only + + + both + org.itsallcode.openfasttrace + openfasttrace-api + GPL-3.0-only + + + both + org.itsallcode.openfasttrace + openfasttrace-core + GPL-3.0-only + + + both + org.itsallcode.openfasttrace + openfasttrace-exporter-common + GPL-3.0-only + + + both + org.itsallcode.openfasttrace + openfasttrace-exporter-specobject + GPL-3.0-only + + + both + org.itsallcode.openfasttrace + openfasttrace-importer-gherkin + GPL-3.0-only + + + both + org.itsallcode.openfasttrace + openfasttrace-importer-lightweightmarkup + GPL-3.0-only + + + both + org.itsallcode.openfasttrace + openfasttrace-importer-markdown + GPL-3.0-only + + + both + org.itsallcode.openfasttrace + openfasttrace-importer-restructuredtext + GPL-3.0-only + + + both + org.itsallcode.openfasttrace + openfasttrace-importer-specobject + GPL-3.0-only + + + both + org.itsallcode.openfasttrace + openfasttrace-importer-tag + GPL-3.0-only + + + both + org.itsallcode.openfasttrace + openfasttrace-importer-tag-importer-common + GPL-3.0-only + + + both + org.itsallcode.openfasttrace + openfasttrace-importer-xmlparser + GPL-3.0-only + + + both + org.itsallcode.openfasttrace + openfasttrace-importer-zip + GPL-3.0-only + + + both + org.itsallcode.openfasttrace + openfasttrace-reporter-aspec + GPL-3.0-only + + + both + org.itsallcode.openfasttrace + openfasttrace-reporter-html + GPL-3.0-only + + + both + org.itsallcode.openfasttrace + openfasttrace-reporter-plaintext + GPL-3.0-only + + + both + org.itsallcode.openfasttrace + openfasttrace-testutil + GPL-3.0-only + + diff --git a/product/src/test/java/org/itsallcode/openfasttrace/SpdxSbomIT.java b/product/src/test/java/org/itsallcode/openfasttrace/SpdxSbomIT.java index df1e5679a..579a62e67 100644 --- a/product/src/test/java/org/itsallcode/openfasttrace/SpdxSbomIT.java +++ b/product/src/test/java/org/itsallcode/openfasttrace/SpdxSbomIT.java @@ -15,28 +15,29 @@ class SpdxSbomIT { private static final Path PROJECT_ROOT = Path.of("..").toAbsolutePath(); private static final String SPDX3_CONTEXT = "https://spdx.org/rdf/3.0.1/spdx-context.jsonld"; + private static final String GPL_3_ONLY = "http://spdx.org/licenses/GPL-3.0-only"; private static final String VERSION = MavenProjectVersionGetter .getProjectRevision(PROJECT_ROOT.resolve("parent/pom.xml")); @Test - // [itest->dsn~build.spdx-sbom-generation~1] + // [itest->dsn~build.spdx-sbom-generation~2] void testBuildCreatesSpdx3SbomWithDependencyAndLicenseData() throws IOException { final Path sbomFile = Path.of("target", "openfasttrace-" + VERSION + ".spdx3.json"); assertThat(Files.exists(sbomFile), is(true)); - try (final Stream files = Files.list(sbomFile.getParent())) { assertThat(files.filter(path -> path.getFileName().toString().matches("openfasttrace-.*\\.spdx3\\.json")) .count(), is(1L)); } - final String sbom = Files.readString(sbomFile); - assertAll( () -> assertThat(sbom, containsString("\"@context\" : \"" + SPDX3_CONTEXT + "\"")), () -> assertThat(sbom, containsString("\"scope\" : \"runtime\"")), + () -> assertThat(sbom, not(containsString("\"scope\" : \"test\""))), () -> assertThat(sbom, containsString("openfasttrace-api")), + () -> assertThat(sbom, not(containsString("Byte Buddy"))), + () -> assertThat(sbom, containsString(GPL_3_ONLY)), () -> assertThat(sbom, containsString("http://spdx.org/licenses/"))); } @@ -45,7 +46,6 @@ void testBuildCreatesSpdx3SbomWithDependencyAndLicenseData() throws IOException void testReleaseScriptIncludesSpdxSbomAsset() throws IOException { final String releaseScript = Files.readString(PROJECT_ROOT.resolve(".github/workflows/github_release.sh")); - assertThat(releaseScript, containsString("\"$sbom_path\"")); } } From cc29d83a3cf97eff0770fa945f334a06ae1e0257 Mon Sep 17 00:00:00 2001 From: redcatbear Date: Fri, 14 Aug 2026 09:13:00 +0200 Subject: [PATCH 3/3] #527: SPDX SBOM --- doc/changes/changes.md | 1 + doc/changes/changes_4.10.0.md | 11 +++++++++++ 2 files changed, 12 insertions(+) create mode 100644 doc/changes/changes_4.10.0.md diff --git a/doc/changes/changes.md b/doc/changes/changes.md index a549f6b2b..46a751710 100644 --- a/doc/changes/changes.md +++ b/doc/changes/changes.md @@ -1,5 +1,6 @@ # Changes +* [4.10.0](changes_4.10.0.md) * [4.9.0](changes_4.9.0.md) * [4.8.0](changes_4.8.0.md) * [4.7.0](changes_4.7.0.md) diff --git a/doc/changes/changes_4.10.0.md b/doc/changes/changes_4.10.0.md new file mode 100644 index 000000000..2c7ebf5ae --- /dev/null +++ b/doc/changes/changes_4.10.0.md @@ -0,0 +1,11 @@ +# OpenFastTrace 4.10.0, released 2026-08-14 + +Code name: SPDX 3 SBOM + +## Summary + +OpenFastTrace release assets now include an SPDX 3 software bill of materials (SBOM) for the product. It lists the product's compile-time, runtime, and provided dependencies, including transitive dependencies. + +## New Features + +* #527: Add an SPDX 3 SBOM to the product build and GitHub release assets.