From 1b79745fbc5518f092b4edaf02b36cceb7a37895 Mon Sep 17 00:00:00 2001 From: Shawn Blackmore Date: Sun, 27 Sep 2026 20:54:20 -0700 Subject: [PATCH 1/2] ci: add tag-gated crates.io trusted publishing --- .github/workflows/publish-crates.yml | 39 ++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 .github/workflows/publish-crates.yml diff --git a/.github/workflows/publish-crates.yml b/.github/workflows/publish-crates.yml new file mode 100644 index 0000000..939c600 --- /dev/null +++ b/.github/workflows/publish-crates.yml @@ -0,0 +1,39 @@ +name: Publish crate + +on: + push: + tags: + - 'v*' + +permissions: + contents: read + id-token: write + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Verify tag matches Cargo package version + shell: bash + run: | + set -euo pipefail + TAG_VERSION="${GITHUB_REF_NAME#v}" + PACKAGE_VERSION="$(python - <<'PY' +import tomllib +with open('Cargo.toml','rb') as f: + print(tomllib.load(f)['package']['version']) +PY +)" + test "$TAG_VERSION" = "$PACKAGE_VERSION" + - name: Qualify package + run: | + cargo test --locked + cargo package --locked + - name: Authenticate with crates.io trusted publishing + id: auth + uses: rust-lang/crates-io-auth-action@v1 + - name: Publish crate + run: cargo publish --locked + env: + CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }} From e4cacade044e845c2693bb22aeddee080ad5fb1b Mon Sep 17 00:00:00 2001 From: Shawn Blackmore Date: Sun, 27 Sep 2026 20:54:32 -0700 Subject: [PATCH 2/2] docs: document crates.io trusted-publishing gate --- PUBLISHING.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 PUBLISHING.md diff --git a/PUBLISHING.md b/PUBLISHING.md new file mode 100644 index 0000000..80a8a28 --- /dev/null +++ b/PUBLISHING.md @@ -0,0 +1,34 @@ +# crates.io publication + +This repository is prepared for crates.io trusted publishing through `.github/workflows/publish-crates.yml`. + +## One-time registry setup + +crates.io Trusted Publishing cannot publish a brand-new crate name for the first time. The crate owner must therefore complete the **first release manually** after confirming that `entity-rust-cleanroom` is available and the package contents are correct. + +After the first crate version exists: + +1. Open the crate settings on crates.io. +2. Add a GitHub Actions Trusted Publisher. +3. Set repository owner to `blackmore-technology-group`. +4. Set repository to `ENTITY-RUST-CLEANROOM`. +5. Set workflow filename to `publish-crates.yml`. +6. Do not configure a GitHub environment unless the workflow is changed to use the same environment. +7. After the trusted path is proven, prefer Trusted-Publishing-only mode over reusable API tokens. + +## Release gate + +A release tag must be exactly `v`. The workflow: + +- requests a short-lived GitHub OIDC identity; +- verifies the tag matches the Cargo package version; +- runs the locked test suite; +- runs `cargo package --locked`; +- exchanges OIDC identity for a short-lived crates.io publishing token using `rust-lang/crates-io-auth-action`; +- publishes with `cargo publish --locked`. + +No long-lived crates.io token is stored in this repository. + +## Evidence boundary + +crates.io publication improves Rust discovery and installation of the BTG-controlled verifier. It does not constitute unrelated third-party validation or an independently authored ENTITY implementation.