#!/bin/bash
set -euo pipefail

# Tag and publish a new release from master.
#
# Aborts unless ALL of these hold:
#   - exactly one version argument, starting with "v"
#   - the current branch is master
#   - the working tree is clean (no staged, unstaged, or untracked changes)
#   - local master is identical to origin/master (nothing unpushed, not behind,
#     not diverged)
#   - the tag does not already exist
ORG="vektah"
REPO="gqlparser"
if [ $# -ne 1 ]; then
    echo "usage: ./bin/release vX.Y.Z" >&2
    exit 1
fi
VERSION=$1

if [[ ${VERSION} != v* ]]; then
    echo "version must start with v (got: ${VERSION})" >&2
    exit 1
fi

# Must be on master.
branch=$(git branch --show-current)
if [ "${branch}" != "master" ]; then
    echo "must be on master to release (on: ${branch:-detached HEAD})" >&2
    exit 1
fi

# Working tree must be clean: modifications, staged changes, or untracked files
# all count as dirty.
if [ -n "$(git status --porcelain)" ]; then
    echo "working tree is dirty, aborting" >&2
    exit 1
fi

# Refuse to overwrite an existing tag.
if git rev-parse -q --verify "refs/tags/${VERSION}" >/dev/null; then
    echo "tag ${VERSION} already exists, aborting" >&2
    exit 1
fi

# Local master must be exactly in sync with the remote.
git fetch --quiet origin master
local_sha=$(git rev-parse HEAD)
remote_sha=$(git rev-parse origin/master)
base_sha=$(git merge-base HEAD origin/master)
if [ "${local_sha}" != "${remote_sha}" ]; then
    if [ "${local_sha}" = "${base_sha}" ]; then
        echo "local master is behind origin/master; pull first" >&2
    elif [ "${remote_sha}" = "${base_sha}" ]; then
        echo "local master has unpushed commits; push first" >&2
    else
        echo "local master and origin/master have diverged; reconcile first" >&2
    fi
    exit 1
fi

# All preconditions met: tag the current commit and push only the tag.
git tag -s "${VERSION}" -m "${VERSION}"
git push origin "${VERSION}"

echo "Tagged ${VERSION}. Now write release notes:"
echo "  https://github.com/${ORG}/${REPO}/releases/tag/${VERSION}"

echo "Now go write some release notes! https://github.com/${ORG}/${REPO}/releases"
# Prime the Go module proxy so `go get` sees the new version promptly.
# Note! The required v2 because we are past v0/v1!
curl -sS "https://proxy.golang.org/github.com/${ORG}/${REPO}/v2/@v/${VERSION}.info"
echo