mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-03 03:27:10 +00:00
feat(ci): reach a milestone's release notes back over its patches
A promotion tags a commit that is already tagged, so GoReleaser's own previous tag makes the notes on a release consolidating six patches describe one merge. Emits the last release at the level being cut instead. Also drops the named-version path: the manual pipeline no longer offers one. Claude-Session: https://claude.ai/code/session_01ShuAy8q8ZfPi8KHxwc8JpQ
This commit is contained in:
1 parent
29ba1d34be
commit
a45f645309
2 files changed
+115
-86
No files matched your search
@@ -4,66 +4,74 @@
|
||||
# nothing in the tree holds it: no commit has to land on master to advance a
|
||||
# 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`, `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.
|
||||
# BUMP is major, minor or patch. Writes `version`, `tag`, `released_tag` and
|
||||
# `previous_tag` to $GITHUB_OUTPUT when it is set. `released_tag` is the release
|
||||
# this one follows, and is the commit a promotion re-cuts. `previous_tag` is how
|
||||
# far back the release notes should reach.
|
||||
set -euo pipefail
|
||||
|
||||
bump="${BUMP:-patch}"
|
||||
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"
|
||||
releases() { # <sed script selecting the tags to consider>
|
||||
git tag -l 'v*' | sed -n "$1" | sort -V
|
||||
}
|
||||
|
||||
if [ -n "$named" ]; then
|
||||
if [[ ! "$named" =~ $semver ]]; then
|
||||
echo "next-version: '$named' is not a version this releases" >&2
|
||||
echo "next-version: a version is MAJOR.MINOR.PATCH with an optional -prerelease, e.g. 0.1.0 or 1.0.0-rc1" >&2
|
||||
stable='s/^v\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\)$/\1/p'
|
||||
released="$(releases "$stable" | tail -1)"
|
||||
released_tag=""
|
||||
if [ -n "$released" ]; then released_tag="v$released"; fi
|
||||
|
||||
base="${released:-0.0.0}"
|
||||
IFS=. read -r major minor patch <<<"$base"
|
||||
|
||||
case "$bump" in
|
||||
major)
|
||||
version="$((major + 1)).0.0"
|
||||
level='s/^v\([0-9][0-9]*\.0\.0\)$/\1/p'
|
||||
;;
|
||||
minor)
|
||||
version="$major.$((minor + 1)).0"
|
||||
level='s/^v\([0-9][0-9]*\.[0-9][0-9]*\.0\)$/\1/p'
|
||||
;;
|
||||
patch)
|
||||
version="$major.$minor.$((patch + 1))"
|
||||
level=""
|
||||
;;
|
||||
*)
|
||||
echo "next-version: '$bump' is not a bump; use major, minor or patch" >&2
|
||||
exit 1
|
||||
fi
|
||||
version="$named"
|
||||
from="named outright"
|
||||
else
|
||||
base="${released:-0.0.0}"
|
||||
from="a $bump off ${base}"
|
||||
IFS=. read -r major minor patch <<<"$base"
|
||||
case "$bump" in
|
||||
major) version="$((major + 1)).0.0" ;;
|
||||
minor) version="$major.$((minor + 1)).0" ;;
|
||||
patch) version="$major.$minor.$((patch + 1))" ;;
|
||||
*)
|
||||
echo "next-version: '$bump' is not a bump; use major, minor or patch" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
# A patch follows the release before it, which is what GoReleaser assumes on its
|
||||
# own, so it is left alone to assume it. A milestone consolidates every patch
|
||||
# since the last release at its own level, and its notes have to reach back that
|
||||
# far or they describe the one merge that happened to be last. With nothing at
|
||||
# that level yet, they reach back to the first release there has ever been.
|
||||
previous_tag=""
|
||||
if [ -n "$level" ]; then
|
||||
previous="$(releases "$level" | tail -1)"
|
||||
previous="${previous:-$(releases "$stable" | head -1)}"
|
||||
if [ -n "$previous" ]; then previous_tag="v$previous"; fi
|
||||
fi
|
||||
|
||||
tag="v$version"
|
||||
|
||||
# A tag that is already there means this version was already cut. Moving it
|
||||
# would relabel a release that people have installed.
|
||||
if git rev-parse -q --verify "refs/tags/$tag" >/dev/null; then
|
||||
echo "next-version: $tag is already tagged, so there is nothing to release at $version" >&2
|
||||
exit 1
|
||||
echo "next-version: releasing $version, a $bump off $base"
|
||||
if [ -n "$previous_tag" ]; then
|
||||
echo "next-version: the notes reach back to $previous_tag"
|
||||
fi
|
||||
|
||||
echo "next-version: releasing $version, $from"
|
||||
if [ -n "${GITHUB_OUTPUT:-}" ]; then
|
||||
{
|
||||
echo "version=$version"
|
||||
echo "tag=$tag"
|
||||
echo "released_tag=$released_tag"
|
||||
echo "previous_tag=$previous_tag"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
Reference in new issue
Block a user