deploy: publish darwin builds for the website's try flow (#1105)
The self-host page's try snippet handed every visitor lchat-linux-amd64 —
exec format error on a Mac (and wrong on arm64 linux). Publish now also
builds lchat-darwin-{arm64,amd64}; promote-stable refreshes them on the
rolling release beside the linux pair. The channel manifest and the fleet
stay linux-only.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
3 files changed,
+30
−12
deploy/build-linux.sh+6 −4deploy/release-server.sh+16 −3docs/server-releases.md+8 −5
diff --git a/deploy/build-linux.sh b/deploy/build-linux.sh| index 7bf40e5..c3473b0 100755 |
| --- a/deploy/build-linux.sh |
| +++ b/deploy/build-linux.sh |
| @@ -3,9 +3,10 @@ |
| # (the git short sha, or $1) so `lchat stage`/`deploy --version` can identify and |
| # health-check it. Prints the build id and the output path. |
| # |
| -# ./deploy/build-linux.sh # amd64, id = git short sha |
| +# ./deploy/build-linux.sh # linux/amd64, id = git short sha |
| # ./deploy/build-linux.sh test-scroll # id = test-scroll (e.g. a canary label) |
| # ARCH=arm64 ./deploy/build-linux.sh # linux/arm64 (self-hosters on ARM) |
| +# OS=darwin ARCH=arm64 ./deploy/build-linux.sh # macOS (the `lchat try` download) |
| # OUT=/tmp/lchat ./deploy/build-linux.sh |
| set -eu |
| @@ -14,10 +15,11 @@ if [ -z "$VER" ]; then |
| echo "build-linux: could not determine a build id (pass one as \$1)" >&2 |
| exit 1 |
| fi |
| +OS="${OS:-linux}" |
| ARCH="${ARCH:-amd64}" |
| -OUT="${OUT:-lchat-linux-$ARCH}" |
| +OUT="${OUT:-lchat-$OS-$ARCH}" |
| -GOOS=linux GOARCH="$ARCH" CGO_ENABLED=0 \ |
| +GOOS="$OS" GOARCH="$ARCH" CGO_ENABLED=0 \ |
| go build -ldflags "-X main.buildVersion=${VER}" -o "$OUT" . |
| -echo "built ${VER} (${ARCH}) -> ${OUT}" |
| +echo "built ${VER} (${OS}/${ARCH}) -> ${OUT}" |
diff --git a/deploy/release-server.sh b/deploy/release-server.sh| index 6ea0e2d..f35ddd4 100755 |
| --- a/deploy/release-server.sh |
| +++ b/deploy/release-server.sh |
| @@ -47,6 +47,11 @@ KEY="${LCHAT_RELEASE_KEY_FILE:-}" |
| MIRROR_BUCKET="${LCHAT_RELEASE_MIRROR_BUCKET:-}" |
| BIN=lchat-linux-amd64 |
| BIN_ARM=lchat-linux-arm64 |
| +# The darwin builds exist for the website's `lchat try` download (Macs hit |
| +# "exec format error" on a linux binary) — the fleet and the channel manifest |
| +# stay linux-only; these just ride the releases as extra assets. |
| +BIN_MAC=lchat-darwin-arm64 |
| +BIN_MAC_X64=lchat-darwin-amd64 |
| TMP="$(mktemp -d)" |
| trap 'rm -rf "$TMP"' EXIT |
| @@ -125,12 +130,17 @@ publish) |
| OUT="$TMP/$BIN" ./deploy/build-linux.sh "$VER" |
| ARCH=arm64 OUT="$TMP/$BIN_ARM" ./deploy/build-linux.sh "$VER" |
| + OS=darwin ARCH=arm64 OUT="$TMP/$BIN_MAC" ./deploy/build-linux.sh "$VER" |
| + OS=darwin ARCH=amd64 OUT="$TMP/$BIN_MAC_X64" ./deploy/build-linux.sh "$VER" |
| SHA="$(shasum -a 256 "$TMP/$BIN" | cut -d' ' -f1)" |
| SIZE="$(wc -c < "$TMP/$BIN" | tr -d ' ')" |
| SHA_ARM="$(shasum -a 256 "$TMP/$BIN_ARM" | cut -d' ' -f1)" |
| SIZE_ARM="$(wc -c < "$TMP/$BIN_ARM" | tr -d ' ')" |
| echo "$SHA $BIN" > "$TMP/$BIN.sha256" |
| echo "$SHA_ARM $BIN_ARM" > "$TMP/$BIN_ARM.sha256" |
| + for M in "$BIN_MAC" "$BIN_MAC_X64"; do |
| + echo "$(shasum -a 256 "$TMP/$M" | cut -d' ' -f1) $M" > "$TMP/$M.sha256" |
| + done |
| if gh release view "server-$VER" -R "$REPO" >/dev/null 2>&1; then |
| echo "release-server: server-$VER already exists on $REPO (promote it, or land a new commit)" >&2; exit 1 |
| @@ -141,12 +151,14 @@ publish) |
| # server publish was silently 404ing every Mac's update check (found |
| # 2026-07-14: the feed pointed at server-414bdeb0, no appcast there). |
| gh release create "server-$VER" -R "$REPO" --title "Server $VER" --notes "$NOTES" --latest=false \ |
| - "$TMP/$BIN" "$TMP/$BIN.sha256" "$TMP/$BIN_ARM" "$TMP/$BIN_ARM.sha256" |
| + "$TMP/$BIN" "$TMP/$BIN.sha256" "$TMP/$BIN_ARM" "$TMP/$BIN_ARM.sha256" \ |
| + "$TMP/$BIN_MAC" "$TMP/$BIN_MAC.sha256" "$TMP/$BIN_MAC_X64" "$TMP/$BIN_MAC_X64.sha256" |
| # Binaries mirror before the manifest that points at them, so the mirror |
| # never serves a feed whose mirror-side binaries don't exist yet. Keys copy |
| # the GitHub layout (server-<ver>/<asset>) — that's what the updater's |
| # mirror fallback derives from a primary binary URL. |
| - for A in "$BIN" "$BIN.sha256" "$BIN_ARM" "$BIN_ARM.sha256"; do |
| + for A in "$BIN" "$BIN.sha256" "$BIN_ARM" "$BIN_ARM.sha256" \ |
| + "$BIN_MAC" "$BIN_MAC.sha256" "$BIN_MAC_X64" "$BIN_MAC_X64.sha256"; do |
| mirror_upload "$TMP/$A" "server-$VER/$A" |
| done |
| @@ -227,7 +239,8 @@ promote) |
| # fixed, JSON-free URLs deploy/install.sh downloads. |
| if [ "$CHAN" = stable ]; then |
| mkdir -p "$TMP/stable" |
| - for A in "$BIN" "$BIN.sha256" "$BIN_ARM" "$BIN_ARM.sha256"; do |
| + for A in "$BIN" "$BIN.sha256" "$BIN_ARM" "$BIN_ARM.sha256" \ |
| + "$BIN_MAC" "$BIN_MAC.sha256" "$BIN_MAC_X64" "$BIN_MAC_X64.sha256"; do |
| if gh release download "server-$VER" -R "$REPO" -p "$A" -O "$TMP/stable/$A" 2>/dev/null; then |
| gh release upload server "$TMP/stable/$A" -R "$REPO" --clobber |
| else |
diff --git a/docs/server-releases.md b/docs/server-releases.md| index 90c2caf..1843262 100644 |
| --- a/docs/server-releases.md |
| +++ b/docs/server-releases.md |
| @@ -16,8 +16,10 @@ app's Sparkle appcast uses, see `ios/release-mac.sh`): |
| - **One release per build**: tag `server-<ver>` (ver = the git short sha that |
| `deploy/build-linux.sh` stamps into the binary as `main.buildVersion`), |
| - carrying **both architectures** — `lchat-linux-amd64` and `lchat-linux-arm64`, |
| - each with its `.sha256`. |
| + carrying **both linux architectures** — `lchat-linux-amd64` and |
| + `lchat-linux-arm64` — plus `lchat-darwin-{arm64,amd64}` (the website's |
| + `lchat try` download for Macs; never referenced by the manifest), each with |
| + its `.sha256`. |
| - **One rolling release**: tag `server`, whose assets live at fixed URLs |
| (re-uploaded with `--clobber`, so the URLs never change): |
| - `manifest.json` — the **feed**, updated on every publish/promote: |
| @@ -25,9 +27,10 @@ app's Sparkle appcast uses, see `ios/release-mac.sh`): |
| ``` |
| https://github.com/elevenmessenger/releases/releases/download/server/manifest.json |
| ``` |
| - - `lchat-linux-{amd64,arm64}` (+ `.sha256`) — copies of the current |
| - **stable** binaries, refreshed by `promote … stable`. These JSON-free URLs |
| - are what `deploy/install.sh` downloads. |
| + - `lchat-linux-{amd64,arm64}` and `lchat-darwin-{arm64,amd64}` |
| + (+ `.sha256`) — copies of the current **stable** binaries, refreshed by |
| + `promote … stable`. These JSON-free URLs are what `deploy/install.sh` |
| + (linux) and the website's try snippet (any OS) download. |
| - `install.sh` — the self-hoster installer, refreshed on every publish. |
| - **The releases repo README** is the public self-hosting guide — synced from |
| `docs/self-hosting.md` on every publish (this source repo is private, so the |