#!/usr/bin/env bash
# Cut a release.
#
#   bin/release 0.1.3
#
# Everything that can be known before the tag exists is written here, on a
# machine with a toolchain, and verified — because the one thing a release job
# cannot do is repair a mistake it has already pushed. The tag then points at a
# commit that is already consistent with itself.
#
# The single exception is the digest of the tarball GitHub builds for the tag,
# which cannot exist until the tag does. The release workflow writes that one
# line afterwards, and nothing else.
set -euo pipefail

cd "$(dirname "$0")/.."

version="${1:-}"
if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
  echo "usage: bin/release <version>   e.g. bin/release 0.1.3" >&2
  exit 2
fi
tag="v$version"

say() { printf '\033[1;34m==>\033[0m %s\n' "$1"; }
die() { printf '\033[1;31m✗\033[0m %s\n' "$1" >&2; exit 1; }

[ -z "$(git status --porcelain)" ] || die "working tree is not clean"
[ "$(git rev-parse --abbrev-ref HEAD)" = main ] || die "not on main"
git fetch -q origin
[ "$(git rev-parse HEAD)" = "$(git rev-parse origin/main)" ] || die "main is not in step with origin"
git rev-parse -q --verify "refs/tags/$tag" >/dev/null && die "$tag already exists"
if git ls-remote --exit-code --tags origin "$tag" >/dev/null 2>&1; then
  die "$tag already exists on origin — a published tag must never move, since the PKGBUILD digest would stop matching for everybody"
fi

say "Writing $version into the three places a tag cannot float"
sed -i -E "0,/^version = \"[0-9]+\.[0-9]+\.[0-9]+\"/s||version = \"$version\"|" Cargo.toml
sed -i -E "s|^pkgver=.*|pkgver=$version|" packaging/aur/PKGBUILD
cargo update -p omacharts

say "Checking the tree agrees with itself"
cargo build --workspace --locked
cargo test --workspace --locked
grep -q "^version = \"$version\"" Cargo.toml || die "Cargo.toml did not take"
grep -q "^pkgver=$version$" packaging/aur/PKGBUILD || die "PKGBUILD did not take"
grep -A1 '^name = "omacharts"' Cargo.lock | grep -q "^version = \"$version\"" \
  || die "Cargo.lock did not take — every --locked build would refuse"

say "Committing and tagging"
git add Cargo.toml Cargo.lock packaging/aur/PKGBUILD
git commit -q -m "Release $version"
git tag -a "$tag" -m "Release $version"

say "Pushing"
git push -q origin main
git push -q origin "$tag"

cat <<DONE

Released $tag.

The workflow now builds it, writes the tarball's digest into the PKGBUILD —
the one thing that could not be known before the tag — and attaches the Arch
package to the release.

  gh run watch \$(gh run list --workflow Release --limit 1 --json databaseId --jq '.[0].databaseId')
DONE
