From 1a3565e29f0d8b0abb9b3c719bd3f7c51558c460 Mon Sep 17 00:00:00 2001 From: Frank Scholter Peres Date: Thu, 6 Aug 2026 15:26:18 +0000 Subject: [PATCH 01/16] add sbom --- BUILD | 65 ++++++++++++++++++++++ MODULE.bazel | 31 +++++++++++ MODULE.bazel.lock | 39 +++++++++++++ README.md | 65 ++++++++++++++++++++++ feature_integration_tests/test_cases/BUILD | 2 + scripts/tooling/BUILD | 2 + 6 files changed, 204 insertions(+) diff --git a/BUILD b/BUILD index 24fe9e51ef7..ddb31768a74 100644 --- a/BUILD +++ b/BUILD @@ -13,6 +13,7 @@ load("@score_docs_as_code//:docs.bzl", "docs") load("@score_tooling//:defs.bzl", "setup_starpls", "use_format_targets") +load("@score_sbom//:defs.bzl", "sbom") # Docs-as-code docs( @@ -45,6 +46,70 @@ use_format_targets() exports_files([ "MODULE.bazel", + "MODULE.bazel.lock", "pyproject.toml", "known_good.json", ]) + +sbom( + name = "sbom", + targets = [ + "//feature_integration_tests/test_scenarios/cpp:cpp_test_scenarios", + "//feature_integration_tests/test_scenarios/rust:rust_test_scenarios", + "//showcases/cli:cli", + "//showcases/orchestration_persistency:orch_per_example", + "@score_communication//score/mw/com/example/com-api-example:com-api-example", + "@score_kyron//examples:main_macro", + "@score_kyron//examples:safety_task", + "@score_kyron//examples:select", + "@score_logging//score/test/component/dlt_generator_app:dlt_generator", + "@score_logging//score/test/component/logging_app:logging_app", + "@score_time//examples/time/high_res_steady_time", + "@score_time//examples/time/steady_time", + "@score_time//examples/time/system_time", + "@score_time//examples/time/vehicle_time", + ], + auto_cdxgen = True, + auto_crates_cache = True, + component_name = "score_reference_integration", + generation_context = "build", + module_lockfiles = [":MODULE.bazel.lock"], + output_formats = ["spdx", "cyclonedx"], +) + +# Product SBOM alias with an explicit lifecycle-oriented name. +alias( + name = "product_sbom", + actual = ":sbom", + visibility = ["//visibility:public"], +) + +# Qualification inventory for Python-based build and test tools. This is kept +# separate from the product SBOM because build-time dependencies are not +# product/runtime dependencies. +sbom( + name = "build_tools_sbom", + targets = [ + "//:docs_combo_experimental", + "//feature_integration_tests/test_scenarios/cpp:cpp_test_scenarios", + "//scripts/tooling:checkout_repos", + "//scripts/tooling:recategorize_guidelines", + "//scripts/tooling:tooling", + "@score_docs_as_code//src:plantuml", + ], + java_files = ["@score_docs_as_code//src:plantuml.jar"], + testonly = True, + auto_cdxgen = False, + auto_crates_cache = False, + component_name = "score_reference_integration_build_tools", + generation_context = "build", + # Pip repositories are represented authoritatively by python_lockfiles; + # exclude their generated Bazel aliases to avoid duplicate components. + exclude_patterns = ["rules_python++pip+"], + output_formats = ["spdx"], + python_lockfiles = [ + "//feature_integration_tests/test_cases:requirements.txt.lock", + "//scripts/tooling:requirements.txt", + "@score_docs_as_code//src:requirements_lock", + ], +) diff --git a/MODULE.bazel b/MODULE.bazel index df2e3a8995e..018b896dc18 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -14,6 +14,37 @@ module( name = "score_ref_int", ) +# SBOM generation is consumed from the local git checkout until score_sbom is +# available in the Bazel registry. +bazel_dep(name = "score_sbom", version = "0.0.1") +git_override( + module_name = "score_sbom", + commit = "9634f855ad9e631307241ab16091a24478ead19f", + remote = "file:///workspaces/sbom-tool", +) + +sbom_ext = use_extension("@score_sbom//:extensions.bzl", "sbom_metadata") +sbom_ext.track_module(name = "score_sbom") +sbom_ext.track_module(name = "score_baselibs") +sbom_ext.track_module(name = "score_communication") +sbom_ext.track_module(name = "score_persistency") +sbom_ext.track_module(name = "score_orchestrator") +sbom_ext.track_module(name = "score_kyron") +sbom_ext.track_module(name = "score_lifecycle_health") +sbom_ext.track_module(name = "score_logging") +sbom_ext.track_module(name = "score_time") +sbom_ext.track_module(name = "score_crates") +sbom_ext.track_module(name = "score_itf") +sbom_ext.track_module(name = "score_tooling") +sbom_ext.track_module(name = "score_platform") +sbom_ext.track_module(name = "score_bazel_platforms") +sbom_ext.track_module(name = "score_test_scenarios") +sbom_ext.track_module(name = "score_docs_as_code") +sbom_ext.track_module(name = "score_process") +sbom_ext.track_module(name = "trlc") +sbom_ext.track_module(name = "lobster") +use_repo(sbom_ext, "sbom_metadata") + # Include common modules include("//bazel_common:score_basic_bazel.MODULE.bazel") diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index c9eb12e0be6..21a6785eb68 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -9892,6 +9892,45 @@ ] } }, + "@@score_sbom+//:extensions.bzl%sbom_metadata": { + "general": { + "bzlTransitiveDigest": "6MZmMjhsKcOnMq12Rbna7aYgF4ZAbEtH3kjZYu4M5nI=", + "usagesDigest": "9i7n8SjRs3isUDHbGTLmCZHFqJDV0njGZIidi0RDBkc=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "sbom_metadata": { + "repoRuleId": "@@score_sbom+//:extensions.bzl%_sbom_metadata_repo", + "attributes": { + "metadata_content": "{\"crates\":{},\"git_repositories\":{},\"http_archives\":{},\"licenses\":{},\"modules\":{}}", + "tracked_modules": [ + "score_sbom", + "score_baselibs", + "score_communication", + "score_persistency", + "score_orchestrator", + "score_kyron", + "score_lifecycle_health", + "score_logging", + "score_time", + "score_crates", + "score_itf", + "score_tooling", + "score_platform", + "score_bazel_platforms", + "score_test_scenarios", + "score_docs_as_code", + "score_process", + "trlc", + "lobster" + ] + } + } + }, + "recordedRepoMappingEntries": [] + } + }, "@@score_toolchains_rust+//extensions:ferrocene_toolchain_ext.bzl%ferrocene_toolchain_ext": { "general": { "bzlTransitiveDigest": "XEgifqjEEdSGw80RccoJ/aUy9smsRXQJ9jO4RDOf2vk=", diff --git a/README.md b/README.md index 16c58de3908..b582229f76d 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,71 @@ To generate a full documentation of all integrated modules, run: bazel run //:docs_combo_experimental ``` +### Software Bill of Materials + +The root `//:sbom` target generates SPDX 2.3 and CycloneDX 1.6 documents for +the integrated showcase and feature-test binaries. It consumes `sbom-tool` +from the local git checkout at `../sbom-tool` in this workspace until the +module is available in the Bazel registry. + +Install Node.js/npm and `@cyclonedx/cdxgen` before building the C++ dependency +metadata, then run: + +```bash +npm install -g @cyclonedx/cdxgen +bazel build //:sbom +``` + +The generated documents are written below `bazel-bin/` as `sbom.spdx.json` and +`sbom.cdx.json`. Rust crate metadata is collected automatically from the +workspace lockfile and the configured `score_crates` module. + +### Selecting an SBOM mode + +Choose the mode based on what is being qualified: + +- **Product mode** is for the software delivered by the integration. It follows + the configured showcase and feature-test binaries and includes their runtime + dependencies. Use `//:product_sbom` (an alias of `//:sbom`) when you need both + SPDX and CycloneDX output for the product scope. +- **Build-tool qualification mode** is for tools used to build, test, or + generate documentation. It is separate from the product scope because these + tools are not shipped as product runtime dependencies. Use + `//:build_tools_sbom` when collecting ISO 26262 qualification evidence for + the development toolchain. + +Build-tool mode includes the Python lockfiles used by the workspace tooling and +docs-as-code, the Sphinx documentation toolchain, the PlantUML integration, and +the PlantUML JAR itself with a SHA-256 checksum. It emits SPDX only and does +not run cdxgen or the Rust crate cache collector. + +Build the selected mode as follows: + +```bash +# Product/runtime dependencies +bazel build //:product_sbom +# Outputs: bazel-bin/product_sbom.spdx.json and bazel-bin/product_sbom.cdx.json + +# Build-tool qualification inventory (SPDX JSON) +bazel build //:build_tools_sbom +# Output: bazel-bin/build_tools_sbom.spdx.json +``` + +While testing the unpublished Python collector branch of `sbom-tool`, resolve +it with the module override below. Apply the override to whichever mode you are +building: + +```bash +bazel build //:product_sbom \ + --override_module=score_sbom=/workspaces/sbom-tool + +bazel build //:build_tools_sbom \ + --override_module=score_sbom=/workspaces/sbom-tool +``` + +Once the collector branch is merged, replace this command-line override with +the merged commit in the root `MODULE.bazel` git override. + ## Operating system integrations > [!NOTE] diff --git a/feature_integration_tests/test_cases/BUILD b/feature_integration_tests/test_cases/BUILD index dcf8ab0542b..18d0b24212f 100644 --- a/feature_integration_tests/test_cases/BUILD +++ b/feature_integration_tests/test_cases/BUILD @@ -14,6 +14,8 @@ load("@pip_score_venv_test//:requirements.bzl", "all_requirements") load("@rules_python//python:pip.bzl", "compile_pip_requirements") load("@score_tooling//python_basics:defs.bzl", "score_py_pytest") +exports_files(["requirements.txt.lock"]) + # In order to update the requirements, change the `requirements.txt` file and run: # `bazel run //feature_integration_tests/test_cases:requirements.update`. # This will update the `requirements.txt.lock` file. diff --git a/scripts/tooling/BUILD b/scripts/tooling/BUILD index c2088414897..8f843625a0a 100644 --- a/scripts/tooling/BUILD +++ b/scripts/tooling/BUILD @@ -15,6 +15,8 @@ load("@rules_python//python:defs.bzl", "py_binary", "py_library") load("@rules_python//python:pip.bzl", "compile_pip_requirements") load("@score_tooling//python_basics:defs.bzl", "score_py_pytest") +exports_files(["requirements.txt"]) + # In order to update the requirements, change the `requirements.in` file and run # `bazel run //scripts/tooling:requirements.update` # This will update the `requirements.txt` file From ff7103334f3673ee38d19866220bd47eb1223ff6 Mon Sep 17 00:00:00 2001 From: Frank Scholter Peres Date: Fri, 7 Aug 2026 09:56:48 +0000 Subject: [PATCH 02/16] updated to new hash --- MODULE.bazel | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 018b896dc18..2bf0a2f5c88 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -14,13 +14,13 @@ module( name = "score_ref_int", ) -# SBOM generation is consumed from the local git checkout until score_sbom is -# available in the Bazel registry. +# SBOM generation is consumed from a pinned score_sbom commit until the module +# is available in the Bazel registry. bazel_dep(name = "score_sbom", version = "0.0.1") git_override( module_name = "score_sbom", - commit = "9634f855ad9e631307241ab16091a24478ead19f", - remote = "file:///workspaces/sbom-tool", + commit = "2249efd97d4a2681dfa18d5b1d6cebbe7da1ce0f", + remote = "https://github.com/eclipse-score/sbom-tool.git", ) sbom_ext = use_extension("@score_sbom//:extensions.bzl", "sbom_metadata") From 663b1caf470cbd79e265f65c8bb2764224401df5 Mon Sep 17 00:00:00 2001 From: Frank Scholter Peres Date: Mon, 10 Aug 2026 12:10:41 +0000 Subject: [PATCH 03/16] add sbom generation --- MODULE.bazel | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 2bf0a2f5c88..ee9be3c3b73 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -14,14 +14,9 @@ module( name = "score_ref_int", ) -# SBOM generation is consumed from a pinned score_sbom commit until the module -# is available in the Bazel registry. -bazel_dep(name = "score_sbom", version = "0.0.1") -git_override( - module_name = "score_sbom", - commit = "2249efd97d4a2681dfa18d5b1d6cebbe7da1ce0f", - remote = "https://github.com/eclipse-score/sbom-tool.git", -) +# SBOM generation pinned to sbom-tool v0.0.2 until registry module naming is aligned. +bazel_dep(name = "score_sbom", version = "0.0.2") + sbom_ext = use_extension("@score_sbom//:extensions.bzl", "sbom_metadata") sbom_ext.track_module(name = "score_sbom") @@ -96,6 +91,7 @@ download_archive( bazel_dep(name = "aspect_rules_lint", version = "2.3.0") bazel_dep(name = "buildifier_prebuilt", version = "8.5.1") bazel_dep(name = "score_rust_policies", version = "0.0.5") +bazel_dep(name = "score_sbom", version = "0.0.2") # TRLC dependency for requirements traceability bazel_dep(name = "trlc") From cb7c9604cd281509a5b0d4ff4253783a5f3904c2 Mon Sep 17 00:00:00 2001 From: Frank Scholter Peres Date: Mon, 10 Aug 2026 14:18:02 +0000 Subject: [PATCH 04/16] fix multiple dependencies --- MODULE.bazel | 48 +++++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index ee9be3c3b73..22b42488219 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -14,31 +14,6 @@ module( name = "score_ref_int", ) -# SBOM generation pinned to sbom-tool v0.0.2 until registry module naming is aligned. -bazel_dep(name = "score_sbom", version = "0.0.2") - - -sbom_ext = use_extension("@score_sbom//:extensions.bzl", "sbom_metadata") -sbom_ext.track_module(name = "score_sbom") -sbom_ext.track_module(name = "score_baselibs") -sbom_ext.track_module(name = "score_communication") -sbom_ext.track_module(name = "score_persistency") -sbom_ext.track_module(name = "score_orchestrator") -sbom_ext.track_module(name = "score_kyron") -sbom_ext.track_module(name = "score_lifecycle_health") -sbom_ext.track_module(name = "score_logging") -sbom_ext.track_module(name = "score_time") -sbom_ext.track_module(name = "score_crates") -sbom_ext.track_module(name = "score_itf") -sbom_ext.track_module(name = "score_tooling") -sbom_ext.track_module(name = "score_platform") -sbom_ext.track_module(name = "score_bazel_platforms") -sbom_ext.track_module(name = "score_test_scenarios") -sbom_ext.track_module(name = "score_docs_as_code") -sbom_ext.track_module(name = "score_process") -sbom_ext.track_module(name = "trlc") -sbom_ext.track_module(name = "lobster") -use_repo(sbom_ext, "sbom_metadata") # Include common modules include("//bazel_common:score_basic_bazel.MODULE.bazel") @@ -108,3 +83,26 @@ git_override( commit = "2792e2daee2cf524fdc7b1545fd3537791ebc36c", remote = "https://github.com/bmw-software-engineering/lobster.git", ) + + +sbom_ext = use_extension("@score_sbom//:extensions.bzl", "sbom_metadata") +sbom_ext.track_module(name = "score_sbom") +sbom_ext.track_module(name = "score_baselibs") +sbom_ext.track_module(name = "score_communication") +sbom_ext.track_module(name = "score_persistency") +sbom_ext.track_module(name = "score_orchestrator") +sbom_ext.track_module(name = "score_kyron") +sbom_ext.track_module(name = "score_lifecycle_health") +sbom_ext.track_module(name = "score_logging") +sbom_ext.track_module(name = "score_time") +sbom_ext.track_module(name = "score_crates") +sbom_ext.track_module(name = "score_itf") +sbom_ext.track_module(name = "score_tooling") +sbom_ext.track_module(name = "score_platform") +sbom_ext.track_module(name = "score_bazel_platforms") +sbom_ext.track_module(name = "score_test_scenarios") +sbom_ext.track_module(name = "score_docs_as_code") +sbom_ext.track_module(name = "score_process") +sbom_ext.track_module(name = "trlc") +sbom_ext.track_module(name = "lobster") +use_repo(sbom_ext, "sbom_metadata") From b67c1feaa4b903d014d0e4ff8e906be0fbf517d5 Mon Sep 17 00:00:00 2001 From: Frank Scholter Peres Date: Tue, 11 Aug 2026 07:26:56 +0000 Subject: [PATCH 05/16] changed dependency to correct name --- MODULE.bazel | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MODULE.bazel b/MODULE.bazel index 22b42488219..0bf61c36aa5 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -85,8 +85,10 @@ git_override( ) +bazel_dep(name = "score_sbom_tool", version = "0.0.2") + sbom_ext = use_extension("@score_sbom//:extensions.bzl", "sbom_metadata") -sbom_ext.track_module(name = "score_sbom") +sbom_ext.track_module(name = "score_sbom_tool") sbom_ext.track_module(name = "score_baselibs") sbom_ext.track_module(name = "score_communication") sbom_ext.track_module(name = "score_persistency") From cfdc1451802a7098e1f20c5aeea3bbe02cdc9e32 Mon Sep 17 00:00:00 2001 From: Frank Scholter Peres Date: Tue, 11 Aug 2026 07:33:14 +0000 Subject: [PATCH 06/16] fix naming issue --- MODULE.bazel | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 0bf61c36aa5..c7fa40e1b1f 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -66,7 +66,6 @@ download_archive( bazel_dep(name = "aspect_rules_lint", version = "2.3.0") bazel_dep(name = "buildifier_prebuilt", version = "8.5.1") bazel_dep(name = "score_rust_policies", version = "0.0.5") -bazel_dep(name = "score_sbom", version = "0.0.2") # TRLC dependency for requirements traceability bazel_dep(name = "trlc") @@ -85,7 +84,7 @@ git_override( ) -bazel_dep(name = "score_sbom_tool", version = "0.0.2") +bazel_dep(name = "score_sbom_tool", version = "0.0.2", repo_name = "score_sbom") sbom_ext = use_extension("@score_sbom//:extensions.bzl", "sbom_metadata") sbom_ext.track_module(name = "score_sbom_tool") From c62b79ee69be0987c3e1a927b0e70f26cbc81381 Mon Sep 17 00:00:00 2001 From: Frank Scholter Peres Date: Tue, 11 Aug 2026 07:50:53 +0000 Subject: [PATCH 07/16] fix dependency --- .gitignore | 3 +++ MODULE.bazel | 2 +- MODULE.bazel.lock | 6 ++++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index b719861b67c..678f4cddfac 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,6 @@ __pycache__/ /.gita-workspace.csv /build artifacts + +#Macos +.DS_Store diff --git a/MODULE.bazel b/MODULE.bazel index c7fa40e1b1f..9ae562d8cf5 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -84,7 +84,7 @@ git_override( ) -bazel_dep(name = "score_sbom_tool", version = "0.0.2", repo_name = "score_sbom") +bazel_dep(name = "score_sbom", version = "0.0.2") sbom_ext = use_extension("@score_sbom//:extensions.bzl", "sbom_metadata") sbom_ext.track_module(name = "score_sbom_tool") diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 21a6785eb68..6bc5b60a5aa 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -1025,6 +1025,8 @@ "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_rust_policies/0.0.3/MODULE.bazel": "9e8310a75c13ccebc49fb9cbf7acc6c1b75654292b2ca907fb5d513133dbf6f3", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_rust_policies/0.0.5/MODULE.bazel": "7de02547bdf121d3dedf5141b97f0fd9a545bd255ff5c7b699056b35816ffad9", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_rust_policies/0.0.5/source.json": "22c8bf0a5cbf7c7b06f774f3f66498e0bc14346a8b2208f7427a8fbb78a42547", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_sbom/0.0.2/MODULE.bazel": "eaddaa984143fc540c48d59988976db82a5ff40b6264df41ad097b520c213201", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_sbom/0.0.2/source.json": "757694093b76ab165663f67987abe7c84a049fb4a5489ee98eccaf5a3fd8da5c", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_toolchains_rust/0.8.0/MODULE.bazel": "ea57a9a4dcb8ad49f4556f824500eb559365f413ccbb39d70d0b363685aacec5", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_toolchains_rust/0.8.0/source.json": "394a615e03ad722bc27bd4a6f098c6ff2fe7120b69cdf3925d47e39d30ada8a4", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/stardoc/0.5.0/MODULE.bazel": "not found", @@ -9895,7 +9897,7 @@ "@@score_sbom+//:extensions.bzl%sbom_metadata": { "general": { "bzlTransitiveDigest": "6MZmMjhsKcOnMq12Rbna7aYgF4ZAbEtH3kjZYu4M5nI=", - "usagesDigest": "9i7n8SjRs3isUDHbGTLmCZHFqJDV0njGZIidi0RDBkc=", + "usagesDigest": "7w/yzAEyY/yCBCR/jIGaWQ/+5X1bjZNUq/AMKPiAUv8=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, @@ -9905,7 +9907,7 @@ "attributes": { "metadata_content": "{\"crates\":{},\"git_repositories\":{},\"http_archives\":{},\"licenses\":{},\"modules\":{}}", "tracked_modules": [ - "score_sbom", + "score_sbom_tool", "score_baselibs", "score_communication", "score_persistency", From f1980e54f5ab988d1f0ba21704011bc0f7d2b9a2 Mon Sep 17 00:00:00 2001 From: Frank Scholter Peres Date: Tue, 11 Aug 2026 07:54:19 +0000 Subject: [PATCH 08/16] format fix --- BUILD | 37 ++++++++++++++++++++----------------- MODULE.bazel | 2 -- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/BUILD b/BUILD index ddb31768a74..cc05dcc5d09 100644 --- a/BUILD +++ b/BUILD @@ -12,8 +12,8 @@ # ******************************************************************************* load("@score_docs_as_code//:docs.bzl", "docs") -load("@score_tooling//:defs.bzl", "setup_starpls", "use_format_targets") load("@score_sbom//:defs.bzl", "sbom") +load("@score_tooling//:defs.bzl", "setup_starpls", "use_format_targets") # Docs-as-code docs( @@ -53,6 +53,15 @@ exports_files([ sbom( name = "sbom", + auto_cdxgen = True, + auto_crates_cache = True, + component_name = "score_reference_integration", + generation_context = "build", + module_lockfiles = [":MODULE.bazel.lock"], + output_formats = [ + "spdx", + "cyclonedx", + ], targets = [ "//feature_integration_tests/test_scenarios/cpp:cpp_test_scenarios", "//feature_integration_tests/test_scenarios/rust:rust_test_scenarios", @@ -69,12 +78,6 @@ sbom( "@score_time//examples/time/system_time", "@score_time//examples/time/vehicle_time", ], - auto_cdxgen = True, - auto_crates_cache = True, - component_name = "score_reference_integration", - generation_context = "build", - module_lockfiles = [":MODULE.bazel.lock"], - output_formats = ["spdx", "cyclonedx"], ) # Product SBOM alias with an explicit lifecycle-oriented name. @@ -89,27 +92,27 @@ alias( # product/runtime dependencies. sbom( name = "build_tools_sbom", - targets = [ - "//:docs_combo_experimental", - "//feature_integration_tests/test_scenarios/cpp:cpp_test_scenarios", - "//scripts/tooling:checkout_repos", - "//scripts/tooling:recategorize_guidelines", - "//scripts/tooling:tooling", - "@score_docs_as_code//src:plantuml", - ], - java_files = ["@score_docs_as_code//src:plantuml.jar"], testonly = True, auto_cdxgen = False, auto_crates_cache = False, component_name = "score_reference_integration_build_tools", - generation_context = "build", # Pip repositories are represented authoritatively by python_lockfiles; # exclude their generated Bazel aliases to avoid duplicate components. exclude_patterns = ["rules_python++pip+"], + generation_context = "build", + java_files = ["@score_docs_as_code//src:plantuml.jar"], output_formats = ["spdx"], python_lockfiles = [ "//feature_integration_tests/test_cases:requirements.txt.lock", "//scripts/tooling:requirements.txt", "@score_docs_as_code//src:requirements_lock", ], + targets = [ + "//:docs_combo_experimental", + "//feature_integration_tests/test_scenarios/cpp:cpp_test_scenarios", + "//scripts/tooling:checkout_repos", + "//scripts/tooling:recategorize_guidelines", + "//scripts/tooling:tooling", + "@score_docs_as_code//src:plantuml", + ], ) diff --git a/MODULE.bazel b/MODULE.bazel index 9ae562d8cf5..d7649762194 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -14,7 +14,6 @@ module( name = "score_ref_int", ) - # Include common modules include("//bazel_common:score_basic_bazel.MODULE.bazel") @@ -83,7 +82,6 @@ git_override( remote = "https://github.com/bmw-software-engineering/lobster.git", ) - bazel_dep(name = "score_sbom", version = "0.0.2") sbom_ext = use_extension("@score_sbom//:extensions.bzl", "sbom_metadata") From 23ae319ec9fb10e9c677acb8974890802cd7c854 Mon Sep 17 00:00:00 2001 From: Frank Scholter Peres Date: Tue, 11 Aug 2026 08:29:59 +0000 Subject: [PATCH 09/16] add sbom step --- .github/workflows/build_and_test_linux.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/build_and_test_linux.yml b/.github/workflows/build_and_test_linux.yml index 39f9fa2527f..4650028b9f8 100644 --- a/.github/workflows/build_and_test_linux.yml +++ b/.github/workflows/build_and_test_linux.yml @@ -48,3 +48,11 @@ jobs: - name: Integration tests run: | bazel test --lockfile_mode=error --config=linux-x86_64 //feature_integration_tests/itf + - name: Build SBOM + run: | + bazel build --lockfile_mode=error //:sbom + - name: Upload SBOM to release + if: github.event_name == 'release' + uses: softprops/action-gh-release@v1 + with: + files: bazel-bin/sbom.spdx.json From 56c5f8b88511827c74d65bdfb5a61bc5ea7592ed Mon Sep 17 00:00:00 2001 From: Frank Scholter Peres Date: Tue, 11 Aug 2026 08:35:54 +0000 Subject: [PATCH 10/16] fix naming --- MODULE.bazel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MODULE.bazel b/MODULE.bazel index d7649762194..30e598deee7 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -85,7 +85,7 @@ git_override( bazel_dep(name = "score_sbom", version = "0.0.2") sbom_ext = use_extension("@score_sbom//:extensions.bzl", "sbom_metadata") -sbom_ext.track_module(name = "score_sbom_tool") +sbom_ext.track_module(name = "score_sbom") sbom_ext.track_module(name = "score_baselibs") sbom_ext.track_module(name = "score_communication") sbom_ext.track_module(name = "score_persistency") From d02902147678aff09e3d869feeb9c68825893b67 Mon Sep 17 00:00:00 2001 From: Frank Scholter Peres Date: Tue, 11 Aug 2026 08:41:38 +0000 Subject: [PATCH 11/16] lock update --- MODULE.bazel.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 6bc5b60a5aa..69b01cc688c 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -9897,7 +9897,7 @@ "@@score_sbom+//:extensions.bzl%sbom_metadata": { "general": { "bzlTransitiveDigest": "6MZmMjhsKcOnMq12Rbna7aYgF4ZAbEtH3kjZYu4M5nI=", - "usagesDigest": "7w/yzAEyY/yCBCR/jIGaWQ/+5X1bjZNUq/AMKPiAUv8=", + "usagesDigest": "9i7n8SjRs3isUDHbGTLmCZHFqJDV0njGZIidi0RDBkc=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, @@ -9907,7 +9907,7 @@ "attributes": { "metadata_content": "{\"crates\":{},\"git_repositories\":{},\"http_archives\":{},\"licenses\":{},\"modules\":{}}", "tracked_modules": [ - "score_sbom_tool", + "score_sbom", "score_baselibs", "score_communication", "score_persistency", From b3a24948a5c59aa402e59ba122b8ac778ca6a156 Mon Sep 17 00:00:00 2001 From: Frank Scholter Peres Date: Tue, 11 Aug 2026 09:05:44 +0000 Subject: [PATCH 12/16] disable cdxgen and split build --- .github/workflows/build_and_test_linux.yml | 11 +++++------ .github/workflows/test_and_docs.yml | 8 ++++++++ BUILD | 3 +-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build_and_test_linux.yml b/.github/workflows/build_and_test_linux.yml index 4650028b9f8..a0db83ecf37 100644 --- a/.github/workflows/build_and_test_linux.yml +++ b/.github/workflows/build_and_test_linux.yml @@ -42,16 +42,15 @@ jobs: disk-cache: ${{ github.workflow }} repository-cache: true cache-save: ${{ github.event_name == 'push' }} - - name: Build image + - name: Build image and product SBOM run: | - bazel build --lockfile_mode=error --config=linux-x86_64 //images/linux_x86_64:image + bazel build --lockfile_mode=error --config=linux-x86_64 \ + //images/linux_x86_64:image \ + //:sbom - name: Integration tests run: | bazel test --lockfile_mode=error --config=linux-x86_64 //feature_integration_tests/itf - - name: Build SBOM - run: | - bazel build --lockfile_mode=error //:sbom - - name: Upload SBOM to release + - name: Upload product SBOM to release if: github.event_name == 'release' uses: softprops/action-gh-release@v1 with: diff --git a/.github/workflows/test_and_docs.yml b/.github/workflows/test_and_docs.yml index e643406fc02..905cde455e8 100644 --- a/.github/workflows/test_and_docs.yml +++ b/.github/workflows/test_and_docs.yml @@ -73,6 +73,9 @@ jobs: - name: Execute Feature Integration Tests run: | bazel test --config=linux-x86_64 //feature_integration_tests/test_cases:fit + - name: Build build tools SBOM + run: | + bazel build --lockfile_mode=error //:build_tools_sbom - name: Publish build summary if: always() run: | @@ -102,6 +105,11 @@ jobs: files: ${{ github.event.repository.name }}_test_reports.zip env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Upload build tools SBOM to release + if: github.event_name == 'release' + uses: softprops/action-gh-release@v1 + with: + files: bazel-bin/build_tools_sbom.spdx.json - name: Install Graphviz uses: eclipse-score/apt-install@main with: diff --git a/BUILD b/BUILD index cc05dcc5d09..f883ae13ed5 100644 --- a/BUILD +++ b/BUILD @@ -53,14 +53,13 @@ exports_files([ sbom( name = "sbom", - auto_cdxgen = True, + auto_cdxgen = False, auto_crates_cache = True, component_name = "score_reference_integration", generation_context = "build", module_lockfiles = [":MODULE.bazel.lock"], output_formats = [ "spdx", - "cyclonedx", ], targets = [ "//feature_integration_tests/test_scenarios/cpp:cpp_test_scenarios", From cfff419b2eaf06b649f8d657c0d61b77ca441904 Mon Sep 17 00:00:00 2001 From: Frank Scholter Peres Date: Tue, 11 Aug 2026 10:40:47 +0000 Subject: [PATCH 13/16] fix missing uv --- .github/workflows/build_and_test_linux.yml | 3 +++ .github/workflows/test_and_docs.yml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/.github/workflows/build_and_test_linux.yml b/.github/workflows/build_and_test_linux.yml index a0db83ecf37..80049176f1d 100644 --- a/.github/workflows/build_and_test_linux.yml +++ b/.github/workflows/build_and_test_linux.yml @@ -42,6 +42,9 @@ jobs: disk-cache: ${{ github.workflow }} repository-cache: true cache-save: ${{ github.event_name == 'push' }} + - name: Install uv (required for SBOM license scanning) + run: | + curl -LsSf https://astral.sh/uv/install.sh | sh - name: Build image and product SBOM run: | bazel build --lockfile_mode=error --config=linux-x86_64 \ diff --git a/.github/workflows/test_and_docs.yml b/.github/workflows/test_and_docs.yml index 905cde455e8..f1f58bf5e7f 100644 --- a/.github/workflows/test_and_docs.yml +++ b/.github/workflows/test_and_docs.yml @@ -73,6 +73,9 @@ jobs: - name: Execute Feature Integration Tests run: | bazel test --config=linux-x86_64 //feature_integration_tests/test_cases:fit + - name: Install uv (required for SBOM license scanning) + run: | + curl -LsSf https://astral.sh/uv/install.sh | sh - name: Build build tools SBOM run: | bazel build --lockfile_mode=error //:build_tools_sbom From c8be0b81e681b078d818c1b5bc86935676ac7d88 Mon Sep 17 00:00:00 2001 From: Frank Scholter Peres Date: Thu, 13 Aug 2026 07:29:16 +0000 Subject: [PATCH 14/16] fix release filter --- .github/workflows/build_and_test_linux.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build_and_test_linux.yml b/.github/workflows/build_and_test_linux.yml index 80049176f1d..5bfe553672f 100644 --- a/.github/workflows/build_and_test_linux.yml +++ b/.github/workflows/build_and_test_linux.yml @@ -53,8 +53,8 @@ jobs: - name: Integration tests run: | bazel test --lockfile_mode=error --config=linux-x86_64 //feature_integration_tests/itf - - name: Upload product SBOM to release - if: github.event_name == 'release' - uses: softprops/action-gh-release@v1 + - name: Upload product SBOM + uses: actions/upload-artifact@v4 with: - files: bazel-bin/sbom.spdx.json + name: sbom-spdx + path: bazel-bin/sbom.spdx.json From 931468f1694200c5ca3cd03c3350234e3d6726ed Mon Sep 17 00:00:00 2001 From: Frank Scholter Peres Date: Thu, 13 Aug 2026 07:44:49 +0000 Subject: [PATCH 15/16] remove filter --- .github/workflows/test_and_docs.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/test_and_docs.yml b/.github/workflows/test_and_docs.yml index f1f58bf5e7f..8127579883d 100644 --- a/.github/workflows/test_and_docs.yml +++ b/.github/workflows/test_and_docs.yml @@ -109,7 +109,6 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Upload build tools SBOM to release - if: github.event_name == 'release' uses: softprops/action-gh-release@v1 with: files: bazel-bin/build_tools_sbom.spdx.json From d2a242cb2bff1207c90ec714da97e10d9b799e34 Mon Sep 17 00:00:00 2001 From: Frank Scholter Peres Date: Thu, 13 Aug 2026 11:53:19 +0000 Subject: [PATCH 16/16] optimized setup --- .github/workflows/build_and_test_ebclfsa.yml | 2 +- .github/workflows/build_and_test_linux.yml | 14 +- .github/workflows/test_and_docs.yml | 7 +- .../cli/misc/assets/report_template.html | 287 +++++++++++++++++- scripts/tooling/cli/misc/html_report.py | 55 +++- 5 files changed, 338 insertions(+), 27 deletions(-) diff --git a/.github/workflows/build_and_test_ebclfsa.yml b/.github/workflows/build_and_test_ebclfsa.yml index afb4f554e1e..86ff50df68d 100644 --- a/.github/workflows/build_and_test_ebclfsa.yml +++ b/.github/workflows/build_and_test_ebclfsa.yml @@ -45,7 +45,7 @@ jobs: run: | bazel build --lockfile_mode=error --config=eb-aarch64 //images/ebclfsa_aarch64:run - name: Upload test logs - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@604875ba63842e1d9f9aee9c783174be8b5afc23 # v5.0.0 with: name: test-logs path: | diff --git a/.github/workflows/build_and_test_linux.yml b/.github/workflows/build_and_test_linux.yml index 5bfe553672f..6c559e1fb95 100644 --- a/.github/workflows/build_and_test_linux.yml +++ b/.github/workflows/build_and_test_linux.yml @@ -32,9 +32,11 @@ jobs: - name: Clean disk space uses: eclipse-score/more-disk-space@v1 - name: Checkout repository - uses: actions/checkout@v4.2.2 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3.8.0 + uses: docker/setup-buildx-action@d707e0a9f13ec3f37a07b96fc8d8ce2ae8bb7557 # v3.8.0 + - name: Setup Bazel uses: bazel-contrib/setup-bazel@0.18.0 with: @@ -42,9 +44,11 @@ jobs: disk-cache: ${{ github.workflow }} repository-cache: true cache-save: ${{ github.event_name == 'push' }} + - name: Install uv (required for SBOM license scanning) - run: | - curl -LsSf https://astral.sh/uv/install.sh | sh + uses: astral-sh/setup-uv@v5 + with: + enable-cache: false - name: Build image and product SBOM run: | bazel build --lockfile_mode=error --config=linux-x86_64 \ @@ -54,7 +58,7 @@ jobs: run: | bazel test --lockfile_mode=error --config=linux-x86_64 //feature_integration_tests/itf - name: Upload product SBOM - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@b4b15b6c7981bb8d8f533a89aa19f67a4b7b679e # v4.4.1 with: name: sbom-spdx path: bazel-bin/sbom.spdx.json diff --git a/.github/workflows/test_and_docs.yml b/.github/workflows/test_and_docs.yml index 8127579883d..3f1dfbd11a5 100644 --- a/.github/workflows/test_and_docs.yml +++ b/.github/workflows/test_and_docs.yml @@ -74,8 +74,9 @@ jobs: run: | bazel test --config=linux-x86_64 //feature_integration_tests/test_cases:fit - name: Install uv (required for SBOM license scanning) - run: | - curl -LsSf https://astral.sh/uv/install.sh | sh + uses: astral-sh/setup-uv@v5 + with: + enable-cache: false - name: Build build tools SBOM run: | bazel build --lockfile_mode=error //:build_tools_sbom @@ -132,7 +133,7 @@ jobs: bazel run //scripts/tooling -- misc html_report --output ${CURRENT}/_build/status_dashboard.html tar -cf github-pages.tar _build - name: Upload documentation artifact - uses: actions/upload-artifact@v4.4.0 + uses: actions/upload-artifact@b4b15b6c7981bb8d8f533a89aa19f67a4b7b679e # v4.4.1 with: name: github-pages-${{ github.event.pull_request.head.sha || github.sha }} path: github-pages.tar diff --git a/scripts/tooling/cli/misc/assets/report_template.html b/scripts/tooling/cli/misc/assets/report_template.html index f3b501af52c..384d0fc60be 100644 --- a/scripts/tooling/cli/misc/assets/report_template.html +++ b/scripts/tooling/cli/misc/assets/report_template.html @@ -256,13 +256,91 @@ border-top: 1px solid var(--border); padding-top: 1rem; } +
-

