Restore reliable macOS desktop updates (#4322)

* fix(desktop): restore macOS app updates

Electron 41's Squirrel helper can leave the update handoff dormant on current macOS, so Paseo quits cleanly but relaunches the old bundle. Electron 44 wakes ShipIt through its XPC service.

Include updater lifecycle events and ShipIt state in app diagnostics so future handoff failures identify the current version, target version, cache paths, and installer output.

* fix(desktop): harden updater diagnostics

Keep each ShipIt file's evidence available when another read fails, carry the service-selected version into updater lifecycle logs, and make clean workspace installs resolve the Electron runtime used by desktop tests.

* refactor(desktop): name updater install options

* refactor(desktop): name updater log payloads

* refactor(desktop): name clipboard payload

* fix(desktop): surface updater lookup failures

* test(desktop): await guest focus transition

* fix(desktop): guard macOS update compatibility

* test(release): validate desktop manifests before publish

* test(desktop): await populated daemon pid file
This commit is contained in:
Mohamed Boudra
2026-09-04 22:17:39 +02:00
committed by GitHub
parent 35d2457d83
commit 9e90b86afa
32 changed files with 922 additions and 249 deletions
-23
View File
@@ -59,8 +59,6 @@ jobs:
needs: changes
if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.format != 'false') }}
runs-on: ubuntu-latest
env:
ELECTRON_SKIP_BINARY_DOWNLOAD: "1"
steps:
- uses: actions/checkout@v4
@@ -80,8 +78,6 @@ jobs:
needs: changes
if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.quality != 'false') }}
runs-on: ubuntu-latest
env:
ELECTRON_SKIP_BINARY_DOWNLOAD: "1"
steps:
- uses: actions/checkout@v4
@@ -107,8 +103,6 @@ jobs:
needs: changes
if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.quality != 'false') }}
runs-on: ubuntu-latest
env:
ELECTRON_SKIP_BINARY_DOWNLOAD: "1"
steps:
- uses: actions/checkout@v4
@@ -137,8 +131,6 @@ jobs:
needs: changes
if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.server != 'false' || needs.changes.outputs.hub != 'false') }}
runs-on: ubuntu-latest
env:
ELECTRON_SKIP_BINARY_DOWNLOAD: "1"
steps: &server_test_steps
- uses: actions/checkout@v4
with:
@@ -180,8 +172,6 @@ jobs:
needs: changes
if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.server != 'false' || needs.changes.outputs.hub != 'false') }}
runs-on: windows-latest
env:
ELECTRON_SKIP_BINARY_DOWNLOAD: "1"
steps: *server_test_steps
desktop-tests-ubuntu:
@@ -268,8 +258,6 @@ jobs:
needs: changes
if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.app != 'false') }}
runs-on: ubuntu-latest
env:
ELECTRON_SKIP_BINARY_DOWNLOAD: "1"
steps:
- uses: actions/checkout@v4
@@ -296,8 +284,6 @@ jobs:
needs: changes
if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.sdk != 'false') }}
runs-on: ubuntu-latest
env:
ELECTRON_SKIP_BINARY_DOWNLOAD: "1"
steps:
- uses: actions/checkout@v4
@@ -330,7 +316,6 @@ jobs:
if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.browser != 'false') }}
runs-on: ubuntu-latest
env:
ELECTRON_SKIP_BINARY_DOWNLOAD: "1"
PLAYWRIGHT_SHARD: "1/4"
PLAYWRIGHT_ARTIFACT: "1"
steps: &playwright_test_steps
@@ -378,7 +363,6 @@ jobs:
if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.browser != 'false') }}
runs-on: ubuntu-latest
env:
ELECTRON_SKIP_BINARY_DOWNLOAD: "1"
PLAYWRIGHT_SHARD: "2/4"
PLAYWRIGHT_ARTIFACT: "2"
steps: *playwright_test_steps
@@ -389,7 +373,6 @@ jobs:
if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.browser != 'false') }}
runs-on: ubuntu-latest
env:
ELECTRON_SKIP_BINARY_DOWNLOAD: "1"
PLAYWRIGHT_SHARD: "3/4"
PLAYWRIGHT_ARTIFACT: "3"
steps: *playwright_test_steps
@@ -400,7 +383,6 @@ jobs:
if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.browser != 'false') }}
runs-on: ubuntu-latest
env:
ELECTRON_SKIP_BINARY_DOWNLOAD: "1"
PLAYWRIGHT_SHARD: "4/4"
PLAYWRIGHT_ARTIFACT: "4"
steps: *playwright_test_steps
@@ -410,8 +392,6 @@ jobs:
needs: changes
if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.relay != 'false') }}
runs-on: ubuntu-latest
env:
ELECTRON_SKIP_BINARY_DOWNLOAD: "1"
steps:
- uses: actions/checkout@v4
@@ -435,7 +415,6 @@ jobs:
if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.cli != 'false') }}
runs-on: ubuntu-latest
env:
ELECTRON_SKIP_BINARY_DOWNLOAD: "1"
PASEO_LOCAL_SPEECH_AUTO_DOWNLOAD: "0"
PASEO_DICTATION_ENABLED: "0"
PASEO_VOICE_MODE_ENABLED: "0"
@@ -467,7 +446,6 @@ jobs:
if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.cli != 'false') }}
runs-on: ubuntu-latest
env:
ELECTRON_SKIP_BINARY_DOWNLOAD: "1"
PASEO_LOCAL_SPEECH_AUTO_DOWNLOAD: "0"
PASEO_DICTATION_ENABLED: "0"
PASEO_VOICE_MODE_ENABLED: "0"
@@ -481,7 +459,6 @@ jobs:
if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.cli != 'false') }}
runs-on: ubuntu-latest
env:
ELECTRON_SKIP_BINARY_DOWNLOAD: "1"
PASEO_LOCAL_SPEECH_AUTO_DOWNLOAD: "0"
PASEO_DICTATION_ENABLED: "0"
PASEO_VOICE_MODE_ENABLED: "0"
+4 -22
View File
@@ -547,28 +547,10 @@ jobs:
fi
timestamp="$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")"
node ../scripts/stamp-rollout.mjs --release-date "$timestamp" --rollout-hours "$ROLLOUT_HOURS" "${files[@]}"
# shellcheck disable=SC2016
ROLLOUT_HOURS_EXPECTED="$ROLLOUT_HOURS" RELEASE_DATE_EXPECTED="$timestamp" node -e '
const yaml = require("js-yaml");
const fs = require("fs");
const expectedHours = Number(process.env.ROLLOUT_HOURS_EXPECTED);
const expectedDate = process.env.RELEASE_DATE_EXPECTED;
if (!Number.isFinite(expectedHours) || expectedHours < 0) {
throw new Error(`expected non-negative rolloutHours, got ${process.env.ROLLOUT_HOURS_EXPECTED}`);
}
for (const f of process.argv.slice(1)) {
const m = yaml.load(fs.readFileSync(f, "utf8")) ?? {};
if (m.rolloutHours !== expectedHours) {
throw new Error(`${f}: rolloutHours=${m.rolloutHours}, expected ${expectedHours}`);
}
if (m.releaseDate !== expectedDate) {
throw new Error(`${f}: releaseDate=${m.releaseDate}, expected ${expectedDate}`);
}
if (typeof m.version !== "string" || m.version.length === 0) {
throw new Error(`${f}: missing or invalid version`);
}
}
' "${files[@]}"
node ../scripts/validate-desktop-manifests.mjs \
--release-date "$timestamp" \
--rollout-hours "$ROLLOUT_HOURS" \
"${files[@]}"
gh release upload "$release_lookup" "${files[@]}" --clobber --repo "${{ github.repository }}"
failed_builds=()