From 159fccbb37323478898221fa05f9b9cb69a30c69 Mon Sep 17 00:00:00 2001 From: Ryan Lopopolo Date: Sun, 30 Aug 2026 15:08:01 -0700 Subject: [PATCH] Document trusted publishing --- CONTRIBUTING.md | 47 +++++++++++++++++++++++++++++++++ docs/publishing.md | 66 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 CONTRIBUTING.md create mode 100644 docs/publishing.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..a805882 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,47 @@ +# Contributing to Artichoke – strftime-ruby + +Welcome to [Artichoke]. Thanks for taking the time to contribute. + +`strftime-ruby` implements Ruby-compatible `Time#strftime` formatting. If its +formatting differs from Ruby or POSIX behavior, please [file an issue]. + +## Setup + +This repository uses [mise] to manage Rust, Node.js, and repository development +tools. Install the declared toolchains and text-formatting dependencies with: + +```sh +mise install +mise run pnpm-install +``` + +Run `mise tasks` to list the available development commands. + +## Validation + +Format, lint, and test changes with: + +```sh +mise run fmt +mise run lint +mise run test +``` + +Pull requests must include appropriate tests and pass all required checks before +merging. + +## Publishing + +Maintainers publish releases through crates.io trusted publishing. See +[`docs/publishing.md`](docs/publishing.md) for the trust configuration, release +procedure, and failure-recovery guidance. + +## Updating dependencies + +Regular dependency updates are handled by [Dependabot]. Keep dependency changes +focused and run the full validation suite before merging them. + +[artichoke]: https://github.com/artichoke +[dependabot]: https://docs.github.com/code-security/dependabot +[file an issue]: https://github.com/artichoke/strftime-ruby/issues/new +[mise]: https://mise.jdx.dev/ diff --git a/docs/publishing.md b/docs/publishing.md new file mode 100644 index 0000000..1e54671 --- /dev/null +++ b/docs/publishing.md @@ -0,0 +1,66 @@ +# Publishing + +This crate is published to [crates.io] by the +[`publish.yaml`](../.github/workflows/publish.yaml) GitHub Actions workflow. +Publishing uses OpenID Connect (OIDC) trusted publishing. The repository does +not store a long-lived crates.io API token. + +## Trust configuration + +The crates.io trusted publisher must match this tuple exactly: + +| Setting | Value | +| ----------------- | ------------------- | +| Crate | `strftime-ruby` | +| GitHub owner | `artichoke` | +| GitHub repository | `strftime-ruby` | +| Workflow | `publish.yaml` | +| Environment | `crates-io-publish` | + +The GitHub `crates-io-publish` environment accepts deployments only from tags +matching `v*.*.*`. Repository rulesets make tags immutable after creation. + +The trusted publisher and GitHub environment are external configuration. Audit +them against this document when changing release automation. + +## Prepare a release + +1. Open a release pull request that updates the version in `Cargo.toml` and + every repository-owned copy of that version, including `html_root_url`, + examples, and lockfiles when present. +2. Run the repository's formatting, linting, and test commands. +3. Run `cargo publish --dry-run` and inspect the packaged file list. +4. Merge the release pull request only after its required checks pass. +5. Wait for CI on the merged `trunk` commit to complete successfully. + +## Publish + +Create the release tag from the merged `trunk` commit. Tags use the exact +`vX.Y.Z` form required by the workflow. + +```sh +git switch trunk +git pull --ff-only +git tag -s "vX.Y.Z" -m "vX.Y.Z" +git push origin "vX.Y.Z" +``` + +The publish workflow verifies that the tag has exact semantic-version syntax, +that the tag version matches `Cargo.toml`, and that CI succeeded for the tagged +commit. It then exchanges its GitHub OIDC identity for a short-lived crates.io +credential and runs `cargo publish`. + +Monitor the Publish workflow through completion, then verify the new version on +crates.io and docs.rs. + +## Failed releases + +Do not move or delete a release tag. Tag immutability is an intentional release +integrity control. + +If publishing fails before crates.io accepts the version, fix the failure on +`trunk` and prepare a new patch release. Before retrying a transient failed +workflow, confirm that crates.io does not already contain the version and that +the tag still points to the intended, green commit. + +[crates.io]: https://crates.io/crates/strftime-ruby