Known Good Status

+

Integration Dashboard

Snapshot: {{ timestamp }}

+
+ + + +
+
@@ -272,25 +350,165 @@

Known Good Status

-
- 🔒 Add a GitHub personal access token (PAT) for live status — exact commit counts fetched directly from GitHub. - Enter it in the token field above, or - create one here. - Without a token, up-to-date / behind status is still shown from data embedded at report generation time. - Your PAT is not sent anywhere — it is only kept in the local cache of this page. -
+ +
+
+ 🔒 Add a GitHub personal access token (PAT) for live status — exact commit counts fetched directly from GitHub. + Enter it in the token field above, or + create one here. + Without a token, up-to-date / behind status is still shown from data embedded at report generation time. + Your PAT is not sent anywhere — it is only kept in the local cache of this page. +
-
-
+
+
+ +
+ Commits-behind data fetched live from the GitHub REST API. +
+
+ + +
+
+

Traceability Overview

+

+ This tab provides an overview of requirements, architecture, and test traceability for the S-CORE reference integration. + Detailed models are maintained in Sphinx with sphinx-needs and linked below. +

+ +
+

Requirements & Architecture

+

+ Central documentation and needs-based traceability are published via Sphinx. Use the links below to inspect coverage between requirements, design, tests, and components. +

