diff --git a/.github/scripts/next-version-test.sh b/.github/scripts/next-version-test.sh index 8b201e3..e156208 100755 --- a/.github/scripts/next-version-test.sh +++ b/.github/scripts/next-version-test.sh @@ -44,6 +44,13 @@ expect_version() { # [ "$status" = 0 ] || fail "$2: exit $status, want 0" } +# The manual pipeline promotes the commit this tag points at, so a wrong answer +# here releases the wrong code under the right version. +expect_released_tag() { # + grep -qxF -- "released_tag=$1" "$outputs" \ + || fail "$2: $(grep '^released_tag=' "$outputs" || echo 'no released_tag'), want released_tag=$1" +} + expect_refused() { # [ "$status" != 0 ] || fail "$1: exit 0, want a refusal" grep -q -- "$2" "$stderr" || fail "$1: refused with '$(cat "$stderr")', want it to mention '$2'" @@ -54,11 +61,14 @@ expect_refused() { # # reissuing 0.0.0. resolve first patch "" expect_version 0.0.1 first +expect_released_tag "" first # The rc tags this repository carries are candidates for 0.0.1, so the first # stable release is 0.0.1 and not 0.0.2. resolve rcs patch "" v0.0.1-rc1 v0.0.1-rc4 expect_version 0.0.1 rcs +# A candidate is not a release, so there is nothing to promote yet. +expect_released_tag "" rcs resolve patch patch "" v1.2.3 expect_version 1.2.4 patch @@ -73,13 +83,17 @@ expect_version 2.0.0 major # next patch off the wrong release and hand back 0.9.1. resolve ordering patch "" v0.9.0 v0.10.0 expect_version 0.10.1 ordering +expect_released_tag v0.10.0 ordering # A tag that is not a release is not a base to count from. resolve noise patch "" v1.2.3 nightly v2.0.0-rc1 vfoo expect_version 1.2.4 noise +expect_released_tag v1.2.3 noise resolve named "" 2.5.0 v1.2.3 expect_version 2.5.0 named +# A named version still promotes the last release rather than some other commit. +expect_released_tag v1.2.3 named # A named version wins over the bump rather than being combined with it. resolve named-over-bump major 0.4.0 v1.2.3 diff --git a/.github/scripts/next-version.sh b/.github/scripts/next-version.sh index 763358c..de3e8f2 100755 --- a/.github/scripts/next-version.sh +++ b/.github/scripts/next-version.sh @@ -5,7 +5,9 @@ # version, and a release cannot disagree with a package.json someone edited. # # BUMP is major, minor or patch. VERSION overrides it with a version named -# outright. Writes `version` and `tag` to $GITHUB_OUTPUT when it is set. +# outright. Writes `version`, `tag` and `released_tag` to $GITHUB_OUTPUT when it +# is set; `released_tag` is the release this one follows, and is empty in a +# repository that has never cut one. set -euo pipefail bump="${BUMP:-patch}" @@ -13,6 +15,18 @@ named="${VERSION:-}" semver='^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z]+(\.[0-9A-Za-z]+)*)?$' +# Only a stable tag counts as a release. v0.0.1-rc4 is a candidate for 0.0.1, so +# counting a patch off it would skip the very version it was a candidate for. +# `sort -V` puts 0.10.0 above 0.9.0, which a lexical sort does not, and +# `sed -n p` reports no matches as an empty line rather than as the failure +# `grep` would return under pipefail. +released="$(git tag -l 'v*' \ + | sed -n 's/^v\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\)$/\1/p' \ + | sort -V \ + | tail -1)" +released_tag="" +[ -n "$released" ] && released_tag="v$released" + if [ -n "$named" ]; then if [[ ! "$named" =~ $semver ]]; then echo "next-version: '$named' is not a version this releases" >&2 @@ -22,16 +36,7 @@ if [ -n "$named" ]; then version="$named" from="named outright" else - # Only a stable tag is a base to count from. v0.0.1-rc4 is a candidate for - # 0.0.1, so counting a patch off it would skip the very version it was a - # candidate for. `sort -V` puts 0.10.0 above 0.9.0, which a lexical sort does - # not, and `sed -n p` reports no matches as an empty line rather than as the - # failure `grep` would return under pipefail. - base="$(git tag -l 'v*' \ - | sed -n 's/^v\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\)$/\1/p' \ - | sort -V \ - | tail -1)" - base="${base:-0.0.0}" + base="${released:-0.0.0}" from="a $bump off ${base}" IFS=. read -r major minor patch <<<"$base" case "$bump" in @@ -59,5 +64,6 @@ if [ -n "${GITHUB_OUTPUT:-}" ]; then { echo "version=$version" echo "tag=$tag" + echo "released_tag=$released_tag" } >> "$GITHUB_OUTPUT" fi