Skip to content

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

Open
charlesvien wants to merge 14 commits into
feat/auto-update-uxfrom
test/macos-auto-update-e2e
Open

test(updates): macOS auto-update E2E test pipeline with real install + relaunch#2828
charlesvien wants to merge 14 commits into
feat/auto-update-uxfrom
test/macos-auto-update-e2e

Conversation

@charlesvien

@charlesvien charlesvien 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-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown

React Doctor found no issues in the changed files. 🎉

Reviewed by React Doctor for commit cb8861a.

@greptile-apps

greptile-apps Bot commented Jun 22, 2026

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 thread apps/code/tests/e2e/tests/update.spec.ts
Comment thread apps/code/scripts/dev-update/serve.mjs Outdated

charlesvien commented Jun 22, 2026

Copy link
Copy Markdown
Member Author

@charlesvien charlesvien added the Stamphog This will request an autostamp by stamphog on small changes label Jun 22, 2026

@stamphog stamphog Bot 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.

@stamphog stamphog Bot removed the Stamphog This will request an autostamp by stamphog on small changes label Jun 22, 2026
@charlesvien charlesvien force-pushed the test/macos-auto-update-e2e branch 5 times, most recently from 817d137 to 8257a56 Compare June 22, 2026 15:32
@charlesvien charlesvien force-pushed the feat/auto-update-ux branch 2 times, most recently from 482f3bf to 2edb0b3 Compare June 22, 2026 18:25
@charlesvien charlesvien force-pushed the test/macos-auto-update-e2e branch from 8257a56 to 80378ac Compare June 22, 2026 18:25
@charlesvien charlesvien force-pushed the feat/auto-update-ux branch from 2edb0b3 to a0d7442 Compare June 23, 2026 05:54
@charlesvien charlesvien force-pushed the test/macos-auto-update-e2e branch 2 times, most recently from 0cba398 to 743a6d9 Compare June 23, 2026 22:06
@charlesvien charlesvien force-pushed the feat/auto-update-ux branch from a0d7442 to 3a289ce Compare June 23, 2026 22:06
@charlesvien charlesvien changed the title test(updates): macOS auto-update E2E with real install + relaunch test(updates): macOS auto-update E2E test pipeline with real install + relaunch Jun 24, 2026
@charlesvien charlesvien force-pushed the feat/auto-update-ux branch from 3a289ce to e76978c Compare June 24, 2026 01:20
@charlesvien charlesvien force-pushed the test/macos-auto-update-e2e branch from 743a6d9 to 51ac970 Compare June 24, 2026 01:20
@charlesvien charlesvien force-pushed the test/macos-auto-update-e2e branch from 54e345f to cb8861a Compare June 24, 2026 02:24
@charlesvien charlesvien force-pushed the feat/auto-update-ux branch from e76978c to 9d9204f Compare June 24, 2026 02:24
@charlesvien charlesvien added the Stamphog This will request an autostamp by stamphog on small changes label Jun 24, 2026

@stamphog stamphog Bot 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 due to a new CI/CD workflow file, which requires human review. Additionally, there are unresolved substantive issues: a push trigger that was explicitly noted for removal before merge remains present, and a functional bug in suffix-range request handling in serve.mjs that could cause incorrect file slices during update verification.

@stamphog stamphog Bot removed the Stamphog This will request an autostamp by stamphog on small changes label Jun 24, 2026
Comment on lines +10 to +13
# Temporary: also run on this branch so the harness can be exercised on the PR.
# Remove this push trigger once merged; nightly + dispatch is the steady state.
# Docs and the local-only run-from-ci helper do not affect CI, so skip rebuilds
# for those and use workflow_dispatch / the nightly schedule on demand instead.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

so we need to remove this then right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants