Skip to content
This repository was archived by the owner on Aug 6, 2026. It is now read-only.

test(updates): macOS auto-update E2E test pipeline with real install + relaunch - #2828

Merged
charlesvien merged 22 commits into
mainfrom
test/macos-auto-update-e2e
Jun 30, 2026
Merged

test(updates): macOS auto-update E2E test pipeline with real install + relaunch#2828
charlesvien merged 22 commits into
mainfrom
test/macos-auto-update-e2e

Conversation

@charlesvien

@charlesviencharlesvien commented Jun 22, 2026

Copy link
Copy Markdown
Member

Problem

The electron-builder + electron-updater migration gave us a real auto-update path (download, install, relaunch), but nothing tests it end to end.

Changes

Two tiny test-gated hooks in the main process, both inert unless POSTHOG_E2E_UPDATE_FEED is set (no production behavior change):

  • electron-updater.ts points the updater at a local feed via setFeedURL. disableDifferentialDownload, autoDownload, autoInstallOnAppQuit and isSupported are untouched.
  • main/index.ts exposes globalThis.__e2eUpdates (check/download/install/status) wired to the real UpdatesService.

Harness:

  • scripts/dev-update/serve.mjs: dependency-free, range-capable static feed server.
  • scripts/dev-update/build-pair.sh: builds a signed 2.0.0 feed and a runnable signed 1.0.0 app (SKIP_NOTARIZE=1).
  • tests/e2e/fixtures/update.ts: ditto run-copy so a retry restarts from 1.0.0, plist version read, pkill helpers.
  • tests/e2e/tests/update.spec.ts: phase 1 drives download then install via the main-process hook; phase 2 waits for the on-disk bundle to swap, kills the auto-relaunched instance, then fresh-launches and asserts app.getVersion() is 2.0.0.

CI: a dedicated code-update-e2e.yml, macOS only, reusing the existing build-macos steps and Apple signing secrets. It is not on the PR gate (nightly + workflow_dispatch); a temporary push trigger on this branch lets it run on the PR and is meant to be removed before merge.

The swap is signature-gated (Squirrel.Mac matches the designated requirement), which is why this runs in CI where the signing cert is present rather than as a local unit test. Notarization is skipped on purpose: it is a Gatekeeper concern, not what the in-place update verifies.

How did you test this?

Ran locally:

  • pnpm --filter code typecheck passes with the hooks.
  • Biome clean on all new and changed files.
  • node --check serve.mjs and bash -n build-pair.sh pass.
  • The e2e tsconfig typechecks the two new e2e files (the only errors are pre-existing in smoke.spec.ts).

Not run locally: the full signed build plus end-to-end swap (two signed mac builds, needs the Developer ID cert). That runs in the new workflow on this branch via the temporary push trigger, which is the real validation.

Automatic notifications

  • Publish to changelog?
  • Alert Sales and Marketing teams?

@github-actions

github-actionsBot commented Jun 22, 2026

Copy link
Copy Markdown

React Doctor found no issues in the changed files. 🎉

Reviewed by React Doctor for commit 460340d.

@greptile-apps

