82 lines
2.9 KiB
Bash
Executable File
82 lines
2.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
set -euo pipefail
|
|
|
|
repo_root=$(CDPATH= cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)
|
|
cd "$repo_root"
|
|
|
|
usage() { printf 'Usage: scripts/package-native.sh --version vX.Y.Z --output DIR\n' >&2; }
|
|
version=''
|
|
output=''
|
|
while (( $# > 0 )); do
|
|
case "$1" in
|
|
--version) [[ $# -ge 2 ]] || { usage; exit 2; }; version=$2; shift 2 ;;
|
|
--output) [[ $# -ge 2 ]] || { usage; exit 2; }; output=$2; shift 2 ;;
|
|
*) usage; exit 2 ;;
|
|
esac
|
|
done
|
|
|
|
if [[ ! "$version" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then
|
|
printf 'error: a canonical v-prefixed release version is required\n' >&2
|
|
exit 2
|
|
fi
|
|
[[ -n "$output" ]] || { usage; exit 2; }
|
|
if ! git diff --quiet -- || ! git diff --cached --quiet --; then
|
|
printf 'error: native release packaging requires a clean tracked worktree\n' >&2
|
|
exit 1
|
|
fi
|
|
untracked_sources=$(git ls-files --others --exclude-standard -- \
|
|
'*.go' '*.sando' 'go.mod' 'go.sum' 'vendor/**' || true)
|
|
if [[ -n "$untracked_sources" ]]; then
|
|
printf 'error: untracked build inputs prevent trustworthy release provenance:\n%s\n' "$untracked_sources" >&2
|
|
exit 1
|
|
fi
|
|
target="$(go env GOOS)/$(go env GOARCH)"
|
|
case "$target" in
|
|
darwin/arm64 | linux/amd64) ;;
|
|
*) printf 'error: unsupported maintained native target: %s\n' "$target" >&2; exit 1 ;;
|
|
esac
|
|
if [[ "$(go env GOVERSION)" != go1.26.7 && "$(go env GOVERSION)" != go1.27.0 ]]; then
|
|
printf 'error: unsupported release toolchain: %s\n' "$(go env GOVERSION)" >&2
|
|
exit 1
|
|
fi
|
|
|
|
temporary=$(mktemp -d "${TMPDIR:-/tmp}/himesan-native-package.XXXXXXXX")
|
|
temporary=$(CDPATH= cd -- "$temporary" && pwd -P)
|
|
cleanup() { rm -rf -- "$temporary"; }
|
|
trap cleanup EXIT HUP INT TERM
|
|
|
|
commit=$(git rev-parse HEAD)
|
|
tree=$(git rev-parse 'HEAD^{tree}')
|
|
source_date_epoch=$(git show -s --format=%ct HEAD)
|
|
go_version=$(go env GOVERSION)
|
|
target_os=${target%/*}
|
|
target_arch=${target#*/}
|
|
linker_flags="-buildid= -X gamertan.com/sandwich-hime/internal/version.Compiler=$version"
|
|
for pass in one two; do
|
|
CGO_ENABLED=0 GOTOOLCHAIN=local go build -buildvcs=false -trimpath \
|
|
-ldflags "$linker_flags" -o "$temporary/himesan-$pass" ./cmd/himesan
|
|
done
|
|
if ! cmp -s "$temporary/himesan-one" "$temporary/himesan-two"; then
|
|
printf 'error: repeated native builds were not byte-identical\n' >&2
|
|
exit 1
|
|
fi
|
|
case "$target" in
|
|
darwin/arm64) expected='Mach-O 64-bit executable arm64' ;;
|
|
linux/amd64) expected='ELF 64-bit LSB executable, x86-64' ;;
|
|
esac
|
|
if ! file "$temporary/himesan-one" | grep -Fq "$expected"; then
|
|
printf 'error: candidate has the wrong native executable format\n' >&2
|
|
file "$temporary/himesan-one" >&2
|
|
exit 1
|
|
fi
|
|
|
|
mkdir -p -- "$output"
|
|
go run ./cmd/himesan-release package \
|
|
--version "$version" --commit "$commit" --tree "$tree" \
|
|
--go-version "$go_version" --goos "$target_os" --goarch "$target_arch" \
|
|
--binary "$temporary/himesan-one" --output "$output" \
|
|
--source-date-epoch "$source_date_epoch"
|
|
printf 'Unsigned native package created. Signing and notarization were not performed.\n'
|