diff --git a/.github/workflows/review-desktop-update-smoke.yml b/.github/workflows/review-desktop-update-smoke.yml deleted file mode 100644 index cf0791e0f..000000000 --- a/.github/workflows/review-desktop-update-smoke.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: Review Desktop Update Smoke - -# Proves a published build updates in place on macOS: each job runs one -# starting build from a throwaway folder, lets Squirrel install the channel's -# current release, and checks the bundle kept its folder name. One job per -# update zip, so both a pre-rename (Review) and a renamed (Whiteboard) install -# are covered. Runners are separate machines, so their Squirrel state is too. - -on: - workflow_dispatch: - inputs: - quality: - description: "Channel whose current release the build should update to" - type: choice - options: - - preview - - stable - default: preview - from_version: - description: "Published version to start from, e.g. 0.0.34-preview.20260924.59 (must be older than the channel's current release)" - required: true - type: string - -permissions: - contents: read - -jobs: - update: - name: ${{ matrix.artifact }} zip → current ${{ inputs.quality }} - runs-on: macos-15 - timeout-minutes: 30 - strategy: - fail-fast: false - matrix: - artifact: [Review, Whiteboard] - steps: - - name: Checkout - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 - with: - sparse-checkout: apps/review-desktop/scripts - - name: Update in place - run: | - chmod +x apps/review-desktop/scripts/update-smoke.sh - apps/review-desktop/scripts/update-smoke.sh "${{ inputs.quality }}" "${{ inputs.from_version }}" "${{ matrix.artifact }}" - - name: Keep the app and installer logs - if: always() - run: | - mkdir -p logs - cp "$RUNNER_TEMP"/update-smoke-*/app.stderr logs/ 2>/dev/null || true - cp "$HOME"/Library/Caches/dev.fast.review*.ShipIt/ShipIt_stderr.log logs/ 2>/dev/null || true - find "$RUNNER_TEMP"/update-smoke-*/state/user-data/logs -name main.log -exec cp {} logs/ \; 2>/dev/null || true - - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 - if: always() - with: - name: update-smoke-${{ inputs.quality }}-${{ matrix.artifact }} - path: logs - if-no-files-found: ignore - retention-days: 3 diff --git a/apps/review-desktop/scripts/update-smoke.sh b/apps/review-desktop/scripts/update-smoke.sh deleted file mode 100755 index 9065fb46c..000000000 --- a/apps/review-desktop/scripts/update-smoke.sh +++ /dev/null @@ -1,88 +0,0 @@ -#!/usr/bin/env bash -# Prove a published build updates in place: run it from a throwaway folder, -# let Squirrel download and install the channel's current release, then check -# that the bundle folder kept its name and carries the new version. -# -# update-smoke.sh -# -# The third argument picks which update zip the starting build came from, so -# the folder is named like an install that predates or postdates the rename. -# Squirrel state is keyed by bundle id, so never run this beside a Desktop of -# the same channel. -set -euo pipefail - -QUALITY="$1"; FROM_VERSION="$2"; ARTIFACT="$3" -APP_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)" -WORK="${RUNNER_TEMP:-${TMPDIR:-/tmp}}/update-smoke-$ARTIFACT" -UPDATE_URL="https://update.dev.fast" - -FOLDER="$(node "$APP_DIR/scripts/release-channel.mjs" "$QUALITY" | awk -F'\t' -v a="$ARTIFACT" '$2 == a { print $1 }')" -[[ -n "$FOLDER" ]] || { echo "no $ARTIFACT zip in the $QUALITY channel" >&2; exit 2; } -case "$QUALITY" in - stable) BUNDLE_ID="dev.fast.review" ;; - preview) BUNDLE_ID="dev.fast.review.preview" ;; -esac -SHIPIT="$HOME/Library/Caches/$BUNDLE_ID.ShipIt" -FEED="$UPDATE_URL/api/update/darwin-arm64/$QUALITY/0000000000000000000000000000000000000000" - -if pgrep -f "/Contents/MacOS/" | xargs -I{} ps -o command= -p {} 2>/dev/null | grep -q "$BUNDLE_ID\|$FOLDER.app"; then - echo "a $QUALITY Desktop is already running; Squirrel state is shared by bundle id" >&2 - exit 1 -fi - -rm -rf "$WORK"; mkdir -p "$WORK/app" "$WORK/state/user-data" "$WORK/state/extensions" "$WORK/home" -ZIP="$ARTIFACT-darwin-arm64-$FROM_VERSION.zip" -echo "Downloading $ZIP" -curl -fsSLo "$WORK/$ZIP" "$UPDATE_URL/releases/$FROM_VERSION/darwin-arm64/$ZIP" -ditto -x -k "$WORK/$ZIP" "$WORK/app" -APP="$WORK/app/$FOLDER.app" -[[ -d "$APP" ]] || { echo "$ZIP did not unpack to $FOLDER.app:"; ls "$WORK/app"; exit 1; } -EXECUTABLE="$(defaults read "$APP/Contents/Info.plist" CFBundleExecutable)" -BEFORE="$(node -p "require('$APP/Contents/Resources/app/product.json').reviewVersion")" - -EXPECTED="$(curl -fsS "$FEED?bundle=$(printf %s "$FOLDER" | sed 's/ /%20/g')" | node -p "JSON.parse(require('fs').readFileSync(0, 'utf8')).productVersion")" -echo "Starting from $FOLDER.app ($BEFORE); the feed offers $EXPECTED" -[[ "$BEFORE" != "$EXPECTED" ]] || { echo "nothing to update to; publish a newer $QUALITY build first" >&2; exit 2; } - -mkdir -p "$SHIPIT"; touch "$SHIPIT/ShipIt_stderr.log" -LOG_START="$(wc -l < "$SHIPIT/ShipIt_stderr.log")" -TARGET_URL="file://$APP/" - -DEV_REVIEW_HOME="$WORK/home" DEV_REVIEW_IMPORT_FROM=none ELECTRON_ENABLE_LOGGING=1 \ - "$APP/Contents/MacOS/$EXECUTABLE" \ - "--user-data-dir=$WORK/state/user-data" "--extensions-dir=$WORK/state/extensions" \ - >"$WORK/app.stdout" 2>"$WORK/app.stderr" & -PID=$! - -# Squirrel writes its install request once the download is verified. The -# first check runs 30 s after launch; the zip is a few hundred megabytes. -for _ in $(seq 1 90); do - if plutil -p "$SHIPIT/ShipItState.plist" 2>/dev/null | grep -qF "$(printf %s "$TARGET_URL" | sed 's/ /%20/g')"; then - break - fi - kill -0 "$PID" 2>/dev/null || { echo "app exited early"; tail -20 "$WORK/app.stderr"; exit 1; } - sleep 5 -done -if ! plutil -p "$SHIPIT/ShipItState.plist" 2>/dev/null | grep -qF "$(printf %s "$TARGET_URL" | sed 's/ /%20/g')"; then - echo "Squirrel never staged an update for $APP" >&2 - grep -h -i "update" "$WORK"/state/user-data/logs/*/main.log 2>/dev/null | tail -30 >&2 - exit 1 -fi -echo "Squirrel staged:"; plutil -p "$SHIPIT/ShipItState.plist" | grep -E "BundleURL|useUpdateBundleName" | sed 's/^/ /' - -# Squirrel installs when the app exits, however it exits. -kill -TERM "$PID"; sleep 15; kill -KILL "$PID" 2>/dev/null || true; wait "$PID" 2>/dev/null || true -for _ in $(seq 1 60); do - tail -n +"$((LOG_START + 1))" "$SHIPIT/ShipIt_stderr.log" | grep -q -E "Installation completed|Installation error" && break - sleep 2 -done -echo "ShipIt:"; tail -n +"$((LOG_START + 1))" "$SHIPIT/ShipIt_stderr.log" | grep -E "Beginning|Installation|error" | sed 's/^/ /' - -BUNDLES="$(find "$WORK/app" -mindepth 1 -maxdepth 1)" -echo "On disk:"; echo "$BUNDLES" | sed 's/^/ /' -[[ -d "$APP" ]] || { echo "FAIL: $FOLDER.app is gone; the install renamed it" >&2; exit 1; } -[[ "$(echo "$BUNDLES" | wc -l)" -eq 1 ]] || { echo "FAIL: more than one bundle in the folder" >&2; exit 1; } -AFTER="$(node -p "require('$APP/Contents/Resources/app/product.json').reviewVersion")" -[[ "$AFTER" == "$EXPECTED" ]] || { echo "FAIL: $FOLDER.app is at $AFTER, expected $EXPECTED" >&2; exit 1; } -tail -n +"$((LOG_START + 1))" "$SHIPIT/ShipIt_stderr.log" | grep -q "Installation completed successfully" || { echo "FAIL: ShipIt did not report success" >&2; exit 1; } -echo "PASS: $FOLDER.app went from $BEFORE to $AFTER in place"