+ +
+ +
+

ISO 26262 Alignment

+

+ For ISO 26262, this view will be extended to expose: +

+
    +
  • Traceability from system requirements → software components → tests.
  • +
  • Links to Safety Sentinel–based checks in the Bazel build.
  • +
  • Automated coverage metrics derived from Sphinx-Needs exports (future).
  • +
+
+
+
+ Central documentation and needs-based traceability are published via Sphinx. Use the links below to inspect coverage between requirements, design, tests, and components. +

+ + + +
+

ISO 26262 Alignment

+

+ For ISO 26262, this view will be extended to expose: +

+
    +
  • Traceability from system requirements → software components → tests.
  • +
  • Links to Safety Sentinel–based checks in the Bazel build.
  • +
  • Automated coverage metrics derived from Sphinx-Needs exports (future).
  • +
+
+ + + --> + + +
+
+

SBOM & Tool Qualification

+

+ Product SBOM (ISO 26262) and tool qualification overview for the S-CORE reference integration. +

+
-
- Commits-behind data fetched live from the GitHub REST API. -
+ +
+

Product SBOM

+

+ +
+ +
+ +
+ + + + + + + + + + +
PackageVersionSupplierLicenses
+
+
+ + +
+

Tool Qualification (ISO 26262)

+

+ Tools used in the build, analysis, and verification pipeline are documented separately and linked here. + Detailed qualification information is maintained in the S-CORE tooling documentation. +

