From 7e32684d1faa03e80018cae70ceb505ad968b0e6 Mon Sep 17 00:00:00 2001 From: Anoop Narang Date: Thu, 10 Sep 2026 19:56:42 +0530 Subject: [PATCH 1/3] fix(release): read the version after checking out the base `cmd_prepare` read the current version before switching to the base branch, so the bump was computed from whatever branch the script happened to be on. Running it from any other branch cuts a release numbered off unrelated history. `scripts/release.sh` in hotdata-ibis already has this ordering; this brings the rest in line. --- scripts/release.sh | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/scripts/release.sh b/scripts/release.sh index bf84490..203ba1d 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -139,6 +139,15 @@ cmd_prepare() { ensure_clean local current new base branch pkg + base="$(default_branch)" + git fetch origin "$base" + git checkout "$base" + git pull --ff-only origin "$base" + ensure_clean + + # Read the version from the base branch, not from whatever branch the script + # was invoked on. The bump is computed from it, so reading it first numbers + # the release off unrelated history. current="$(get_version)" if [[ "$bump" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then new="$bump" @@ -147,12 +156,6 @@ cmd_prepare() { fi [[ "$new" != "$current" ]] || die "new version ($new) equals current ($current)" - base="$(default_branch)" - git fetch origin "$base" - git checkout "$base" - git pull --ff-only origin "$base" - ensure_clean - set_version "$new" update_changelog "$new" if command -v uv >/dev/null 2>&1 && [[ -f uv.lock ]]; then From e252626b21fd3ec2a0779126a7833baf8aea748f Mon Sep 17 00:00:00 2001 From: Anoop Narang Date: Thu, 10 Sep 2026 20:00:48 +0530 Subject: [PATCH 2/3] fix(release): validate the bump kind before switching branches Moving the version read below the checkout also moved the bump-kind validation, which lives inside bump_version. A typo then switched the caller to the base branch before failing. Check the argument next to the existing emptiness check, using the same pattern the explicit-version branch already accepts, so an argument error exits without side effects as it did before. --- scripts/release.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/release.sh b/scripts/release.sh index 203ba1d..fd8a3cf 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -134,6 +134,10 @@ update_changelog() { cmd_prepare() { local bump="${1:-}" [[ -n "$bump" ]] || { usage; die "missing bump kind or explicit version"; } + # Validate before any branch switch below, so a typo exits without moving the + # caller off the branch they invoked from. + [[ "$bump" =~ ^(patch|minor|major|[0-9]+\.[0-9]+\.[0-9]+)$ ]] \ + || { usage; die "unknown bump kind: $bump"; } need gh PY_BIN="$(resolve_python)" ensure_clean From 2a9db4109c09076a1fe35102105096694205910e Mon Sep 17 00:00:00 2001 From: Anoop Narang Date: Thu, 10 Sep 2026 20:04:25 +0530 Subject: [PATCH 3/3] refactor(release): one definition of the version pattern The explicit-version regex appeared in both the argument check and the branch that takes the argument verbatim, so a change to the accepted format had to be made twice. Hoist it to VERSION_RE, alongside BUMP_KIND_RE. Also narrow the comment above the check: an unchanged version and a pre-release suffix are found from the base branch version, so those necessarily fail after the checkout and the comment should not imply otherwise. --- scripts/release.sh | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/scripts/release.sh b/scripts/release.sh index fd8a3cf..c59a925 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -5,6 +5,11 @@ ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "$ROOT" die() { echo "error: $*" >&2; exit 1; } + +# The one definition of an explicit version, shared by the argument check and +# the branch that takes the argument verbatim, so the two cannot drift apart. +readonly VERSION_RE='^[0-9]+\.[0-9]+\.[0-9]+$' +readonly BUMP_KIND_RE='^(patch|minor|major)$' need() { command -v "$1" >/dev/null 2>&1 || die "$1 is required"; } # An interpreter that can `import tomllib`, which is stdlib only from 3.11. @@ -134,9 +139,11 @@ update_changelog() { cmd_prepare() { local bump="${1:-}" [[ -n "$bump" ]] || { usage; die "missing bump kind or explicit version"; } - # Validate before any branch switch below, so a typo exits without moving the - # caller off the branch they invoked from. - [[ "$bump" =~ ^(patch|minor|major|[0-9]+\.[0-9]+\.[0-9]+)$ ]] \ + # Check the argument before any branch switch below, so a typo exits without + # moving the caller off the branch they invoked from. Failures that depend on + # the base branch's version — an unchanged version, a pre-release suffix — + # can only be found after the checkout. + [[ "$bump" =~ $BUMP_KIND_RE || "$bump" =~ $VERSION_RE ]] \ || { usage; die "unknown bump kind: $bump"; } need gh PY_BIN="$(resolve_python)" @@ -153,7 +160,7 @@ cmd_prepare() { # was invoked on. The bump is computed from it, so reading it first numbers # the release off unrelated history. current="$(get_version)" - if [[ "$bump" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + if [[ "$bump" =~ $VERSION_RE ]]; then new="$bump" else new="$(bump_version "$bump" "$current")"