-
Notifications
You must be signed in to change notification settings - Fork 0
docs: include details on how downstream products can use the rust release workflow #36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,13 @@ | ||
| rules: | ||
| superfluous-actions: | ||
| ignore: | ||
| # release-rust.yml:250 — dtolnay/rust-toolchain: explicit toolchain + | ||
| # release-rust.yml:257 — dtolnay/rust-toolchain: explicit toolchain + | ||
| # cross-target install; hand-rolling rustup here would just reimplement | ||
| # this action with less auditability. | ||
| - release-rust.yml:250 | ||
| - release-rust.yml:257 | ||
| stale-action-refs: | ||
| ignore: | ||
| # release-rust.yml:250 — dtolnay/rust-toolchain intentionally ships no | ||
| # release-rust.yml:257 — dtolnay/rust-toolchain intentionally ships no | ||
| # tags: master/stable/beta/nightly are branch aliases by design, so | ||
| # this pin is the tip of "master", not a stale reference. | ||
| - release-rust.yml:250 | ||
| - release-rust.yml:257 | ||
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,7 @@ | |
| !.zed/settings.json | ||
| !CODE_OF_CONDUCT.md | ||
| !CODEOWNERS | ||
| !docs/*.md | ||
| !flake.lock | ||
| !flake.nix | ||
| !LICENSE | ||
|
|
||
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,14 +1,24 @@ | ||
| # Release Workflows | ||
|
|
||
| [](LICENSE) | ||
| [](https://scorecard.dev/viewer/?uri=github.com/purpleclay/release-workflows) | ||
| Reusable release workflows for `purpleclay` projects. Every release built here ships with SLSA Build Level 3 provenance, per-artifact SBOMs, and keyless Sigstore signatures — with no secrets, no key material, and no per-project security plumbing. | ||
|
|
||
| Reusable release workflows for projects. Every release built here ships with SLSA Build Level 3 provenance and keyless Sigstore signatures — no per-project secrets or signing-key management. Per-artifact SBOM attestation is on the roadmap. | ||
|
|
||
| ## Why this repository exists | ||
|
|
||
| GitHub artifact attestations generated inside a project's own workflow reach SLSA Build **Level 2**: the provenance is real, but it is produced by the same workflow a compromised repository could edit. Level **3** requires the provenance to be generated somewhere the build cannot reach — a shared, vetted, isolated workflow whose identity a tenant build cannot impersonate. | ||
| This repository is that workflow. Projects delegate their release to it with a single `uses:` call, and consumers gain something stronger than "this artifact has provenance": they can verify that a release was built by *this specific pipeline*, at a known commit, from a known source revision — and reject anything that wasn't. | ||
|
|
||
| This repository is that workflow. Projects delegate their release to it with a single `uses:` call, and consumers gain something stronger than "this artifact has provenance": they can verify that a release was built by _this specific pipeline_, at a known commit, from a known source revision — and reject anything that wasn't. | ||
|
|
||
| Centralising the release path has a second benefit that has nothing to do with attestations: there is exactly one place where release security is implemented, reviewed, and improved. A hardening change lands here once and every project inherits it on its next release. | ||
|
|
||
| ## Workflows | ||
|
|
||
| | Workflow | Purpose | Caller contract | | ||
| | -------------------------------------------------- | ---------------------------------------- | -------------------------------------------- | | ||
| | [release-rust](.github/workflows/release-rust.yml) | Build, attest, and release Rust binaries | [docs/release-rust.md](docs/release-rust.md) | | ||
|
|
||
| The contract documents define everything callers may rely on — usage, inputs, outputs, supported targets, archive naming, attestation subjects, adoption steps, and how to verify what was produced — and change only under the versioning rules in [RELEASE.md](RELEASE.md). | ||
|
|
||
| Pin the full commit SHA of whichever workflow you adopt, with the version as a trailing comment, so your dependency-update tooling (Renovate, Dependabot, ...) can propose bumps — there are no floating major tags here, by design. |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| # release-rust | ||
|
|
||
| Builds Rust binaries across a fixed target allowlist, attests them, and publishes a GitHub release. This page is the **caller contract** — anything listed here changes only under the versioning rules in [RELEASE.md](../RELEASE.md). The workflow file's comments explain _how_; this page defines _what_ callers may rely on. | ||
|
|
||
| ## Usage | ||
|
|
||
| ```yaml | ||
| name: release | ||
| on: | ||
| push: | ||
| tags: ["*.*.*"] | ||
|
|
||
| permissions: {} | ||
|
|
||
| jobs: | ||
| release: | ||
| permissions: | ||
| id-token: write # OIDC identity for Sigstore signing | ||
| attestations: write # persist attestations | ||
| contents: write # create the release, upload assets | ||
| actions: read # list this run's artifacts to resolve their immutable ids | ||
| uses: purpleclay/release-workflows/.github/workflows/release-rust.yml@<pinned-sha> # vX.Y.Z | ||
| with: | ||
| bin: gpg-import | ||
| targets: '["x86_64-unknown-linux-musl","aarch64-unknown-linux-musl","x86_64-apple-darwin","aarch64-apple-darwin"]' | ||
| ``` | ||
|
|
||
| Must be triggered from a **tag push**; the workflow fails fast otherwise. | ||
|
|
||
| ## Inputs | ||
|
|
||
| See [release-rust.yml](../.github/workflows/release-rust.yml) | ||
|
|
||
| ```yaml | ||
| uses: purpleclay/release-workflows/.github/workflows/release-rust.yml@<pinned-sha> # vX.Y.Z | ||
| with: | ||
| # Binary to build and package. | ||
| # Required. | ||
| bin: | ||
|
|
||
| # JSON array of target triples. Non-array input, empty arrays, duplicates, | ||
| # and unsupported targets all fail in the plan job. | ||
| # Required. | ||
| targets: | ||
|
|
||
| # Rust toolchain specifier. | ||
| # Optional. Default is stable | ||
| toolchain: | ||
|
|
||
| # GitHub environment for the attest/publish job. Auto-created unprotected | ||
| # on first reference — add a required reviewer per repo to complete the | ||
| # S11 control. | ||
| # Optional. Default is release | ||
| environment: | ||
|
|
||
| # Extra files bundled into each archive. Missing files are skipped; a | ||
| # file whose basename equals `bin` fails. | ||
| # Optional. Default is "LICENSE README.md" | ||
| package-files: | ||
| ``` | ||
|
|
||
| ## Outputs | ||
|
|
||
| | Output | Description | | ||
| | ------------- | ----------------------------- | | ||
| | `release-url` | URL of the published release. | | ||
|
|
||
| ## Supported targets | ||
|
|
||
| | Target | Runner | Build | | ||
| | ---------------------------- | ------------ | ---------------------- | | ||
| | `x86_64-unknown-linux-musl` | ubuntu-24.04 | cargo-zigbuild (cross) | | ||
| | `aarch64-unknown-linux-musl` | ubuntu-24.04 | cargo-zigbuild (cross) | | ||
| | `x86_64-apple-darwin` | macos-15 | native cargo | | ||
| | `aarch64-apple-darwin` | macos-15 | native cargo | | ||
|
|
||
| Adding a target is a minor version; removing one is a major. | ||
|
|
||
| ## What a release contains | ||
|
|
||
| For each target: `<bin>-<version>-<target>.tar.gz` containing the binary plus `package-files`, where `<version>` is the tag name with `/` replaced by `-`. Plus `checksums.txt` (SHA-256 over each archive; generated before it exists, so it does not hash itself). Every asset — checksums.txt included — is a subject of a SLSA build provenance attestation signed by this workflow's identity. Release notes are generated by release-note from conventional commits. The archive naming and attestation subjects are contract: parsers (installers, download actions) may rely on them. | ||
|
|
||
| ## What callers must know | ||
|
|
||
| - **Builds are clean-room**: no caches are used in the release path. Release builds are slower than CI builds; that is the price of the integrity claim. | ||
| - **Checkout is shallow** in the build job: build scripts must not derive version information from git history (vergen-style `git describe`). The archive and checksum names are derived entirely from the tag (`github.ref_name`), not from `Cargo.toml` or `CARGO_PKG_VERSION` — if your build embeds a version at compile time, keep it in sync with the release tag yourself. | ||
| - **One release per tag, ever.** Re-running the workflow against a tag that already has a published release fails. Fix-forward with a new tag. | ||
| - **Dependencies are pinned centrally** (Zig, cargo-zigbuild, all actions) and bumped via reviewed `fix(deps)` patch releases — callers inherit them by bumping their pinned SHA, normally via Renovate. | ||
|
|
||
| ## Verifying what it produced | ||
|
|
||
| ```sh | ||
| gh attestation verify <artifact>.tar.gz \ | ||
| --repo purpleclay/<project> \ | ||
| --signer-workflow purpleclay/release-workflows/.github/workflows/release-rust.yml | ||
| ``` | ||
|
|
||
| The `--signer-workflow` check is the SLSA Build L3 claim: the signing identity belongs to this reusable workflow, which the calling repository invokes but cannot edit. | ||
|
|
||
| ## Adoption checklist | ||
|
|
||
| 1. Delete in-repo build/package/publish release jobs; add the caller above. | ||
| 2. Create the environment named by `environment` (default `release`) and add a required reviewer. | ||
| 3. Confirm the tag ruleset permits your release tag pattern and enable | ||
| immutable releases. | ||
| 4. Cut a pre-release tag; run the verify command against every asset. | ||
| 5. Add the standard verification section to the project README. |
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.
Uh oh!
There was an error while loading. Please reload this page.