#!/usr/bin/env bash # # Builds the `warmbly` CLI for every platform we publish, packages each one, # and writes the manifests the package managers read. # # Run by the release workflow and by `make cli-dist`, so a release artifact can # be reproduced locally byte for byte given the same VERSION and COMMIT. # # ./scripts/build-cli.sh dist # # Assets are named without the version on purpose: the install script resolves # https://github.com/warmbly/warmbly/releases/latest/download/warmbly__.tar.gz # with no GitHub API call, and the unauthenticated API's rate limit is exactly # what breaks a curl installer on a shared CI runner. set -euo pipefail cd "$(dirname "$0")/.." OUT=${1:-dist} REPO=warmbly/warmbly MODULE=github.com/warmbly/warmbly VERSION=${VERSION:-$(git describe --tags --always --dirty 2>/dev/null || echo dev)} COMMIT=${COMMIT:-$(git rev-parse HEAD 2>/dev/null || echo "")} BUILT_AT=${BUILT_AT:-$(date -u +%Y-%m-%dT%H:%M:%SZ)} # Every platform the install script and the package managers know how to ask # for. Keep this list and the one in site/public/cli.sh in step; the installer # check verifies they agree. PLATFORMS="darwin/amd64 darwin/arm64 linux/amd64 linux/arm64 windows/amd64 windows/arm64" LDFLAGS="-s -w -X ${MODULE}/internal/version.Version=${VERSION} -X ${MODULE}/internal/version.Commit=${COMMIT} -X ${MODULE}/internal/version.BuiltAt=${BUILT_AT}" # macOS ships shasum and not GNU sha256sum, and this script is meant to be # reproducible on a maintainer's laptop as well as on the release runner. sha256_all() { if command -v sha256sum >/dev/null 2>&1; then sha256sum "$@" else shasum -a 256 "$@" fi } rm -rf "$OUT" mkdir -p "$OUT" # Completions ship inside every archive so the install script can drop them in # without running the binary it just downloaded, which it cannot do for a # cross-platform install anyway. stage_completions() { local host_bin=$1 dest=$2 mkdir -p "$dest" for shell in bash zsh fish powershell; do "$host_bin" completion "$shell" > "$dest/warmbly.$shell" 2>/dev/null || true done } echo "building warmbly ${VERSION}" host_bin="$OUT/.host/warmbly" mkdir -p "$OUT/.host" # shellcheck disable=SC2086 go build -ldflags="$LDFLAGS" -o "$host_bin" ./cmd/cli completions="$OUT/.completions" stage_completions "$host_bin" "$completions" for target in $PLATFORMS; do os=${target%/*} arch=${target#*/} ext="" if [ "$os" = "windows" ]; then ext=".exe"; fi stage="$OUT/.stage/warmbly_${os}_${arch}" mkdir -p "$stage" echo " $os/$arch" # shellcheck disable=SC2086 CGO_ENABLED=0 GOOS="$os" GOARCH="$arch" \ go build -ldflags="$LDFLAGS" -o "$stage/warmbly${ext}" ./cmd/cli cp LICENSE README.md "$stage/" cp -r "$completions" "$stage/completions" if [ "$os" = "windows" ]; then (cd "$stage" && zip -qr "../../warmbly_${os}_${arch}.zip" .) else tar -czf "$OUT/warmbly_${os}_${arch}.tar.gz" -C "$stage" . fi done rm -rf "$OUT/.stage" "$OUT/.host" "$OUT/.completions" (cd "$OUT" && sha256_all warmbly_* > checksums.txt) echo cat "$OUT/checksums.txt" # ───────────────────────────────────────────────────────────────────────── # Package manager manifests # # Written here rather than by hand so the checksums in them can never drift # from the archives they describe, which is the failure mode that makes a tap # install fail for everyone at once. # ───────────────────────────────────────────────────────────────────────── sum_for() { awk -v f="$1" '$2 == f { print $1 }' "$OUT/checksums.txt"; } BASE="https://github.com/${REPO}/releases/download/${VERSION}" cat > "$OUT/warmbly.rb" < "warmbly" zsh_completion.install "completions/warmbly.zsh" => "_warmbly" fish_completion.install "completions/warmbly.fish" => "warmbly.fish" end test do assert_match "warmbly", shell_output("#{bin}/warmbly version") end end EOF cat > "$OUT/warmbly.json" <