Copy link
Copy Markdown
Contributor
Prompt To Fix All With AI
Fix the following 3 code review issues. Work through them one at a time, proposing concise fixes.
---### Issue 1 of 3
.github/workflows/code-update-e2e.yml:10-14
**Temporary push trigger not removed before merge**
The PR description explicitly states this push trigger "is meant to be removed before merge." It's still present. If the source branch (`test/macos-auto-update-e2e`) continues to exist in the repo after the merge, any future push to it will fire this workflow — which runs two full signed macOS builds and exercises the real install. That's expensive (and confusing) for what should be a nightly-only job.
### Issue 2 of 3
apps/code/tests/e2e/tests/update.spec.ts:63-130
**`app` and `updated` not closed in finally**
If `pollStatus` for check/download times out (phase 1 fails), the `app` Electron process is left running — only `feed.kill()` is in the `finally` block. Similarly, if the `expect(version).toBe(NEW_VERSION)` assertion at line 126 fails, `updated` is leaked. Playwright does not automatically close `electron.launch()` instances on test failure. Adding `app.close().catch(() => {})` / `updated.close().catch(() => {})` to the `finally` block (tracked via `let app` / `let updated` in outer scope) would prevent stale processes from interfering with a retry.
### Issue 3 of 3
apps/code/scripts/dev-update/serve.mjs:50-52
**Suffix-range requests (`bytes=-N`) compute wrong offsets**
When the range header is `bytes=-500` (last 500 bytes), the regex captures `match[1] = ""` and `match[2] = "500"`. Because `""` is falsy, `start` is set to `0` instead of `stat.size - 500`, so the response sends the wrong slice of the file. The electron-updater differential/blockmap code can emit suffix ranges during verification. In practice `electron-updater` on this path likely uses open-ended ranges (`bytes=0-`), but a defensive fix would be: `const start = match?.[1] ? Number(match[1]) : match?.[2] ? stat.size - Number(match[2]) : 0`.

Reviews (1): Last reviewed commit: "add macos auto-update e2e harness and ci" | Re-trigger Greptile

Comment thread.github/workflows/code-update-e2e.yml
Comment threadapps/code/tests/e2e/tests/update.spec.ts
Comment threadapps/code/scripts/dev-update/serve.mjs Outdated
@charlesviencharlesvien added the Stamphog This will request an autostamp by stamphog on small changes label Jun 22, 2026

@stamphogstamphogBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gates denied because this PR adds a new CI/CD workflow file (.github/workflows/code-update-e2e.yml), which is on the infra/CI deny-list and requires human review. Additionally, there are unresolved bot comments flagging a push trigger that was explicitly noted for removal before merge but wasn't removed, and a functional bug in the range-request handling in serve.mjs.

@stamphogstamphogBot removed the Stamphog This will request an autostamp by stamphog on small changes label Jun 22, 2026
@charlesvien
charlesvienforce-pushed the test/macos-auto-update-e2e branch 5 times, most recently from 817d137 to 8257a56CompareJune 22, 2026 15:32
@charlesvien
charlesvienforce-pushed the feat/auto-update-ux branch 2 times, most recently from 482f3bf to 2edb0b3CompareJune 22, 2026 18:25
@charlesvien
charlesvienforce-pushed the test/macos-auto-update-e2e branch from 8257a56 to 80378acCompareJune 22, 2026 18:25
@charlesvien
charlesvienforce-pushed the test/macos-auto-update-e2e branch 2 times, most recently from 0cba398 to 743a6d9CompareJune 23, 2026 22:06
@charlesviencharlesvien changed the title test(updates): macOS auto-update E2E with real install + relaunchtest(updates): macOS auto-update E2E test pipeline with real install + relaunchJun 24, 2026
@charlesvien
charlesvienforce-pushed the test/macos-auto-update-e2e branch 2 times, most recently from 54e345f to cb8861aCompareJune 24, 2026 02:24
@charlesvien
charlesvien changed the base branch from feat/auto-update-ux to graphite-base/2828June 30, 2026 04:40
@charlesvien
charlesvienforce-pushed the test/macos-auto-update-e2e branch from 02ea609 to ce9a5d8CompareJune 30, 2026 04:41
@graphite-app
graphite-appBot changed the base branch from graphite-base/2828 to mainJune 30, 2026 04:41
@charlesvien
charlesvienforce-pushed the test/macos-auto-update-e2e branch from ce9a5d8 to 82c4776CompareJune 30, 2026 04:41
@charlesvien
charlesvien merged commit 8f2c339 into mainJun 30, 2026
25 checks passed
@charlesvien
charlesvien deleted the test/macos-auto-update-e2e branch June 30, 2026 05:09
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@charlesvien@tatoalo