#!/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. VERSION overrides it with a version named # outright. Writes `version` and `tag` to $GITHUB_OUTPUT when it is set. set -euo pipefail bump="${BUMP:-patch}" named="${VERSION:-}" semver='^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z]+(\.[0-9A-Za-z]+)*)?$' 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 exit 1 fi 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}" 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 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 fi echo "next-version: releasing $version, $from" if [ -n "${GITHUB_OUTPUT:-}" ]; then { echo "version=$version" echo "tag=$tag" } >> "$GITHUB_OUTPUT" fi