release.sh can build the macOS package too

Cheap for a reason worth stating: the Windows package is already a SOURCE
install - a pure-Python wheel plus a setup tool that builds a venv on the
target machine, because PyInstaller cannot cross-compile. macOS needs
nothing different. Same wheel, same setup tool, a natively built .app in
place of the .exe. No frozen engine, no 200 MB, no second packaging story.

behavision-setup already handled both platforms (Scripts vs bin, the
tasklist check guarded) and cross-compiled for darwin without a change.
The one thing that did not was its advice when Python is missing: it told
everyone to tick 'Add python.exe to PATH' on a Windows installer page.
Software that does not know which machine it is running on is software
somebody stops trusting for the rest of the session.

MAC=1 opts in, so the ordinary Windows release is unchanged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KGcjxF1cNLcuwc3DAPcnfj
This commit is contained in:
2026-09-30 14:50:45 +05:30
parent f5eb2bb124
commit 71008e116a
2 changed files with 49 additions and 6 deletions

View File

@@ -266,10 +266,19 @@ func findPython() (string, string, error) {
}
}
msg := "no Python 3.10 or newer was found on this PC.\n\n" +
" Install it from https://www.python.org/downloads/windows/\n" +
" and tick \"Add python.exe to PATH\" on the first screen,\n" +
" then run this again."
// The advice has to match the machine. Telling a Mac user to tick "Add
// python.exe to PATH" on a Windows installer page reads as software that
// does not know where it is running, which is exactly the moment somebody
// stops trusting the rest of what it says.
msg := "no Python 3.10 or newer was found on this computer.\n\n"
if runtime.GOOS == "windows" {
msg += " Install it from https://www.python.org/downloads/windows/\n" +
" and tick \"Add python.exe to PATH\" on the first screen,\n" +
" then run this again."
} else {
msg += " Install it with `brew install python@3.12`, or from\n" +
" https://www.python.org/downloads/macos/, then run this again."
}
if len(tried) > 0 {
msg += "\n\n Found, but too old: " + strings.Join(tried, ", ")
}

View File

@@ -1,8 +1,9 @@
#!/usr/bin/env bash
# Build the Windows shop-PC package and publish it as a Gitea release.
#
# ./release.sh v0.4.2 build dist/Behavision-v0.4.2-windows-x64.zip and publish
# ./release.sh v0.4.2 build the Windows zip and publish
# PUBLISH=0 ./release.sh v0.4.2 build only
# MAC=1 ./release.sh v0.4.2 also build and attach the macOS zip
# DEMO_PACK=demo-cameras.enc ./release.sh v0.4.4-demo
# a demo build: the sealed bundle from
# behavision-demo-pack ships in engine-src,
@@ -22,6 +23,8 @@ TAG=${1:?usage: release.sh vX.Y.Z}
REPO_API=https://gitapp.workolik.com/api/v1/repos/Loyaly/Behavision
STAGE=dist/Behavision
ZIP="dist/Behavision-$TAG-windows-x64.zip"
MACZIP="dist/Behavision-$TAG-macos-arm64.zip"
MACSTAGE=dist/Behavision-mac
step() { printf '\n\033[1m%s\033[0m\n' "$*"; }
case "$(git describe --tags --always --dirty)" in *-dirty) echo "refusing to release uncommitted changes" >&2; exit 1;; esac
@@ -62,9 +65,39 @@ step "4. Package"
rm -f "$ZIP" && (cd dist && zip -qr "$(basename "$ZIP")" Behavision) && ls -la "$ZIP" | awk '{print " " $5 " bytes " $9}'
unzip -l "$ZIP" | grep -E "Behavision\.exe|agent\.exe|setup\.exe|\.whl|INSTALL" | awk '{print " " $4}'
# --- macOS, same SOURCE-install shape as Windows -------------------------
#
# Worth stating because it is the reason this is cheap: the Windows package
# already ships a pure-Python WHEEL and builds a venv on the target machine,
# because PyInstaller cannot cross-compile. macOS needs nothing different -
# the same wheel, the same setup tool, a natively built .app instead of an
# .exe. No frozen engine, no 200 MB, no second packaging story.
#
# Two things it is NOT, and the release notes should say so:
# * not notarised. macOS blocks an unsigned download outright rather than
# warning like SmartScreen, so the first launch needs right-click > Open.
# Notarising needs an Apple Developer account.
# * arm64 only. Every Mac worth demoing on since 2020, and building a
# universal binary doubles the size for machines nobody here has.
if [ "${MAC:-0}" = "1" ]; then
step "5. macOS package"
command -v wails >/dev/null || { echo "wails CLI not found; go install github.com/wailsapp/wails/v2/cmd/wails@latest" >&2; exit 1; }
rm -rf "$MACSTAGE" && mkdir -p "$MACSTAGE/engine-src"
(cd desktop && wails build -platform darwin/arm64 -tags "desktop,production" -skipbindings >/dev/null)
cp -R desktop/build/bin/Behavision.app "$MACSTAGE/"
(cd agent && CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -trimpath \
-ldflags "-s -w -X main.version=$TAG" -o "../$MACSTAGE/behavision-agent" . \
&& CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -trimpath \
-ldflags "-s -w -X main.version=$TAG" -o "../$MACSTAGE/behavision-setup" ./cmd/behavision-setup)
# The identical engine payload the Windows package carries.
cp -R "$STAGE/engine-src/." "$MACSTAGE/engine-src/"
rm -f "$MACZIP" && (cd dist && zip -qry "$(basename "$MACZIP")" Behavision-mac)
ls -la "$MACZIP" | awk '{print " " $5 " bytes " $9}'
fi
[ "${PUBLISH:-1}" = "1" ] || { echo "built, not published"; exit 0; }
step "5. Tag and publish"
step "6. Tag and publish"
git rev-parse -q --verify "refs/tags/$TAG" >/dev/null || git tag -a "$TAG" -m "$TAG"
git push -q origin "$TAG"
# The notes come from a file so they are reviewed, not typed into a shell.
@@ -77,4 +110,5 @@ BODY=$(python3 -c 'import json,sys;print(json.dumps({"tag_name":sys.argv[1],"nam
REL=$(curl -sS -u "$USER:$PASS" -H 'content-type: application/json' -d "$BODY" "$REPO_API/releases")
ID=$(printf '%s' "$REL" | python3 -c 'import json,sys;print(json.load(sys.stdin)["id"])')
curl -sS -u "$USER:$PASS" -F "attachment=@$ZIP" "$REPO_API/releases/$ID/assets?name=$(basename "$ZIP")" >/dev/null
[ "${MAC:-0}" = "1" ] && curl -sS -u "$USER:$PASS" -F "attachment=@$MACZIP" "$REPO_API/releases/$ID/assets?name=$(basename "$MACZIP")" >/dev/null
echo " published: https://gitapp.workolik.com/Loyaly/Behavision/releases/tag/$TAG"