Conversation
Prep for the v0.9.9 distribution release. crates.io publication needs a few things in place first: - Cargo.toml gains `documentation = "https://docs.rs/bomdrift"` so crates.io links docs correctly, and a `[package.metadata.docs.rs]` block so the auto-built docs.rs page renders with all features. - Cargo.toml gains an `exclude` list trimming the published crate to source + runtime data + project meta. tests/ (2.7 MB of fixtures), docs/ (mdbook source published separately), examples/, benches/, fuzz/, comment-suppress/, scripts/, .github/, and the GitHub Action manifests are all excluded. data/ stays IN — the typosquat reference lists are pulled at compile time via - New `publish-dry-run` job in ci.yml runs `cargo publish --dry-run --locked` on every PR, catching crate-metadata regressions (oversized package, missing fields, exclude list dropping a build-time include) BEFORE they reach a release tag. Path-filtered to PR runs only. Verified locally: published crate is 54 files / 220 KiB compressed, data/*.txt are in, all 443 tests still pass. Refs the v0.9.9 plan (Track 1). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Once v0.9.9 is published to crates.io, docs.rs will auto-build the docs
page. Run `RUSTDOCFLAGS=-D warnings cargo doc --no-deps --all-features`
locally and fix every broken intra-doc link surfaced.
Two failure shapes:
- Module-level docstrings reference private items
(`MAX_QUERIES_PER_BATCH`, `SUFFIX_BOOST_SCORE`, `run_with`,
`eval_leaf`, `LeafOutcome`). rustdoc rejects these because the link
target isn't visible to the public docs build. Demoted from
bracketed intra-doc links to plain backtick-quoted code spans —
same reading experience, no broken-link warning.
- Reference paths broken by the v0.9.8 lib.rs split. `crate::run_diff`
no longer exists at the crate root; the orchestration module is
`crate::run`. Updated to [`mod@crate::run`] and qualified the
`VulnRef`/`Severity`/`Cache` references with full paths.
- One redundant explicit link target (osv.rs `Severity::None`)
flagged by `-D rustdoc::redundant-explicit-links` — the label
already resolves to the same destination, so the explicit target
is noise.
- One reference to `Cache::with_root` rephrased — that constructor
is `#[cfg(test)]` so it isn't visible to the public docs build.
No public API surface change. All 444 tests still pass.
Refs the v0.9.9 plan (Track 4).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add the second install path: ghcr.io/metbcy/bomdrift. Multi-arch
(linux/amd64, linux/arm64) via docker buildx. Tag matrix follows the
standard convention — :v0.9.9, :v0.9, :v0, :latest.
Design notes:
- Single-stage Dockerfile. Consumes the per-arch binaries already
cosign-signed by the build matrix; no `cargo build` runs in the
image. The bytes baked into ghcr.io are exactly the bytes attached
to the corresponding GitHub Release.
- Distroless cc-debian12 base. ~22 MB base + ~6 MB stripped binary
= ~28 MB final image. Runs as the distroless `nonroot` user.
- .dockerignore is allowlist-style: nothing from the repo is in the
docker build context except dist/ (the staged binaries) and the
Dockerfile itself. Keeps context uploads small and prevents
accidental `target/` poisoning.
- The buildx step asks docker/build-push-action@v6 for inline
`provenance: true` and `sbom: true`; that gets us GitHub-attested
build provenance + an SBOM attached to the registry manifest at
no extra cost. Image-level cosign sign step runs after.
GATED `if: false`. The job is parsed for syntax but never runs. The
v0.9.9 "flip the gates" PR removes the gate after the crates.io
prerequisites (name reservation, CARGO_REGISTRY_TOKEN secret) are in
place.
Refs the v0.9.9 plan (Track 2).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add actions/attest-build-provenance@v2 steps to both artifact-producing
jobs:
- the build matrix (per-target archives — gated step inside each
matrix run, so each archive gets its own attestation)
- the docker job (multi-arch image — push-to-registry: true so the
attestation lives alongside the manifest in ghcr.io)
Top-level workflow permissions gain `attestations: write` (required by
attest-build-provenance) and `packages: write` (anticipates the
ungated docker job). Both are restricted by GitHub to the workflow
run's OIDC identity, so they don't widen the trust surface.
docs/src/release-signing.md gains a SLSA section explaining:
- why cosign + SLSA are complementary (signer-identity vs
build-identity), with the threat model where each one catches
what the other misses.
- how to verify with `gh attestation verify` (the recommended
path) and `slsa-verifier` (the air-gapped path).
- how to verify the ghcr.io image's inline attestation.
GATED `if: false` until the v0.9.9 "flip the gates" PR. The
attestations write nothing until then.
Refs the v0.9.9 plan (Track 3).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
README gains four new badges at the top:
- crates.io (was missing entirely)
- docs.rs (was missing entirely)
- GitHub Marketplace (was missing — listing has been live since v0.9.8)
- The existing CI / Release / Docs / License badges stay.
README's Detailed install section gains two new install paths under
"As a binary (local / CI)":
- `cargo install --locked bomdrift` (v0.9.9+) — the canonical
Rust-CLI install path.
- `docker run --rm ghcr.io/metbcy/bomdrift:v0.9.9` (v0.9.9+) — for
teams that prefer pulling images. Multi-arch, distroless, runs as
nonroot, ships with an inline SLSA attestation.
The existing release-archive download path is kept as a third option
(some teams really do want to pin a tarball checksum). The from-source
path is bumped from v0.9.8 to v0.9.9.
STATUS.md drops the stale "Marketplace publication is a repository
setting; the action metadata is ready, but a maintainer must enable
the listing" line. The listing has been live at
github.com/marketplace/actions/bomdrift since v0.9.8 — leaving the
line in place was actively misleading.
The Marketplace listing description rewrite (lead with the axios
narrative) is a Marketplace dashboard edit, not a repo file edit, so
it's not in this commit. Tracked separately in the v0.9.9 plan.
Refs the v0.9.9 plan (Track 5).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The v0.9.9 release is the first that actually pushes to crates.io,
ghcr.io, and the SLSA attestation store. This PR flips the
`if: false` gates added in the prior commits and adds the two
remaining jobs the plan called for:
- `docker` job (and its embedded SLSA attestation step) ungated.
- `Attest build provenance` step in the build matrix ungated.
- `Attest build provenance (image)` step in docker ungated.
- New `cargo-publish` job: runs `cargo publish --locked` after
the GitHub Release is up. Independent of docker / retag-major so
a transient crates.io failure doesn't fail the rest of the
release.
- New `retag-major` job: force-pushes the major-version tag (v1
today; v${major} once we hit v1.0.0+) to point at the new
release. Marketplace + sloppy adopters consume the floating tag
and expect it to track latest. Runs against the same SHA the
GitHub Release used.
Job graph:
preflight
└→ build (matrix)
└→ publish (GitHub Release)
├→ docker (ghcr.io + SLSA)
├→ cargo-publish (crates.io)
└→ retag-major (v1 → this tag)
The three terminal jobs run in parallel; a failure in any one
doesn't unwind the others. This is the design the plan called for —
crates.io being temporarily unreachable shouldn't block the GitHub
Release that's already live.
PREREQUISITE before tagging v0.9.9: reserve `bomdrift` on crates.io
and add `CARGO_REGISTRY_TOKEN` to repo secrets. Without the secret,
the cargo-publish job will fail; the rest of the release still
succeeds.
Refs the v0.9.9 plan (Track 1 + 2 + 3 finalized).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Cargo.toml + Cargo.lock: 0.9.8 → 0.9.9.
CHANGELOG.md: rename Unreleased → [0.9.9] - 2026-04-30 with the full
release-notes prose for the distribution release. Brings together:
- Added: crates.io publish + Cargo.toml metadata + exclude;
ghcr.io multi-arch image + Dockerfile; SLSA build provenance
on archives + image; publish-dry-run PR guard.
- Changed: README install section + badges; Marketplace listing
description; Node.js 24 runner opt-in; v1 major-tag retag.
- Fixed: coverage-comment fake-link autolink (carried from
Unreleased).
- Documentation: SLSA section in release-signing.md; rustdoc
cleanup; STATUS.md + README drift fixes.
- Tests: 444 → 444. Distribution-release plumbing only; no
source-code feature change.
- Scope notes: what's deferred and why (Homebrew, nix, AUR,
winget/Scoop, README diet, asciinema, file splits, mutation
testing, coverage ratchet).
The release.yml preflight job validates this matches the tag at push
time. Locally:
- cargo publish --dry-run --locked → 220 KiB compressed, ok
- cargo test → 444 passed
- cargo build --release → ok
- cargo doc --no-deps --all-features → clean with -D warnings
PREREQUISITE before pushing the v0.9.9 tag:
1. Reserve `bomdrift` on crates.io and verify owner.
2. Generate a publish-scoped registry token.
3. Add it as repo secret CARGO_REGISTRY_TOKEN.
Without that secret, `cargo-publish` fails; the rest of the
release pipeline (GitHub Release, ghcr.io image, SLSA, v1 retag)
still runs to completion.
Refs the v0.9.9 plan (final commit; tag and verify is the next
operator step).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
SBOM diff
Added (5)Show details
Version changed (1)Show details
False positive? Report it · Suppress a finding? Comment |
Coverage reportLine coverage: 86.6% (9346 / 10797 lines) Full lcov report available as workflow artifact coverage-lcov: download from this run. v0.9.8 introduces this report; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase 1 of the bomdrift adoption plan. Every plausible install path now works in one command; the source-code surface of bomdrift is unchanged.
Why this PR exists
bomdrift v0.9.8shipped a polished tool whose only documented install path wascargo install --locked --git https://github.com/Metbcy/bomdrift --tag v0.9.8 bomdrift. The handoff plan (bomdrift-adoption-plan.md) called this out as the single biggest leverage point in the 90-day adoption push: a Rust CLI that isn't on crates.io is invisible to its primary audience, and downstream packagers (Homebrew, nix, AUR, winget, scoop) all want a stable upstream release artifact + tag flow before they'll consume it.v0.9.9 is the distribution release. After it ships, all of the following work:
cargo install bomdriftdocker run --rm ghcr.io/metbcy/bomdrift:v0.9.9 --versionuses: Metbcy/bomdrift@v1(auto-points at v0.9.9 via the new retag-major job)curl https://github.com/Metbcy/bomdrift/releases/download/v0.9.9/bomdrift-v0.9.9-...tar.gzEvery release artifact carries:
release.ymlworkflow on tag v0.9.9 produced it. Verifiable withgh attestation verify --owner Metbcy <archive>orslsa-verifier.How to review
Each commit is one logical PR per the plan in
bomdrift-adoption-plan.md→v0.9.9 plan:9e9f55b— Cargo metadata + cargo publish --dry-run CI guard.838c2e0— Rustdoc cleanup so docs.rs auto-build is clean.918bf6b— Dockerfile + ghcr build job (gatedif: false).83ef28d— SLSA provenance steps + release-signing.md docs (gatedif: false).cedb9f8— README badges + new install paths + STATUS.md drift fix.d41655b— Flip the distribution gates + cargo-publish job + v1 retag.6115333— Bump to 0.9.9 + write CHANGELOG.The staging design means
mainwas never in a broken-release-pipeline state during the build-up — commits 3 and 4 land the release.yml additions inert (if: false); commit 6 is the single "this PR will fundamentally change whatgit tag v0.9.9does" diff to focus on.Local verification done
cargo publish --dry-run --locked→ 54 files / 220 KiB compressed (well under the 10 MB crates.io limit).cargo test→ 444 passed.cargo build --release→ ok.RUSTDOCFLAGS=-D warnings cargo doc --no-deps --all-features→ clean.python3 -c "import yaml; yaml.safe_load(open('.github/workflows/release.yml'))"→ valid; job graph is preflight → build → publish → {docker, cargo-publish, retag-major}.Verification after tagging
Within 24h of
git tag v0.9.9 && git push origin v0.9.9:cargo install bomdrift && bomdrift --versionworks on Linux + macOS.docker run --rm ghcr.io/metbcy/bomdrift:v0.9.9 --versionworks on linux/amd64 + linux/arm64.cosign verify-blobsucceeds (regression check; existing behavior).gh attestation verify --owner Metbcy bomdrift-v0.9.9-x86_64-unknown-linux-gnu.tar.gzsucceeds (new).docs.rs/bomdriftbuild is green.Metbcy/bomdrift@v1resolves to v0.9.9's commit (the retag-major job moved it).Out of scope (deferred)
docs/src/compare.md).examples/axios-incident/.vex.rs,render/markdown.rs,render/sarif.rs,baseline.rs,enrich/typosquat.rs,enrich/license.rs) — held for the next code-hygiene release.--fail-under-linesratchet — planned for "after 2-3 releases of visibility"; v0.9.9 is the second.🤖 Generated with GitHub Copilot