diff --git a/agent/cmd/behavision-setup/main.go b/agent/cmd/behavision-setup/main.go index 003ce44..5cd4996 100644 --- a/agent/cmd/behavision-setup/main.go +++ b/agent/cmd/behavision-setup/main.go @@ -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, ", ") } diff --git a/release.sh b/release.sh index 0e3e865..5fb1d1e 100755 --- a/release.sh +++ b/release.sh @@ -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"