mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-02 19:17:10 +00:00
npm revoked every classic token in December 2025 and caps a granular one at 90 days, so a token in CI would expire quarterly. OIDC is the only option left, and it matches a package's single trusted publisher against the filename of the workflow that starts the run. So the release lives in ci.yml and nowhere else: release.yml and release-publish.yml are gone, along with the released_tag the promotion used to re-cut an older commit. Actions -> ci -> Run workflow, promote=minor|major cuts a milestone, and it runs the whole suite first like a merge does. Claude-Session: https://claude.ai/code/session_01ShuAy8q8ZfPi8KHxwc8JpQ
73 lines
2.4 KiB
Bash
Executable File
73 lines
2.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Resolves the version a release is cutting. The tags this repo carries are the
|
|
# record of what has been released, so the version is counted off them and
|
|
# 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. Writes `version`, `tag` and `previous_tag` to
|
|
# $GITHUB_OUTPUT when it is set. `previous_tag` is how far back the release
|
|
# notes should reach.
|
|
set -euo pipefail
|
|
|
|
bump="${BUMP:-patch}"
|
|
|
|
# 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.
|
|
releases() { # <sed script selecting the tags to consider>
|
|
git tag -l 'v*' | sed -n "$1" | sort -V
|
|
}
|
|
|
|
stable='s/^v\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\)$/\1/p'
|
|
base="$(releases "$stable" | tail -1)"
|
|
base="${base:-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
|
|
;;
|
|
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"
|
|
|
|
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
|
|
|
|
if [ -n "${GITHUB_OUTPUT:-}" ]; then
|
|
{
|
|
echo "version=$version"
|
|
echo "tag=$tag"
|
|
echo "previous_tag=$previous_tag"
|
|
} >> "$GITHUB_OUTPUT"
|
|
fi
|