From d7de5ca4d0149896dfad85be33bde925471567e2 Mon Sep 17 00:00:00 2001 From: "@permadeath.com" Date: Thu, 6 Aug 2026 12:45:49 -0400 Subject: [PATCH] build: compute the next version from the commits that landed `git cliff --unreleased --bumped-version` reads the conventional commits since the last tag and prints the version they imply; `cargo release` writes it into Cargo.toml and Cargo.lock, commits it, and creates an annotated tag. CONTRIBUTING.md carries the single command that joins the two. cliff.toml sets breaking_always_bump_major = false, which is the point of the file. git-cliff defaults it to true and its docs are explicit that this covers the 0-to-1 transition, so with five `!` commits in range the first bump would be 1.0.0. Checked rather than inferred: the same command prints v1.0.0 without that line and v0.2.0 with it. 1.0.0 is a promise this project has not made. release.toml turns off everything that leaves the machine. publish = false was confirmed by flipping it - true reaches the crates.io index and dies on a missing token, false never opens a socket. None of this has run against the real repo, which has no tag yet for it to count from. --- cliff.toml | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ release.toml | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 cliff.toml create mode 100644 release.toml diff --git a/cliff.toml b/cliff.toml new file mode 100644 index 0000000..44d8ed8 --- /dev/null +++ b/cliff.toml @@ -0,0 +1,48 @@ +# git-cliff (https://git-cliff.org), used here for exactly one thing: reading +# the conventional commits since the last tag and printing the version they +# imply. No changelog is generated, so there is no [changelog] section and no +# template; `git cliff --unreleased --bumped-version` prints a version and +# exits, and that is the whole of this file's job. cargo-release does the +# writing — see release.toml, and CONTRIBUTING.md for the one command that +# joins them. + +[git] +conventional_commits = true + +# Drop commits that do not parse rather than failing on them. Only the 36 +# commits from 5f7d819 onwards are conventional; the 46 before it are prose, +# and they are inside the repository forever. Without this, computing a version +# means arguing with history. It costs nothing in practice because the epoch +# tag sits on 6d16818, the last prose commit, so every commit in the range this +# is ever asked about is already conventional. --unreleased narrows it to that +# range and, as a side effect, silences the "46 commits skipped" warning that +# a whole-history run prints. +filter_unconventional = false + +[bump] +# The line this file exists for. +# +# git-cliff defaults `breaking_always_bump_major` to true, and its +# documentation is explicit that this includes "the transition from version 0 +# to 1". This repo is 0.1.0 and has five `!` commits in the range since the +# epoch tag, so under the default the first bump is 1.0.0 — verified, not +# inferred: with no [bump] section `git cliff --unreleased --bumped-version` +# prints v1.0.0 here, and with this line it prints v0.2.0. +# +# 1.0.0 would be a claim this project does not make. README and CONTRIBUTING +# both say single-user, largely AI generated, no stability guarantees; a major +# version is a promise about compatibility, and the point of 0.x is that no +# such promise has been made. So a breaking change inside 0.x bumps the minor, +# and 1.0.0 stays a decision someone takes on purpose, by passing the version +# by hand, rather than one that falls out of a `!` in a subject line. +breaking_always_bump_major = false + +# Left at git-cliff's default of true, but set explicitly because the default +# is worth disagreeing with knowingly. With this false, a `feat` under 0.x +# would only bump the patch, which would put features and bugfixes in the same +# bucket and make the version number carry less information than the commit +# log it came from. True means: feat -> minor, fix -> patch, feat! -> minor +# (via the line above). Under 0.x the minor is the only digit that moves for +# anything but a pure fix, which is the usual reading of semver's "anything MAY +# change at any time" clause for 0.y.z. +features_always_bump_minor = true diff --git a/release.toml b/release.toml new file mode 100644 index 0000000..915c76e --- /dev/null +++ b/release.toml @@ -0,0 +1,45 @@ +# 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 -- 2.51.2