#!/bin/sh
# script/release: build and publish the release artifacts with the
# pinned goreleaser. Our own extension to scripts-to-rule-them-all.
#
# Normally invoked by a tag push through .gitea/workflows/release.yml,
# not by hand: a release cut from a workstation is a release nobody can
# reproduce. Any arguments are passed through to `goreleaser release`,
# which is how script/release-snapshot adds --snapshot.
set -eu

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
ROOT="$(cd "$SCRIPT_DIR/.." && pwd -P)"

# Keep in sync with script/install-goreleaser, which owns the pin.
GORELEASER_VERSION="2.17.1"

goreleaser_version() {
    [ -x "$1" ] || return 0
    "$1" --version 2>/dev/null |
        sed -n 's/^ *GitVersion: *//p' |
        head -n 1
}

# Resolve the goreleaser to run, on the same rule script/lint uses for
# golangci-lint: a binary on PATH is accepted only when it is exactly
# the pinned version, because a differently versioned tool would
# produce a differently built release from the same tag. Anything else
# comes from .tool/bin, and a missing one is a loud failure naming the
# script that installs it rather than a silent fallback.
resolve_goreleaser() {
    path_bin="$(command -v goreleaser || true)"
    if [ -n "$path_bin" ] &&
        [ "$(goreleaser_version "$path_bin")" = "$GORELEASER_VERSION" ]; then
        echo "$path_bin"
        return 0
    fi
    if [ "$(goreleaser_version "$ROOT/.tool/bin/goreleaser")" \
        = "$GORELEASER_VERSION" ]; then
        echo "$ROOT/.tool/bin/goreleaser"
        return 0
    fi
    return 1
}

main() {
    cd "$ROOT"

    if ! bin="$(resolve_goreleaser)"; then
        cat >&2 <<EOF
release: goreleaser $GORELEASER_VERSION is not available.

Run script/bootstrap (or script/install-goreleaser directly) to install
it. A goreleaser already on PATH is used only when it reports exactly
$GORELEASER_VERSION; any other version is refused rather than used,
because the released binaries must come from a known build of a known
tool.
EOF
        exit 1
    fi

    snapshot=0
    for arg in "$@"; do
        [ "$arg" = "--snapshot" ] && snapshot=1
    done

    if [ "$snapshot" -eq 0 ]; then
        # Publishing needs a Gitea token. Check it here so the failure
        # names the secret, rather than after several minutes of
        # cross-compiling.
        if [ -z "${GITEA_TOKEN:-}" ]; then
            cat >&2 <<'EOF'
release: GITEA_TOKEN is not set.

Publishing needs a Gitea API token with write access to this
repository's releases. In CI it comes from the RELEASE_TOKEN repository
secret (see .gitea/workflows/release.yml and the Releasing section of
README.md). To build without publishing, use script/release-snapshot.
EOF
            exit 1
        fi
        # goreleaser picks its forge from whichever token variable is
        # set and refuses to run when it finds more than one. A CI
        # runner may export a GITHUB_TOKEN of its own; this repo lives
        # on Gitea and releases only there, so an unrelated token must
        # not be allowed to decide where the artifacts are published.
        unset GITHUB_TOKEN GITLAB_TOKEN
    fi

    exec "$bin" release --clean "$@"
}

main "$@"
