Files
2026-07-13 13:00:08 +08:00

262 lines
7.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# Build a local production-style Reasonix desktop package from this checkout.
#
# This is intentionally worktree-relative: run ./prod_test from any clone or
# git worktree and it will package that exact tree, including dirty local changes.
set -euo pipefail
usage() {
cat <<'EOF'
Usage:
./prod_test [platform] [version] [channel]
Examples:
./prod_test
./prod_test darwin/arm64
./prod_test darwin/universal v1.5.0-prodtest stable
./prod_fast_test
Defaults:
platform auto-detected from this machine; macOS defaults to darwin/universal
version v0.0.0-prodtest.<branch-or-detached>.<short-sha>[.dirty]
channel stable
Environment overrides:
PROD_TEST_PLATFORM Same as first argument.
PROD_TEST_VERSION Same as second argument.
PROD_TEST_CHANNEL Same as third argument.
PROD_TEST_FAST 1 enables a faster local iteration build:
native host architecture on macOS, no Wails clean,
and no DMG packaging unless overridden below.
PROD_TEST_INSTALL_TOOLS 1 installs missing Wails/create-dmg/nfpm when possible.
Set to 0 to only check and print missing deps.
PROD_TEST_OPEN_DIST 1 opens dist/ after a successful build when supported.
DESKTOP_BUILD_CLEAN 0 skips Wails -clean.
DESKTOP_BUILD_SKIP_DMG 1 skips macOS DMG creation.
EOF
}
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
usage
exit 0
fi
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
ROOT="$SCRIPT_DIR"
cd "$ROOT"
fail() {
echo "prod_test: $*" >&2
exit 1
}
need_cmd() {
command -v "$1" >/dev/null 2>&1 || fail "missing required command: $1"
}
go_bin_dir() {
local gobin
gobin="$(go env GOBIN)"
if [[ -z "$gobin" ]]; then
gobin="$(go env GOPATH)/bin"
fi
printf '%s' "$gobin"
}
sanitize_semver_id() {
local value="$1"
value="$(printf '%s' "$value" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^0-9A-Za-z]+/-/g; s/^-+//; s/-+$//; s/-+/-/g')"
printf '%s' "${value:-local}"
}
detect_platform() {
local os arch machine
case "$(uname -s)" in
Darwin) os="darwin" ;;
Linux) os="linux" ;;
MINGW*|MSYS*|CYGWIN*) os="windows" ;;
*) fail "unsupported host OS: $(uname -s)" ;;
esac
machine="$(uname -m)"
case "$machine" in
arm64|aarch64) arch="arm64" ;;
x86_64|amd64) arch="amd64" ;;
*) fail "unsupported host architecture: $machine" ;;
esac
if [[ "$os" == "darwin" ]]; then
# Match the release workflow's single macOS artifact by default.
printf 'darwin/universal'
else
printf '%s/%s' "$os" "$arch"
fi
}
detect_native_platform() {
local os arch machine
case "$(uname -s)" in
Darwin) os="darwin" ;;
Linux) os="linux" ;;
MINGW*|MSYS*|CYGWIN*) os="windows" ;;
*) fail "unsupported host OS: $(uname -s)" ;;
esac
machine="$(uname -m)"
case "$machine" in
arm64|aarch64) arch="arm64" ;;
x86_64|amd64) arch="amd64" ;;
*) fail "unsupported host architecture: $machine" ;;
esac
printf '%s/%s' "$os" "$arch"
}
default_version() {
local ref sha dirty
ref="$(git branch --show-current 2>/dev/null || true)"
if [[ -z "$ref" ]]; then
ref="$(git describe --tags --exact-match 2>/dev/null || true)"
fi
ref="${ref:-detached}"
sha="$(git rev-parse --short=8 HEAD 2>/dev/null || echo unknown)"
dirty=""
if [[ -n "$(git status --porcelain 2>/dev/null)" ]]; then
dirty=".dirty"
fi
printf 'v0.0.0-prodtest.%s.%s%s' "$(sanitize_semver_id "$ref")" "$sha" "$dirty"
}
install_or_check_tools() {
local os install_tools
os="${1%/*}"
install_tools="${PROD_TEST_INSTALL_TOOLS:-1}"
need_cmd git
need_cmd go
need_cmd node
export PATH="$(go_bin_dir):$PATH"
if ! command -v pnpm >/dev/null 2>&1; then
if [[ "$install_tools" == "1" ]]; then
echo "==> installing pnpm"
if command -v corepack >/dev/null 2>&1; then
corepack enable
corepack prepare pnpm@10 --activate
else
need_cmd npm
npm install -g pnpm@10
fi
else
fail "pnpm not found. Install with: corepack enable && corepack prepare pnpm@10 --activate"
fi
fi
if ! command -v wails >/dev/null 2>&1; then
if [[ "$install_tools" == "1" ]]; then
echo "==> installing Wails CLI"
go install github.com/wailsapp/wails/v2/cmd/wails@v2.12.0
else
fail "wails not found. Install with: go install github.com/wailsapp/wails/v2/cmd/wails@v2.12.0"
fi
fi
case "$os" in
darwin)
if [[ "${DESKTOP_BUILD_SKIP_DMG:-0}" == "1" ]]; then
return
fi
if ! command -v create-dmg >/dev/null 2>&1; then
if [[ "$install_tools" == "1" && -x "$(command -v brew 2>/dev/null || true)" ]]; then
echo "==> installing create-dmg"
brew install create-dmg
else
fail "create-dmg not found. Install with: brew install create-dmg"
fi
fi
;;
linux)
if ! command -v nfpm >/dev/null 2>&1; then
if [[ "$install_tools" == "1" ]]; then
echo "==> installing nfpm"
go install github.com/goreleaser/nfpm/v2/cmd/nfpm@v2.46.3
else
fail "nfpm not found. Install with: go install github.com/goreleaser/nfpm/v2/cmd/nfpm@v2.46.3"
fi
fi
;;
windows)
command -v makensis >/dev/null 2>&1 || fail "makensis not found. Install NSIS first."
;;
esac
}
FAST="${PROD_TEST_FAST:-0}"
if [[ "$FAST" == "1" ]]; then
export DESKTOP_BUILD_CLEAN="${DESKTOP_BUILD_CLEAN:-0}"
export DESKTOP_BUILD_SKIP_DMG="${DESKTOP_BUILD_SKIP_DMG:-1}"
fi
if [[ -n "${1:-}" ]]; then
PLATFORM="$1"
elif [[ -n "${PROD_TEST_PLATFORM:-}" ]]; then
PLATFORM="$PROD_TEST_PLATFORM"
elif [[ "$FAST" == "1" ]]; then
PLATFORM="$(detect_native_platform)"
else
PLATFORM="$(detect_platform)"
fi
VERSION="${2:-${PROD_TEST_VERSION:-$(default_version)}}"
CHANNEL="${3:-${PROD_TEST_CHANNEL:-stable}}"
OPEN_DIST="${PROD_TEST_OPEN_DIST:-1}"
case "$PLATFORM" in
darwin/*|linux/*|windows/*) ;;
*) fail "platform must look like os/arch, got: $PLATFORM" ;;
esac
case "$CHANNEL" in
stable|canary) ;;
*) fail "channel must be stable or canary, got: $CHANNEL" ;;
esac
install_or_check_tools "$PLATFORM"
if [[ -n "$(git status --porcelain)" ]]; then
echo "==> worktree has uncommitted changes; this build will include them"
git status --short
fi
wails_json="desktop/wails.json"
tmp_wails="$(mktemp)"
cp "$wails_json" "$tmp_wails"
restore_wails() {
if [[ -f "$tmp_wails" ]]; then
cp "$tmp_wails" "$wails_json"
rm -f "$tmp_wails"
fi
}
trap restore_wails EXIT
echo "==> root: ."
echo "==> branch: $(git branch --show-current 2>/dev/null || echo detached)"
echo "==> commit: $(git rev-parse --short=8 HEAD 2>/dev/null || echo unknown)"
echo "==> platform: $PLATFORM"
echo "==> version: $VERSION"
echo "==> channel: $CHANNEL"
if [[ "$FAST" == "1" ]]; then
echo "==> fast mode: DESKTOP_BUILD_CLEAN=$DESKTOP_BUILD_CLEAN DESKTOP_BUILD_SKIP_DMG=$DESKTOP_BUILD_SKIP_DMG"
fi
bash scripts/desktop-build.sh "$PLATFORM" "$VERSION" "$CHANNEL"
echo "==> restored desktop/wails.json"
echo "==> production-style artifacts are in dist/"
if [[ "$OPEN_DIST" == "1" ]]; then
case "$(uname -s)" in
Darwin) open dist ;;
Linux) command -v xdg-open >/dev/null 2>&1 && xdg-open dist >/dev/null 2>&1 || true ;;
MINGW*|MSYS*|CYGWIN*) explorer.exe dist 2>/dev/null || true ;;
esac
fi