diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..4e379d2 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.0.2 diff --git a/scripts/release.sh b/scripts/release.sh new file mode 100755 index 0000000..16dbf00 --- /dev/null +++ b/scripts/release.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$ROOT_DIR" + +VERSION_FILE="VERSION" +BRANCH="main" + +usage() { + echo "Usage: $0 patch|minor|major" >&2 + exit 1 +} + +BUMP="${1:-}" +case "$BUMP" in + patch | minor | major) ;; + *) usage ;; +esac + +if [[ "$(git rev-parse --abbrev-ref HEAD)" != "$BRANCH" ]]; then + echo "Error: releases must be cut from $BRANCH" >&2 + exit 1 +fi + +if [[ -n "$(git status --porcelain)" ]]; then + echo "Error: working tree is not clean; commit or stash first" >&2 + exit 1 +fi + +git fetch origin "$BRANCH" +if ! git merge-base --is-ancestor "origin/$BRANCH" HEAD; then + echo "Error: $BRANCH is behind origin/$BRANCH; pull first" >&2 + exit 1 +fi + +CURRENT="$(<"$VERSION_FILE")" +if [[ ! "$CURRENT" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Error: $VERSION_FILE contains '$CURRENT', expected X.Y.Z" >&2 + exit 1 +fi + +IFS=. read -r MAJOR MINOR PATCH <<<"$CURRENT" +case "$BUMP" in + major) NEW="$((MAJOR + 1)).0.0" ;; + minor) NEW="$MAJOR.$((MINOR + 1)).0" ;; + patch) NEW="$MAJOR.$MINOR.$((PATCH + 1))" ;; +esac + +# docker-publish.yml only runs tag builds for v* refs, so the tag needs the prefix. +TAG="v$NEW" +if git rev-parse -q --verify "refs/tags/$TAG" >/dev/null; then + echo "Error: tag $TAG already exists" >&2 + exit 1 +fi + +printf '%s\n' "$NEW" >"$VERSION_FILE" +git add "$VERSION_FILE" +git commit -m "Release $NEW" +git tag -a "$TAG" -m "Release $NEW" +git push origin "$BRANCH" "$TAG" + +echo "Released $CURRENT -> $NEW (tag $TAG)"