From 820e7a08fcb76ebbcda8cfca59ef7329a90d94b8 Mon Sep 17 00:00:00 2001 From: sravan Date: Fri, 3 Jul 2026 16:04:22 +0530 Subject: [PATCH] =?UTF-8?q?add=20publish-desktop.sh=20=E2=80=94=20one-comm?= =?UTF-8?q?and=20desktop=20installer=20publish=20from=20laptop?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mirrors redeploy.sh conventions (pinned host key, DEPLOY_PASS/deploy.secret/ prompt password resolution, plink discovery). Uploads the three electron-builder artifacts via pscp to a temp dir, then docker cp's them into the app container's /data/downloads (volume-path-independent), and verifies the public feed serves the new version. Keeps older versions; only latest.yml is overwritten. Co-Authored-By: Claude Opus 4.8 --- publish-desktop.sh | 100 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 publish-desktop.sh diff --git a/publish-desktop.sh b/publish-desktop.sh new file mode 100644 index 0000000..92b3134 --- /dev/null +++ b/publish-desktop.sh @@ -0,0 +1,100 @@ +#!/usr/bin/env bash +# +# publish-desktop.sh — publish a desktop installer FROM YOUR LAPTOP (Git Bash). +# It uploads the three electron-builder artifacts to the server and drops them into +# the app container's DOWNLOADS_DIR (/data/downloads), which powers both the site's +# "Download for Windows" button and the auto-update feed for installed apps. +# +# Uploaded artifacts (from desktop/dist/): +# - Biz Connect Setup .exe the installer +# - Biz Connect Setup .exe.blockmap differential-update map +# - latest.yml update manifest (the ONLY file overwritten) +# +# It does NOT delete older versions — keeping old .exe/.blockmap lets installed apps +# pull deltas. Only latest.yml is replaced (there must be exactly one, newest wins). +# +# Usage: +# ./publish-desktop.sh # publish the version in desktop/package.json +# ./publish-desktop.sh 0.1.4 # publish a specific version +# +# Password (in priority order), same as redeploy.sh: +# 1. $DEPLOY_PASS environment variable +# 2. a gitignored `deploy.secret` file next to this script (one line = the pw) +# 3. hidden prompt +set -euo pipefail + +HOST=118.95.33.89 +PORT=61 +USER=root +CONTAINER=bizgaze-support +DEST=/data/downloads +# Pinned server host key (SHA256). -batch won't prompt to cache an unknown key, so +# we pin it here (same value as redeploy.sh). Override with $DEPLOY_HOSTKEY if the +# server is rebuilt. +HOSTKEY="${DEPLOY_HOSTKEY:-SHA256:hxfv/hH5aplnM4wOsl+jLjWaXwEeceZ4Uz932/5IoCE}" + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DIST="$DIR/desktop/dist" + +# Locate plink + pscp (PuTTY). +PLINK="$(command -v plink 2>/dev/null || true)"; [ -n "$PLINK" ] || PLINK="/c/Program Files/PuTTY/plink" +PSCP="$(command -v pscp 2>/dev/null || true)"; [ -n "$PSCP" ] || PSCP="/c/Program Files/PuTTY/pscp" +[ -x "$PLINK" ] || { echo "ERROR: plink not found (install PuTTY or add to PATH)"; exit 1; } +[ -x "$PSCP" ] || { echo "ERROR: pscp not found (install PuTTY or add to PATH)"; exit 1; } + +# Resolve the version: explicit arg, else desktop/package.json. +VER="${1:-}" +if [ -z "$VER" ]; then + VER="$(grep -oE '"version"[[:space:]]*:[[:space:]]*"[^"]+"' "$DIR/desktop/package.json" | head -1 | sed -E 's/.*"([^"]+)"$/\1/')" +fi +[ -n "$VER" ] || { echo "ERROR: could not determine version (pass it as an argument)"; exit 1; } + +EXE="$DIST/Biz Connect Setup $VER.exe" +MAP="$DIST/Biz Connect Setup $VER.exe.blockmap" +YML="$DIST/latest.yml" +for f in "$EXE" "$MAP" "$YML"; do + [ -f "$f" ] || { echo "ERROR: missing artifact: $f"; echo " build it first: cd desktop && npm run dist"; exit 1; } +done + +# Sanity: latest.yml should reference this version, or installed apps won't update to it. +if ! grep -qE "^version:[[:space:]]*$VER([^0-9]|$)" "$YML"; then + echo "WARNING: $YML does not declare version $VER — is dist/ from an older build?" +fi + +# Resolve password (same precedence as redeploy.sh). +PW="${DEPLOY_PASS:-}" +if [ -z "$PW" ] && [ -f "$DIR/deploy.secret" ]; then + PW="$(tr -d '\r\n' < "$DIR/deploy.secret")" +fi +if [ -z "$PW" ]; then + read -rsp "Server password for $USER@$HOST: " PW; echo +fi + +STAGE="/tmp/bizc-desktop-$VER" + +echo "==> Publishing Biz Connect $VER to $USER@$HOST:$CONTAINER:$DEST" + +# 1. Stage a clean temp dir on the server. +"$PLINK" -ssh -batch -hostkey "$HOSTKEY" -P "$PORT" -pw "$PW" "$USER@$HOST" "rm -rf '$STAGE' && mkdir -p '$STAGE'" + +# 2. Upload the three artifacts into it. +echo "--> uploading installer, blockmap, manifest …" +"$PSCP" -P "$PORT" -pw "$PW" -hostkey "$HOSTKEY" "$EXE" "$MAP" "$YML" "$USER@$HOST:$STAGE/" + +# 3. Copy them into the container's DOWNLOADS_DIR (volume-path-independent), then clean up. +# \$f stays literal so the REMOTE shell iterates/quotes the space-containing names. +REMOTE_CMD="set -e; for f in '$STAGE'/*; do docker cp \"\$f\" $CONTAINER:$DEST/; done; echo '--- $DEST now holds ---'; docker exec $CONTAINER ls -la $DEST; rm -rf '$STAGE'" +echo "--> installing into container …" +"$PLINK" -ssh -batch -hostkey "$HOSTKEY" -P "$PORT" -pw "$PW" "$USER@$HOST" "$REMOTE_CMD" + +# 4. Verify the public feed actually serves this version (GET, not HEAD — the route is GET-only). +echo "==> Verifying public feed …" +if command -v curl >/dev/null 2>&1; then + echo -n " latest.yml -> "; curl -s "https://remote.bizgaze.com/downloads/latest.yml" | grep -E '^version:' || echo "??" + code="$(curl -s -r 0-1 -o /dev/null -w '%{http_code}' -L "https://remote.bizgaze.com/download/windows")" + echo " /download/windows -> HTTP $code (expect 200 or 206)" +else + echo " (curl not found — skip; check https://remote.bizgaze.com/downloads/latest.yml manually)" +fi + +echo "==> Done. Installed 0.x apps will auto-update to $VER on next launch (or within 6h)."