返回 DeepSeek-Reasonix
prod_test
根目录 / prod_test
1 #!/usr/bin/env bash
2 # Build a local production-style Reasonix desktop package from this checkout.
3 #
4 # This is intentionally worktree-relative: run ./prod_test from any clone or
5 # git worktree and it will package that exact tree, including dirty local changes.
6 set -euo pipefail
7
8 usage() {
9 cat <<'EOF'
10 Usage:
11 ./prod_test [platform] [version] [channel]
12
13 Examples:
14 ./prod_test
15 ./prod_test darwin/arm64
16 ./prod_test darwin/universal v1.5.0-prodtest stable
17 ./prod_fast_test
18
19 Defaults:
20 platform auto-detected from this machine; macOS defaults to darwin/universal
21 version v0.0.0-prodtest.<branch-or-detached>.<short-sha>[.dirty]
22 channel stable
23
24 Environment overrides:
25 PROD_TEST_PLATFORM Same as first argument.
26 PROD_TEST_VERSION Same as second argument.
27 PROD_TEST_CHANNEL Same as third argument.
28 PROD_TEST_FAST 1 enables a faster local iteration build:
29 native host architecture on macOS, no Wails clean,
30 and no DMG packaging unless overridden below.
31 PROD_TEST_INSTALL_TOOLS 1 installs missing Wails/create-dmg/nfpm when possible.
32 Set to 0 to only check and print missing deps.
33 PROD_TEST_OPEN_DIST 1 opens dist/ after a successful build when supported.
34 DESKTOP_BUILD_CLEAN 0 skips Wails -clean.
35 DESKTOP_BUILD_SKIP_DMG 1 skips macOS DMG creation.
36 EOF
37 }
38
39 if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
40 usage
41 exit 0
42 fi
43
44 SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
45 ROOT="$SCRIPT_DIR"
46 cd "$ROOT"
47
48 fail() {
49 echo "prod_test: $*" >&2
50 exit 1
51 }
52
53 need_cmd() {
54 command -v "$1" >/dev/null 2>&1 || fail "missing required command: $1"
55 }
56
57 go_bin_dir() {
58 local gobin
59 gobin="$(go env GOBIN)"
60 if [[ -z "$gobin" ]]; then
61 gobin="$(go env GOPATH)/bin"
62 fi
63 printf '%s' "$gobin"
64 }
65
66 sanitize_semver_id() {
67 local value="$1"
68 value="$(printf '%s' "$value" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^0-9A-Za-z]+/-/g; s/^-+//; s/-+$//; s/-+/-/g')"
69 printf '%s' "${value:-local}"
70 }
71
72 detect_platform() {
73 local os arch machine
74 case "$(uname -s)" in
75 Darwin) os="darwin" ;;
76 Linux) os="linux" ;;
77 MINGW*|MSYS*|CYGWIN*) os="windows" ;;
78 *) fail "unsupported host OS: $(uname -s)" ;;
79 esac
80
81 machine="$(uname -m)"
82 case "$machine" in
83 arm64|aarch64) arch="arm64" ;;
84 x86_64|amd64) arch="amd64" ;;
85 *) fail "unsupported host architecture: $machine" ;;
86 esac
87
88 if [[ "$os" == "darwin" ]]; then
89 # Match the release workflow's single macOS artifact by default.
90 printf 'darwin/universal'
91 else
92 printf '%s/%s' "$os" "$arch"
93 fi
94 }
95
96 detect_native_platform() {
97 local os arch machine
98 case "$(uname -s)" in
99 Darwin) os="darwin" ;;
100 Linux) os="linux" ;;
101 MINGW*|MSYS*|CYGWIN*) os="windows" ;;
102 *) fail "unsupported host OS: $(uname -s)" ;;
103 esac
104
105 machine="$(uname -m)"
106 case "$machine" in
107 arm64|aarch64) arch="arm64" ;;
108 x86_64|amd64) arch="amd64" ;;
109 *) fail "unsupported host architecture: $machine" ;;
110 esac
111 printf '%s/%s' "$os" "$arch"
112 }
113
114 default_version() {
115 local ref sha dirty
116 ref="$(git branch --show-current 2>/dev/null || true)"
117 if [[ -z "$ref" ]]; then
118 ref="$(git describe --tags --exact-match 2>/dev/null || true)"
119 fi
120 ref="${ref:-detached}"
121 sha="$(git rev-parse --short=8 HEAD 2>/dev/null || echo unknown)"
122 dirty=""
123 if [[ -n "$(git status --porcelain 2>/dev/null)" ]]; then
124 dirty=".dirty"
125 fi
126 printf 'v0.0.0-prodtest.%s.%s%s' "$(sanitize_semver_id "$ref")" "$sha" "$dirty"
127 }
128
129 install_or_check_tools() {
130 local os install_tools
131 os="${1%/*}"
132 install_tools="${PROD_TEST_INSTALL_TOOLS:-1}"
133
134 need_cmd git
135 need_cmd go
136 need_cmd node
137 export PATH="$(go_bin_dir):$PATH"
138
139 if ! command -v pnpm >/dev/null 2>&1; then
140 if [[ "$install_tools" == "1" ]]; then
141 echo "==> installing pnpm"
142 if command -v corepack >/dev/null 2>&1; then
143 corepack enable
144 corepack prepare pnpm@10 --activate
145 else
146 need_cmd npm
147 npm install -g pnpm@10
148 fi
149 else
150 fail "pnpm not found. Install with: corepack enable && corepack prepare pnpm@10 --activate"
151 fi
152 fi
153
154 if ! command -v wails >/dev/null 2>&1; then
155 if [[ "$install_tools" == "1" ]]; then
156 echo "==> installing Wails CLI"
157 go install github.com/wailsapp/wails/v2/cmd/wails@v2.12.0
158 else
159 fail "wails not found. Install with: go install github.com/wailsapp/wails/v2/cmd/wails@v2.12.0"
160 fi
161 fi
162
163 case "$os" in
164 darwin)
165 if [[ "${DESKTOP_BUILD_SKIP_DMG:-0}" == "1" ]]; then
166 return
167 fi
168 if ! command -v create-dmg >/dev/null 2>&1; then
169 if [[ "$install_tools" == "1" && -x "$(command -v brew 2>/dev/null || true)" ]]; then
170 echo "==> installing create-dmg"
171 brew install create-dmg
172 else
173 fail "create-dmg not found. Install with: brew install create-dmg"
174 fi
175 fi
176 ;;
177 linux)
178 if ! command -v nfpm >/dev/null 2>&1; then
179 if [[ "$install_tools" == "1" ]]; then
180 echo "==> installing nfpm"
181 go install github.com/goreleaser/nfpm/v2/cmd/nfpm@v2.46.3
182 else
183 fail "nfpm not found. Install with: go install github.com/goreleaser/nfpm/v2/cmd/nfpm@v2.46.3"
184 fi
185 fi
186 ;;
187 windows)
188 command -v makensis >/dev/null 2>&1 || fail "makensis not found. Install NSIS first."
189 ;;
190 esac
191 }
192
193 FAST="${PROD_TEST_FAST:-0}"
194 if [[ "$FAST" == "1" ]]; then
195 export DESKTOP_BUILD_CLEAN="${DESKTOP_BUILD_CLEAN:-0}"
196 export DESKTOP_BUILD_SKIP_DMG="${DESKTOP_BUILD_SKIP_DMG:-1}"
197 fi
198
199 if [[ -n "${1:-}" ]]; then
200 PLATFORM="$1"
201 elif [[ -n "${PROD_TEST_PLATFORM:-}" ]]; then
202 PLATFORM="$PROD_TEST_PLATFORM"
203 elif [[ "$FAST" == "1" ]]; then
204 PLATFORM="$(detect_native_platform)"
205 else
206 PLATFORM="$(detect_platform)"
207 fi
208 VERSION="${2:-${PROD_TEST_VERSION:-$(default_version)}}"
209 CHANNEL="${3:-${PROD_TEST_CHANNEL:-stable}}"
210 OPEN_DIST="${PROD_TEST_OPEN_DIST:-1}"
211
212 case "$PLATFORM" in
213 darwin/*|linux/*|windows/*) ;;
214 *) fail "platform must look like os/arch, got: $PLATFORM" ;;
215 esac
216
217 case "$CHANNEL" in
218 stable|canary) ;;
219 *) fail "channel must be stable or canary, got: $CHANNEL" ;;
220 esac
221
222 install_or_check_tools "$PLATFORM"
223
224 if [[ -n "$(git status --porcelain)" ]]; then
225 echo "==> worktree has uncommitted changes; this build will include them"
226 git status --short
227 fi
228
229 wails_json="desktop/wails.json"
230 tmp_wails="$(mktemp)"
231 cp "$wails_json" "$tmp_wails"
232 restore_wails() {
233 if [[ -f "$tmp_wails" ]]; then
234 cp "$tmp_wails" "$wails_json"
235 rm -f "$tmp_wails"
236 fi
237 }
238 trap restore_wails EXIT
239
240 echo "==> root: ."
241 echo "==> branch: $(git branch --show-current 2>/dev/null || echo detached)"
242 echo "==> commit: $(git rev-parse --short=8 HEAD 2>/dev/null || echo unknown)"
243 echo "==> platform: $PLATFORM"
244 echo "==> version: $VERSION"
245 echo "==> channel: $CHANNEL"
246 if [[ "$FAST" == "1" ]]; then
247 echo "==> fast mode: DESKTOP_BUILD_CLEAN=$DESKTOP_BUILD_CLEAN DESKTOP_BUILD_SKIP_DMG=$DESKTOP_BUILD_SKIP_DMG"
248 fi
249
250 bash scripts/desktop-build.sh "$PLATFORM" "$VERSION" "$CHANNEL"
251
252 echo "==> restored desktop/wails.json"
253 echo "==> production-style artifacts are in dist/"
254
255 if [[ "$OPEN_DIST" == "1" ]]; then
256 case "$(uname -s)" in
257 Darwin) open dist ;;
258 Linux) command -v xdg-open >/dev/null 2>&1 && xdg-open dist >/dev/null 2>&1 || true ;;
259 MINGW*|MSYS*|CYGWIN*) explorer.exe dist 2>/dev/null || true ;;
260 esac
261 fi
262
262 lines Plain Text