#!/bin/sh
# Before pushing to production—the main or master branch, or a vX.Y.Z tag—the
# pushed commit must have passed `make release`: build packages and test them
# installed on every distribution. Other branches are pushed without this gate.
#
# releases/latest/version records the built commit, so a release already run for
# this commit is not repeated. Otherwise it runs now and the push waits.
# `git push --no-verify` skips it.

set -eu
cd "$(git rev-parse --show-toplevel)"

zero=0000000000000000000000000000000000000000
gated=

# One line per reference: <local ref> <local sha> <remote ref> <remote sha>.
while read -r _ local_sha remote_ref _; do
    [ "$local_sha" != "$zero" ] || continue # borrar una referencia
    case "$remote_ref" in
    refs/heads/main | refs/heads/master | refs/tags/v[0-9]*) ;;
    *) continue ;;
    esac
    # An annotated tag arrives as its own object rather than as the commit.
    commit=$(git rev-parse "$local_sha^{commit}")
    if [ "$commit" != "$(git rev-parse HEAD)" ]; then
        echo "pre-push: $remote_ref is not HEAD; check it out so make release can build it" >&2
        exit 1
    fi
    gated=1
done

[ -n "$gated" ] || exit 0

version=$(test/version.sh)
case "$version" in
*.dirty)
    echo "pre-push: the working tree has changes; commit or stash them first" >&2
    exit 1
    ;;
esac

if [ "$(cat releases/latest/version 2>/dev/null)" = "$version" ]; then
    echo "pre-push: releases/latest is uxsm $version, already tested" >&2
    exit 0
fi

echo "pre-push: releases/latest is not uxsm $version; running make release" >&2
# stdin is the reference list, not a terminal.
make release </dev/null
