desktop-release: never run the x86_64 slice on the build Mac (Rosetta makes macOS warn the owner that the app will not open in the next macOS); every Mach-O in the bundle checked with lipo (arm64 + x86_64), self-test and sidecar version run natively only; pitfall 34

This commit is contained in:
CRTkafa 2026-10-13 01:59:23 +08:00
parent 7e09947e62
commit 3952716ef8
5 changed files with 64 additions and 22 deletions

View file

@ -91,8 +91,11 @@ What it does, in order:
- `codesign --verify --deep --strict`;
- the Gatekeeper expectation (signed: `spctl` accepts it as Notarized Developer ID and `stapler validate` passes;
unsigned: ad-hoc, and `spctl` rejects it);
- the self-test, run from the mounted DMG and from the unpacked updater bundle, for both CPU types (x86_64 through
Rosetta). `storebound-desktop --self-test` starts the bundled sidecar, sends `session.hello`, prints one JSON
- `lipo -archs` on every executable in the bundle (each must carry arm64 and x86_64). The x86_64 slice is never
run on the build Mac: that starts Rosetta, and macOS then warns the owner that the app "includes a component that
will not open" in the next macOS;
- the self-test (arm64, native), run from the mounted DMG and from the unpacked updater bundle.
`storebound-desktop --self-test` starts the bundled sidecar, sends `session.hello`, prints one JSON
line and exits, before Tauri starts, so no window opens;
- the privacy scan of the app, the DMG and the updater bundle.
6. Writes minisign `.sig` files with the updater key and checks them right away against tauri.conf.json's key.

View file

@ -9,6 +9,7 @@ fails without the fix.
| # | date | lesson | guard |
|---|---|---|---|
| 34 | 2026-10 | The macOS desktop release ran the universal app's x86_64 slice on the Apple silicon build Mac (`arch -x86_64 storebound-desktop --self-test`, and the x64 sidecar's `version`) to cover both CPU types. That starts Rosetta, and macOS showed the owner "App Update Required: this version of storebound includes a component that will not open in macOS 28". | `tools/desktop-release.ts` never runs an x86_64 slice: `sliceProblems` checks every Mach-O in the bundle with `lipo -archs` (each must carry arm64 and x86_64), the self-test and the sidecar `version` run natively (arm64) only; `tests/desktop-release.test.ts` (slice check, and no `arch -x86_64` / Rosetta launch in the release tools); docs/desktop-release.md. |
| 33 | 2026-10 | Play Console: pressing "Submit N changes for review" in Publishing overview while a review was running opened a dialog "Do you want to restart your review?" with "Restart review". Pressing it restarts the running review with the new changes; the plan did not know the dialog. | `play-production-release` plan: the dialog is a known step and UI fact, "Restart review" is in neverPress (the owner's button), Cancel is allowed (closes it, nothing changes); play-first-release and release-management skills explain it. `tests/console-play-plans.test.ts`. |
| 32 | 2026-10 | `play build` passed `-PversionCode` / `-PversionName` and `android.injected.version.*`, but a Capacitor `app/build.gradle` read versionCode from an env var, so the AAB stayed at versionCode 1 (the post-build check caught it). Checked with AGP 8.13: `-Pandroid.injected.version.code=42` on `versionCode 1` gives an AAB with versionCode 1, so the injected property does not override `defaultConfig` for `bundleRelease`. The Groovy line `versionCode (project.findProperty('versionCode') ?: 1) as Integer` fails ("Value is null": it parses as `versionCode(...) as Integer`); the cast belongs inside the parentheses. | `versionSourceIssues` (cli/lib/gradle.ts) reads `defaultConfig` of the app module's build.gradle(.kts): a literal, an env var or anything but the project property is a warning in `play build` (before Gradle, also in the dry run and `--json` as `versionWarnings`) and in `check`, with the exact line (Groovy `versionCode((project.findProperty('versionCode') ?: <current>) as Integer)`, `versionName project.findProperty('versionName') ?: '<current>'`; Kotlin `versionCode = (project.findProperty("versionCode") as String?)?.toInt() ?: <current>`, `versionName = project.findProperty("versionName") as String? ?: "<current>"`), both lines built with AGP 8.13; the post-build versionCode check is now a hard stop (the AAB is not copied). `tests/build-sign.test.ts`, `tests/web-assets.test.ts`. |
| 31 | 2026-10 | After the owner canceled a WAITING_FOR_REVIEW submission, the app version went DEVELOPER_REJECTED, then PREPARE_FOR_SUBMISSION, and every IAP version stayed DEVELOPER_REJECTED. `apple iap-submit --with-version --dry` skipped all of them ("latest version is DEVELOPER_REJECTED: change it in App Store Connect (or --new-version)") and said "nothing to submit". Apple takes the same version again: `POST /v1/reviewSubmissionItems` with that inAppPurchaseVersion → 201 READY_FOR_REVIEW (all 7), then `PATCH submitted: true` → 200 WAITING_FOR_REVIEW; an empty READY_FOR_REVIEW draft was reused for it. | DEVELOPER_REJECTED IAP, subscription and subscription group versions are submittable as they are (`planIapSubmission`; the app version already was): the plan says "add (developer rejected, re-submitted as is)" and `apple resubmit`'s table the same; `--new-version` only for APPROVED / REJECTED; an empty draft is reused (`chooseSubmission`). The fake ASC leaves the versions of a canceled submission DEVELOPER_REJECTED, accepts them as items and refuses APPROVED ones. `tests/resubmit.test.ts`. |