Files
openwork/scripts/migration/README.md
ben 7a53c2964c feat(desktop): Tauri → Electron migration release kit (#1526)
Ships the last-missing piece of the Electron migration. After this PR
merges there are three one-shot scripts under scripts/migration/ that
carry the whole lifecycle from "cut v0.12.0" through "delete src-tauri":

  01-cut-migration-release.mjs   # bumps versions, writes the release env
                                 # fragment, tags, pushes.
  02-validate-migration.mjs      # guided smoke test against a cut release.
  03-post-migration-cleanup.mjs  # deletes src-tauri, flips defaults,
                                 # scrubs Tauri docs (dry-run by default).

Code landing in the same PR (dormant until a release sets
VITE_OPENWORK_MIGRATION_RELEASE=1):

- apps/desktop/src-tauri/src/commands/migration.rs gains
  migrate_to_electron() — downloads the matching Electron .zip, verifies
  the Apple signature, swaps the .app bundle in place via a detached
  shell script, relaunches, and exits. Windows + Linux branches are
  stubbed with clear TODOs for the follow-up.
- apps/app/src/app/lib/migration.ts grows migrateToElectron() + a
  "later" defer helper.
- apps/app/src/react-app/shell/migration-prompt.tsx adds the one-time
  "OpenWork is moving to a new engine" modal. Mounted from
  providers.tsx. Gated on isTauriRuntime() AND the build-time flag, so
  Electron users and all non-migration-release builds never render it.
- apps/app/vite.config.ts loads apps/app/.env.migration-release when
  present so the prompt gets the release-specific download URLs.
- .gitignore allows the migration-release fragment to be committed only
  on the tagged migration-release commit (removed in cleanup step).

Release workflow:
- .github/workflows/release-macos-aarch64.yml gains a publish-electron
  job alongside the Tauri jobs. Gated on RELEASE_PUBLISH_ELECTRON repo
  var OR the new publish_electron workflow_dispatch input (default
  false). Uses the existing Apple Dev ID secrets — no new credential
  story. Produces latest-mac.yml alongside Tauri's latest.json so a
  v0.12.0 release serves both updaters.

Verified:
  pnpm --filter @openwork/app typecheck   ✓
  cargo check --manifest-path apps/desktop/src-tauri/Cargo.toml   ✓
  node --check on all mjs scripts   ✓
  python yaml parse of release-macos-aarch64.yml   ✓

Not verified (needs a real release cycle):
  end-to-end migration from a signed Tauri .app to a signed Electron
  .app through the detached-script install swap.

Co-authored-by: Benjamin Shafii <benjamin@openworklabs.com>
2026-04-22 18:52:30 -07:00

108 lines
4.1 KiB
Markdown

# Tauri → Electron migration runbook
Three scripts. Run in order. Each one is idempotent and prints what it
will do before it does it.
```
scripts/migration/01-cut-migration-release.mjs # cut v0.12.0, the last Tauri release
scripts/migration/02-validate-migration.mjs # guided post-release smoke test
scripts/migration/03-post-migration-cleanup.mjs # delete src-tauri, flip defaults (run after users stabilize)
```
## When to run what
| Step | When | What user-visible effect |
| ---- | ---- | ------------------------ |
| 01 | Ready to ship the migration | Tauri users see "OpenWork is moving" prompt on next update |
| 02 | Right after the workflow finishes | Dogfood validation — no user effect |
| 03 | After 1-2 weeks of stable Electron telemetry | Dev repo is Electron-only; no user effect |
## 01 — cut-migration-release.mjs
```bash
node scripts/migration/01-cut-migration-release.mjs --version 0.12.0 \
--mac-url 'https://github.com/different-ai/openwork/releases/download/v0.12.0/OpenWork-darwin-arm64-0.12.0-mac.zip' \
--dry-run # inspect planned changes first
```
What it does:
1. Refuses to run on a dirty working tree.
2. Runs `pnpm bump:set -- <version>` (bumps all 5 sync files per
AGENTS.md release runbook).
3. Creates a release-config fragment at
`apps/app/.env.migration-release` setting
`VITE_OPENWORK_MIGRATION_RELEASE=1` and the per-platform download
URLs. The `Release App` workflow copies this into the build env so
the migration prompt is dormant on every other build but live for
this release.
4. Commits the version bump.
5. Creates and pushes the `vX.Y.Z` tag.
6. Prints `gh run watch` command so you can follow the workflow.
Drop `--dry-run` to actually execute.
## 02 — validate-migration.mjs
```bash
node scripts/migration/02-validate-migration.mjs --tag v0.12.0
```
Interactive guided check. Prints steps and confirms each one before
moving on:
1. Downloads the Tauri DMG for the tag and verifies its minisign
signature (reuses the existing updater public key).
2. Downloads the Electron .zip for the tag and verifies the Apple
Developer ID signature.
3. Prompts you to install the Tauri DMG on a fresh machine / VM and
confirm the migration prompt appears.
4. Drops a canary key into localStorage on the Tauri side, triggers
"Install now", and checks that the canary survives into the Electron
launch via `readMigrationSnapshot` + localStorage inspection.
5. Reports pass/fail for each step.
Needs `--skip-manual` to run the automated parts only. Useful inside a
release-review meeting as a shared checklist.
## 03 — post-migration-cleanup.mjs
```bash
node scripts/migration/03-post-migration-cleanup.mjs --dry-run
```
Once v0.12.x has been stable for 1-2 weeks:
1. Flips `apps/desktop/package.json` defaults:
- `dev``node ./scripts/electron-dev.mjs`
- `build``node ./scripts/electron-build.mjs`
- `package``pnpm run build && pnpm exec electron-builder …`
2. Removes `apps/desktop/src-tauri/` entirely.
3. Strips `@tauri-apps/*` from `apps/app/package.json` and
`apps/story-book/package.json`.
4. Collapses `apps/app/src/app/lib/desktop-tauri.ts` into
`desktop.ts` (direct Electron implementation).
5. Updates `AGENTS.md`, `ARCHITECTURE.md`, `README.md`, translated
READMEs to drop Tauri references.
6. Updates the release runbook in `AGENTS.md` to remove the
`Cargo.toml` and `tauri.conf.json` version-bump entries.
7. Creates a commit with the combined cleanup.
Drop `--dry-run` to actually perform the changes.
## Emergency rollback
If the v0.12.0 migration release is bad:
- Users on Electron already: ship v0.12.1 via electron-updater. Same
mechanism as any other update.
- Users still on Tauri: the migrate prompt is gated on
`VITE_OPENWORK_MIGRATION_RELEASE=1` at build time. Re-cut the
release with that flag unset, minisign-sign a replacement
`latest.json`, and users who haven't clicked "Install now" yet will
fall back to the non-migrating release.
- Users mid-migration: the Rust `migrate_to_electron` command keeps
the previous `.app` at `OpenWork.app.migrate-bak`. Instruct users
to `mv OpenWork.app.migrate-bak OpenWork.app` if the Electron
launch fails.