From a028da763de62961111e621f8a5b14de46d93940 Mon Sep 17 00:00:00 2001 From: default <216188+jdx@users.noreply.github.com> Date: Sat, 25 Jul 2026 23:01:26 +0000 Subject: [PATCH 1/2] fix(ci): stop clap_usage changes from majoring usage-lib and usage-cli MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A clap_usage-only PR (#743) made release-plz propose v5.0.0 for usage-lib and usage-cli hours after v4.0.0 shipped, with no source change in either. `git cliff --bumped-version` reads the whole repo, so the `!` on a clap_usage commit majored everything, while `cargo set-version --exclude clap_usage` then applied that version to every crate except the one that actually broke. Scope the bump and the changelog to lib/ and cli/ so the version reflects the crates it is set on. Confirmed: scoped, there is nothing to bump since v4.0.0, which is correct — neither crate has changed. Also exit before opening a release PR when the bumped version equals the current one. Without that the fixed calculation would keep reopening a PR that bumps nothing, and #744 could not simply be closed because the next run would recreate it. Separately, publish clap_usage when its manifest is ahead of crates.io. The release path only ever published usage-lib and usage-cli, so clap_usage sat unpublished at 2.0.3 from 2025-01 until now despite the workspace building against a much newer version. Its version stays hand-managed, so the check is against the index rather than the usage-lib tag. `breaking_always_bump_major` is left alone: the policy is right, it was being applied to the wrong crates. Co-Authored-By: Claude Opus 5 --- tasks/release-plz | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/tasks/release-plz b/tasks/release-plz index cc1df63e..12dbe4fe 100755 --- a/tasks/release-plz +++ b/tasks/release-plz @@ -2,6 +2,18 @@ # shellcheck shell=bash set -euxo pipefail +# clap_usage is versioned by hand and released on its own cadence, so check it +# separately: the usage-lib release cycle below would otherwise never publish it. +# It sat unpublished at 2.0.3 from 2025-01 to 2026-07 for exactly this reason. +clap_usage_version="$(cargo pkgid clap_usage | cut -d# -f2 | cut -d@ -f2)" +if ! curl -fsS https://index.crates.io/cl/ap/clap_usage | + grep -q "\"vers\":\"$clap_usage_version\""; then + echo "Releasing clap_usage $clap_usage_version" + if [ "${usage_dry_run:-}" != 1 ]; then + cargo publish -p clap_usage + fi +fi + released_versions="$(git tag --list | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+(-rc\.[0-9]+)?$')" cur_version="$(cargo pkgid usage-lib | cut -d# -f2 | cut -d@ -f2)" if ! echo "$released_versions" | grep -q "^v$cur_version$"; then @@ -15,11 +27,16 @@ if ! echo "$released_versions" | grep -q "^v$cur_version$"; then exit 0 fi -version="$(git cliff --bumped-version)" +version="$(git cliff --bumped-version --include-path 'lib/**' --include-path 'cli/**')" + +if [ "v$cur_version" == "$version" ]; then + echo "No usage-lib/usage-cli changes since $version; nothing to release" + exit 0 +fi if [ "${usage_dry_run:-}" == 1 ]; then echo "version: $version" - changelog="$(git cliff --bump --unreleased --strip all)" + changelog="$(git cliff --bump --unreleased --strip all --include-path 'lib/**' --include-path 'cli/**')" echo "changelog: $changelog" exit 0 fi From cee8990ef904a384be15e0de46507f49e68ccd32 Mon Sep 17 00:00:00 2001 From: default <216188+jdx@users.noreply.github.com> Date: Sat, 25 Jul 2026 23:05:05 +0000 Subject: [PATCH 2/2] fix(ci): publish clap_usage in dependency order, scope every changelog call MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two problems with the previous commit: clap_usage was published from a block at the top of the script, before usage-lib. It depends on usage-lib at the workspace version, so on a release where both advance, cargo would reject the publish for an unpublished dependency and `set -e` would abort before usage-lib went out at all. It is now a function called in dependency order — after usage-lib, before usage-cli — plus once more on the path where usage-lib is already released and only clap_usage is behind, which is today's situation. The bump was scoped to lib/ and cli/ but `git cliff --bump` for CHANGELOG.md and the PR body were not, so a clap_usage breaking commit could still drive the changelog to a major while cargo set-version applied the scoped version. All four git cliff invocations are scoped now. Co-Authored-By: Claude Opus 5 --- tasks/release-plz | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/tasks/release-plz b/tasks/release-plz index 12dbe4fe..3abba50a 100755 --- a/tasks/release-plz +++ b/tasks/release-plz @@ -2,17 +2,25 @@ # shellcheck shell=bash set -euxo pipefail -# clap_usage is versioned by hand and released on its own cadence, so check it -# separately: the usage-lib release cycle below would otherwise never publish it. -# It sat unpublished at 2.0.3 from 2025-01 to 2026-07 for exactly this reason. -clap_usage_version="$(cargo pkgid clap_usage | cut -d# -f2 | cut -d@ -f2)" -if ! curl -fsS https://index.crates.io/cl/ap/clap_usage | - grep -q "\"vers\":\"$clap_usage_version\""; then - echo "Releasing clap_usage $clap_usage_version" +# clap_usage is versioned by hand and released on its own cadence, so it needs +# its own check: the usage-lib release cycle below would otherwise never publish +# it. That omission is why it sat unpublished at 2.0.3 from 2025-01 to 2026-07. +# +# It depends on usage-lib at the workspace version, so it can only be published +# once that version is on crates.io — hence a function called in dependency +# order rather than a block at the top of the script. +publish_clap_usage_if_needed() { + local version + version="$(cargo pkgid clap_usage | cut -d# -f2 | cut -d@ -f2)" + if curl -fsS https://index.crates.io/cl/ap/clap_usage | + grep -q "\"vers\":\"$version\""; then + return + fi + echo "Releasing clap_usage $version" if [ "${usage_dry_run:-}" != 1 ]; then cargo publish -p clap_usage fi -fi +} released_versions="$(git tag --list | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+(-rc\.[0-9]+)?$')" cur_version="$(cargo pkgid usage-lib | cut -d# -f2 | cut -d@ -f2)" @@ -20,6 +28,7 @@ if ! echo "$released_versions" | grep -q "^v$cur_version$"; then echo "Releasing $cur_version" if [ "${usage_dry_run:-}" != 1 ]; then cargo publish -p usage-lib + publish_clap_usage_if_needed cargo publish -p usage-cli git tag "v$cur_version" git push --tags @@ -27,6 +36,10 @@ if ! echo "$released_versions" | grep -q "^v$cur_version$"; then exit 0 fi +# usage-lib's current version is already released, so clap_usage's dependency +# is satisfied; catch it up if it is behind. +publish_clap_usage_if_needed + version="$(git cliff --bumped-version --include-path 'lib/**' --include-path 'cli/**')" if [ "v$cur_version" == "$version" ]; then @@ -42,11 +55,11 @@ if [ "${usage_dry_run:-}" == 1 ]; then fi # Generate changelog using git-cliff (LLM editorialization happens in release.yml after merge) -git cliff --bump -o CHANGELOG.md +git cliff --bump -o CHANGELOG.md --include-path 'lib/**' --include-path 'cli/**' # Get the unreleased notes for PR body # Strip version header since PR title already has version -PR_BODY="$(git cliff --bump --unreleased --strip all | tail -n +3)" +PR_BODY="$(git cliff --bump --unreleased --strip all --include-path 'lib/**' --include-path 'cli/**' | tail -n +3)" cargo set-version "${version#v}" --exclude clap_usage mise run render