#!/usr/bin/env bash
# Merges the current branch into master and tags a release. Run
# deploy/prepare-release.sh on this branch first - this script does not
# build anything itself, it only bumps VERSION, merges, tags, and pushes.
set -euo pipefail

if [ $# -ne 1 ]; then
    echo "Usage: deploy/publish-release.sh <version>   e.g. deploy/publish-release.sh 1.1.0" >&2
    exit 1
fi

VERSION="$1"
cd "$(dirname "$0")/.."

if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
    echo "Version must be plain SemVer (MAJOR.MINOR.PATCH), got: $VERSION" >&2
    exit 1
fi

CURRENT_BRANCH="$(git branch --show-current)"

if [ "$CURRENT_BRANCH" = "master" ]; then
    echo "Run this from the branch you want to release (e.g. develop), not from master itself." >&2
    exit 1
fi

echo "==> Bumping VERSION to $VERSION on $CURRENT_BRANCH..."
echo "$VERSION" > VERSION
git add VERSION
git commit -m "Release v$VERSION" --allow-empty

# Push the version-bump commit back to its own branch immediately -
# otherwise it only ever exists locally and inside the master merge
# below, leaving origin/$CURRENT_BRANCH permanently stuck behind by
# however many commits this release added (a real gap that shipped
# once: origin/develop sat 5 commits behind origin/master because this
# push was simply missing).
echo "==> Pushing $CURRENT_BRANCH..."
git push origin "$CURRENT_BRANCH"

# Merge into master via a scratch worktree instead of `git checkout
# master` in this working directory - this repo's checked-out branch
# never changes, even transiently, and a failure here (bad merge,
# push rejected, etc.) can never strand you on master.
echo "==> Merging $CURRENT_BRANCH into master (in a scratch worktree)..."
git worktree prune
git fetch origin master:master
WORKTREE_DIR="$(mktemp -d)"
git worktree add --quiet "$WORKTREE_DIR" master

cleanup() {
    git worktree remove "$WORKTREE_DIR" --force >/dev/null 2>&1 || true
}
trap cleanup EXIT

(
    cd "$WORKTREE_DIR"
    git merge --no-ff "$CURRENT_BRANCH" -m "Merge $CURRENT_BRANCH into master for v$VERSION"
    echo "==> Tagging v$VERSION..."
    git tag -a "v$VERSION" -m "v$VERSION"
    echo "==> Pushing master and the tag..."
    git push origin master
    git push origin "v$VERSION"
)

cat <<EOF

Done. master is now at v$VERSION and pushed.

Tonight's 2am cron on the server (deploy/update.php) will pick this up
on its own. To deploy right now instead of waiting, visit or trigger
deploy/update.php on the server directly.
EOF