+ +
+

Static Analysis & Code Quality

+ +
+ +
+

SBOM & Dependency Tools

+

+ SBOM generation and dependency analysis tools (e.g., Syft, Grype) are configured in CI and documented as part of the tooling landscape. + A dedicated tool-qualification table will be added here once a central manifest is available. +

+
+
+
diff --git a/scripts/tooling/cli/misc/html_report.py b/scripts/tooling/cli/misc/html_report.py index 00af22e2cf1..04d8a94c8a6 100644 --- a/scripts/tooling/cli/misc/html_report.py +++ b/scripts/tooling/cli/misc/html_report.py @@ -97,10 +97,40 @@ def _enrich_with_compare_data(entries: list[dict[str, Any]], token: str) -> None _LOG.warning("Could not fetch compare data for %s@%s", entry["owner_repo"], entry["branch"]) -def generate_report(known_good: KnownGood, token: Optional[str] = None) -> str: +def _parse_sbom_packages(sbom_path: Path) -> list[dict[str, Any]]: + """Minimal SPDX JSON parser for SBOM dashboard.""" + data = json.loads(sbom_path.read_text(encoding="utf-8")) + packages = [] + for p in data.get("packages", []): + name = (p.get("name") or "").strip() + version = (p.get("versionInfo") or "").strip() + supplier_raw = p.get("supplier") or {} + supplier = "" + if isinstance(supplier_raw, dict): + supplier = supplier_raw.get("name", "") + elif isinstance(supplier_raw, str): + supplier = supplier_raw + + licenses = [] + for lic in (p.get("licenseConcluded") or "").split(" OR "): + lic = lic.strip() + if lic and lic != "NOASSERTION": + licenses.append(lic) + + packages.append({ + "name": name, + "version": version or "", + "supplier": supplier or "", + "licenses": licenses, + }) + return packages + + +def generate_report(known_good: KnownGood, token: Optional[str] = None, sbom_packages: Optional[list[dict[str, Any]]] = None) -> str: entries = _collect_entries(known_good) if token: _enrich_with_compare_data(entries, token) + env = Environment( loader=FileSystemLoader(TEMPLATE_DIR), autoescape=select_autoescape(["html"]), @@ -108,12 +138,13 @@ def generate_report(known_good: KnownGood, token: Optional[str] = None) -> str: tmpl = env.get_template("report_template.html") return tmpl.render( modules_json=json.dumps(entries, indent=2), + sbom_packages_json=json.dumps(sbom_packages or [], indent=2), timestamp=known_good.timestamp, ) -def write_report(known_good: KnownGood, output_path: Path, token: Optional[str] = None) -> None: - Path(output_path).write_text(generate_report(known_good, token), encoding="utf-8") +def write_report(known_good: KnownGood, output_path: Path, token: Optional[str] = None, sbom_packages: Optional[list[dict[str, Any]]] = None) -> None: + Path(output_path).write_text(generate_report(known_good, token, sbom_packages), encoding="utf-8") def register(subparsers: argparse._SubParsersAction) -> None: @@ -130,6 +161,12 @@ def register(subparsers: argparse._SubParsersAction) -> None: default="report.html", help="Output HTML file path (default: report.html)", ) + parser.add_argument( + "--sbom", + metavar="PATH", + default=None, + help="Optional SPDX JSON SBOM to include in the SBOM & Tools tab.", + ) parser.set_defaults(func=_run) @@ -143,7 +180,17 @@ def _run(args: argparse.Namespace) -> int: token = os.environ.get("GITHUB_TOKEN") output = _resolve_path_from_bazel(Path(args.output)) - write_report(known_good, output, token=token) + + sbom_packages = None + if args.sbom: + sbom_path = _resolve_path_from_bazel(Path(args.sbom)) + try: + sbom_packages = _parse_sbom_packages(sbom_path) + except Exception as e: + print(f"warning: failed to parse SBOM {sbom_path}: {e}", file=sys.stderr) + + write_report(known_good, output, token=token, sbom_packages=sbom_packages) + if token: print(f"Report written to {output} (current hashes fetched from GitHub)") else: