# cargo-release (https://github.com/crate-ci/cargo-release). git-cliff decides # what the next version is (cliff.toml); this decides what happens to the tree # when it is applied. Run from `main`, by a person, as described in # CONTRIBUTING.md — never from a feature branch, and never inside a PR. # # Everything that leaves the machine is off. This project publishes nothing: # no crates.io release, no artifacts, no prebuilt binaries. What is wanted is # narrow — the version in Cargo.toml moves, Cargo.lock follows it, and a tag # marks where the next bump should start counting from. # Not `cargo publish`, not now and not by accident. Checked by flipping this to # true in a scratch clone: with `publish = true` the run reaches "Updating # crates.io index" and dies on a missing token, and with it false it does not # touch the network at all. The "Publishing atgc" line that still prints in # both cases is a step banner, not the step. publish = false # No `git push`. The bump is a local act that is reviewed like any other commit # before it goes anywhere, and pushing a tag to the shared repo is deliberately # a separate, deliberate command. push = false # A tag is the one piece that is not optional. `git cliff --bumped-version` # counts commits since the most recent tag, so a bump that does not leave a tag # behind cannot be run twice: the second run would recompute from the epoch tag # and hand back the same answer. The tag is what makes this repeatable. tag = true tag-name = "v{{version}}" # `tag-message` being set is what makes the tag annotated rather than # lightweight. That distinction matters beyond git's own reachability rules: # an annotated tag is an object with its own hash, and the wider Tangled # ecosystem keys off that object. Verified in a scratch clone — # `git cat-file -t v0.2.0` returns `tag`, not `commit`. tag-message = "atgc {{tag_name}}" # The version commit has to satisfy the commit-msg hook this repo now installs # (prek.toml), because cargo-release shells out to `git commit` and the hook # fires. Hence `chore(release):` and a lower-case description; `chore` was added # to committed.toml's allowed_types for exactly this. Note that {{version}} # only renders here with consolidate-commits off — with it on, the commit spans # packages and the placeholder is left as literal text with a warning. This is # a single-crate repo, so off is also simply the truthful setting. pre-release-commit-message = "chore(release): atgc v{{version}}" consolidate-commits = false # The README says which release is current, and this is what writes it. The # line is rewritten before the version commit is made, so it lands in that # commit alongside Cargo.toml and Cargo.lock rather than trailing a release # by however long it takes someone to notice. # # The line is found by its opening prose and not by hidden `` markers # around it. Markers would let the wording drift freely, but they only stay # invisible if the renderer drops comments, and this README is read through # Tangled's sanitizer as well as any other — a renderer that escaped them # instead would print the scaffolding at the top of the front page. The # tradeoff bought by not finding out: "*Current release: " is now load-bearing # text. Reword it here and in tests/release_metadata.rs together. # # `(?m)` so `^` and `$` bind to the line rather than the file. The match stops # at the newline, which is why the replacement is a single line — it is one # line by design, and widening it later (a built binary alongside the tag) is # an edit to this string, not to the shape of the rule. # # `exactly = 1` is the check that matters. Without it a reword that got out of # step would leave the README pinned at whatever version it last said, and a # release that quietly does not update the thing it exists to update is worse # than one that fails; with it, cargo-release stops with "N replacements # expected, found M" before anything is committed. # # The repository URL is spelled out rather than taken from {{repository}}. # Only {{version}} is documented for this step, and an unrecognized # placeholder is not an error — it is copied through as literal text, which # would put a dead link in the README and tag it as current. The test in # tests/release_metadata.rs is the backstop for that whole class of failure: # it reads this line back and fails if it disagrees with Cargo.toml. pre-release-replacements = [ { file = "README.md", exactly = 1, search = "(?m)^\\*Current release: .*$", replace = "*Current release: [v{{version}}](https://tangled.org/permadeath.com/atgc/tags/v{{version}})*" }, ]