Skip to content

Add configurable CycloneDX and SPDX SBOM generation - #2999

Merged
Sebastian Thiel (Byron) merged 2 commits into
mainfrom
sbom
Sep 16, 2026
Merged

Sebastian Thiel (Byron) merged 2 commits into
mainfrom
sbom

Conversation

@Byron

@Byron Sebastian Thiel (Byron) commented Sep 15, 2026

Copy link
Copy Markdown
Member

Tasks

This section is for Byron only. Models continuing this PR must not add, remove, check, uncheck, rename, or reorder checkboxes here.

  • refackiew

Everything below this line was generated by Codex GPT-6.

Created by Codex on behalf of Byron. Byron will review before this is ready to merge.

Adds just sbom-install, just sbom, and just sbom-test to generate CycloneDX 1.5 and SPDX 2.3 JSON using Cargo-installed tools and Rust code in jtt.

just sbom inventories all workspace members with all features and platforms. --package selects one crate with its default features on the host platform, with support for --features, --no-default-features, --all-features, --target, and --output-dir. For example:

just sbom --package gitoxide --no-default-features --features small
just sbom --package gix --features blocking-http-transport-reqwest-rust-tls

Resolution uses a temporary workspace and a copy of Cargo.lock so unrelated members cannot enable extra HTTP/TLS backends. cargo tree supplies the final graph, respecting platform-specific feature activation and host build dependencies. Inventories include runtime and build dependencies, exclude dev-only dependencies, and preserve original package identities, including binary-only workspace members. Both output files are published after generation and conversion succeed.

cargo deny cannot export these formats. The pinned tools are cargo-cyclonedx 0.5.9 and sbom-tools 0.2.0; the latter converts the same CycloneDX inventory to SPDX. Conversion reports metadata loss, such as CycloneDX properties, on stderr. These are Cargo dependency inventories; they do not scan system libraries or compiled binaries.

Validation

  • just sbom-test: isolated offline fixtures cover library/binary features, target filtering, package/version parity, valid references, output paths with spaces, source lockfile preservation, and failed conversion preserving previous output.
  • Full gix-testtools tests and doctests with sha1,sbom and GIX_TEST_IGNORE_ARCHIVES=1.
  • Focused Clippy with --no-deps and -D warnings, cargo machete, stable Rust and justfile formatting, just check-mode, and script-mode help.
  • Real inventories for all 71 workspace members, gitoxide with small and max-pure, and gix without HTTP, with Reqwest/Rustls, and with Curl/OpenSSL. Both formats have matching package versions and valid references; backend selection and the unchanged source lockfile were verified.

Clippy without --no-deps hits an existing collapsible_if warning in gix-tempfile/src/registry.rs with the installed Rust toolchain. The focused check passes.

Reported issue

Add tooling to the justfile to create an SBOM in both formats. Using cargo deny would be good if possible, and generally, cargo based tooling.

Ideally it's possible to specify a crate and its features as well, particularly relevant for the gix binary, but also for the gix crate which has vastly different dependencies depending on which HTTP backend is chosen, if at all, or which TLS implementation.

Can we avoid python please? If custom tooling is needed, rather use jtt in this repository.

@Byron

Copy link
Copy Markdown
Member Author

CC Eliah Kagan (@EliahKagan) just as FYI. It will be a while until I try and review this.

<!-- Byron -->
Let's just roll with this, rubber-stamping, as it generally seems to work.

<!-- agent  -->

Provide `just sbom-install`, `just sbom`, and `just sbom-test` using pinned
Cargo-installed tools and Rust orchestration in `jtt`. `cargo deny` cannot
export these formats, so generate CycloneDX 1.5 with `cargo-cyclonedx` and
convert that same inventory to SPDX 2.3 with `sbom-tools`.

Allow selecting a workspace package, its features, its target platform,
and an output directory. This matters for `gitoxide`'s binary profiles and
the `gix` library's optional HTTP and TLS backends. Resolve a temporary
workspace from the existing lockfile so unrelated members cannot enable
extra backends, retain runtime/build dependencies, and exclude dev-only
dependencies. Include every workspace member in the default inventory,
including binary-only packages, while preserving original package identities.

Use `cargo tree` for the final graph, including host build dependencies.
Commit review requested: "Resolve features for the selected target before
generating the BOM". `cargo metadata --filter-platform` leaves features from
other platforms enabled; an additional regression reproduces a Windows-only
backend leaking into a Linux inventory and verifies that it stays excluded.

The regression initially failed with `Unknown subcommand: sbom`. Isolated,
offline fixtures now exercise library and binary feature selection, target
filtering, valid references and matching package versions in both formats,
unchanged source lockfiles, paths with spaces, and converter failure without
replacing previous output. Normal unit tests cover argument validation;
`just sbom-test` also runs the external-tool integration test.

Validation: `just sbom-test`; the full `gix-testtools` test/doctest suite with
`sha1,sbom` and `GIX_TEST_IGNORE_ARCHIVES=1`; focused Clippy with `--no-deps`
and `-D warnings`; stable Rust and justfile formatting; `just check-mode`;
and script-mode help. Real inventories for all 71 workspace members,
`gitoxide` with `small`/`max-pure`, and `gix` without HTTP, with Reqwest/Rustls,
and with Curl/OpenSSL have matching packages and valid references in both
formats. Generation leaves the source `Cargo.lock` unchanged.
<!-- Byron -->

I just tried it, the commit just adds grouping

<!-- agent -->

The flat alphabetical list makes everyday development commands hard to find
among CI, release, and maintenance tasks.

Use native recipe groups and source order to put development commands first
and CI last. Shorten the longer descriptions and document group filtering
so contributors can focus on the commands they need.

Validated the default listing, group filtering, script invocation, and
justfile formatting. Compared parsed recipes to verify that commands,
dependencies, parameters, and aliases retain their existing behavior.
@Byron

Copy link
Copy Markdown
Member Author

Let's get this merged, also improves the justfile

@Byron
Sebastian Thiel (Byron) merged commit 77c8cd9 into main Sep 16, 2026
32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants