#!/bin/sh
# Refuse to push a commit to `beta` or `main` whose own signature is not a
# good SSH signature from a key in the trust anchor
# (src/omm/trust/allowed_signers).
#
# Why: `omm update` verifies the freshly fetched channel HEAD's signature
# directly (trust/__init__.py:verify_update), and the "Trusted PR head" CI
# check (scripts/verify_trusted_head.py) verifies a PR head's own signature
# without peeling a parent. A merge commit made through GitHub's web UI
# ("Sync fork" / "Update branch" / merging a PR on the site) carries only
# GitHub's web-flow GPG signature, which never verifies against the SSH
# anchor -- it strands every installed client at that HEAD ("gpg: Can't
# check signature: No public key") and blocks PRs. Keeping every trunk tip
# exact-verifiable also means `omm update` never has to walk the lineage
# chain, so an unverifiable commit deeper in history can't bite later.
#
# Only the pushed tip is checked, not the whole range: a local
# `git merge origin/main` onto beta legitimately carries main's own
# (web-flow) PR merge commits into the range, and those are fine as long as
# the tip the maintainer creates is SSH-signed.
#
# Installed via: git config core.hooksPath scripts
# Override for a genuine exception: git push --no-verify

ANCHOR="src/omm/trust/allowed_signers"
z40="0000000000000000000000000000000000000000"

status=0
while read -r local_ref local_sha remote_ref remote_sha; do
    case "$remote_ref" in
        refs/heads/beta|refs/heads/main) ;;
        *) continue ;;
    esac
    [ "$local_sha" = "$z40" ] && continue   # branch deletion

    if ! git -c gpg.format=ssh -c gpg.ssh.allowedSignersFile="$ANCHOR" \
         verify-commit "$local_sha" >/dev/null 2>&1; then
        short=$(git rev-parse --short "$local_sha")
        branch=${remote_ref#refs/heads/}
        echo "pre-push: refusing to push $short to $branch." >&2
        echo "  Its signature is not a good SSH signature from $ANCHOR." >&2
        echo "  A GitHub web-UI merge produces such a commit and breaks 'omm update'" >&2
        echo "  for every client. Re-do the merge locally:" >&2
        echo "    git checkout $branch && git merge --no-ff origin/main && git push" >&2
        status=1
    fi
done
exit $status
