apple build exports each build into build/ios/export/<version>-<build>/ (cleaned first), runs xcodebuild with Apple's tool folders first on PATH (Homebrew rsync 3.x broke Xcode's IPA step: exportArchive Copy failed), shows the IDEDistribution log's real error lines and exits non-zero on any export failure; apple upload fails with exit 1 when the IPA's build number is already on App Store Connect (stale IPA after a failed build), --allow-existing re-checks, --build N picks that build's IPA, release and beta flows use both; doctor flags a non-Apple rsync first on PATH; desktop publish calls rsync by absolute path without --chmod (publishSteps); site download notice per OS (macOS signed and notarized, Windows unsigned for now, Linux unsigned); game-report credential tests hermetic against a machine default profile (pitfalls 53, 54)

This commit is contained in:
CRTkafa 2026-10-13 09:45:48 +08:00
parent 8fd4ac741e
commit 0e4f579899
20 changed files with 338 additions and 48 deletions

View file

@ -36,7 +36,7 @@ answers the compliance facts no file proves, all in one batch at the start.
```sh
storebound apple signing status # capabilities, certificate with a key on this Mac, profiles
storebound apple build --version 1.0.0 --dry # project + scheme found, next build number, ExportOptions.plist
storebound apple build --version 1.0.0 # xcodebuild archive + exportArchive -> build/ios/export/*.ipa
storebound apple build --version 1.0.0 # xcodebuild archive + exportArchive -> build/ios/export/<version>-<build>/*.ipa
storebound apple upload --dry # then without --dry (asks): API build upload, waits for VALID
```
`apple build` takes the build number from `storebound apple next-build` unless `--build-number N` is given, and

View file

@ -44,7 +44,11 @@ when the owner said so for this run). The MCP server offers only `apple_signing_
`project` / `scheme`), the build number (next free one from App Store Connect, or `--build-number N`), the
ExportOptions.plist (`method` app-store-connect, `destination` export, team, style, profiles) and both xcodebuild
commands. Then run it without `--dry` (minutes; full logs in `build/ios/xcodebuild-*.log`). It ends with the IPA
path, version and build. **Note the build number**: later steps use exactly it.
path (`build/ios/export/<version>-<build>/App.ipa`, a fresh folder per build), version and build. **Note the build
number**: later steps use exactly it. Any archive or export failure exits non-zero, so `apple build && apple upload`
stops there; an export failure shows the IDEDistribution log's real error lines. xcodebuild runs with Apple's tool
folders first on PATH (a Homebrew rsync breaks Xcode's IPA step: "exportArchive Copy failed"; `storebound doctor`
flags it).
- Capacitor: the archive ships the web assets `npx cap sync` copied last. Set `build.prebuild` (e.g.
`"npm run build && npx cap sync"`; per store `apple.prebuild` / `play.prebuild`) and `apple build` / `play build`
run it first (once per `flow run`; `--no-prebuild` skips it). Then the copied `public/index.html` must be newer
@ -56,8 +60,10 @@ when the owner said so for this run). The MCP server offers only `apple_signing_
run warns when Pods/ is missing). Flutter: storebound runs `flutter build ios --config-only` with the build
number. Unity: build the Xcode project from Unity first.
- Capacitor needs a UTF-8 locale; storebound sets `LANG` / `LC_ALL` for xcodebuild.
5. **Upload.** `storebound apple upload --dry` (default: the newest IPA in `build/ios/export`): bundle id, version,
build, and a refusal when that build number is already on App Store Connect. Then without `--dry` after a yes. Default
5. **Upload.** `storebound apple upload --build N --dry` (the IPA of build N; without `--build`, the newest IPA under
`build/ios/export`): bundle id, version, build, and exit 1 when that build number is already on App Store Connect
(a stale IPA from a failed build: build again). `--allow-existing` only re-checks a build this command uploaded
before (flows resuming). Then without `--dry` after a yes. Default
`--via api` is the App Store Connect API build upload (Build Uploads: reserve, upload the parts, commit with the
MD5, poll the upload state; any OS). `--via altool` uses `xcrun altool --upload-package` with the API key. Apple
lists both (and Xcode / Transporter); neither is deprecated. storebound then waits until the build is VALID

View file

@ -626,3 +626,18 @@ that fails without the fix (see CONTRIBUTING.md).
- **Do:** `storebound apps add --store apple --app-id <id> --account <profile>`; the desktop shows it read-only
("Store only": status, reviews, analytics). `apps remove apple:<id>` takes it out.
- **Guard:** `storeApps` in `~/.storebound/projects.json` (`cli/lib/registry.ts`, `registry.rs`), the boot check.
## 53. `apple upload` passed a stale IPA as "already VALID"
- **Do:** upload the IPA `apple build` just printed (`build/ios/export/<version>-<build>/App.ipa`), or `apple upload
--build N`. An IPA whose build number is already on App Store Connect now fails with exit 1: the last build failed;
run `apple build` again. `--allow-existing` only for re-checking a build this command uploaded before (flows use it
with `--build ${BUILD}`).
- **Guard:** per-build export folders, `existingBuild` / `exportedIpas` (`cli/apple/upload.ts`), `exportIpa`
(`cli/apple/build.ts`), `tests/apple-build-export.test.ts`.
## 54. "exportArchive Copy failed": a Homebrew rsync on PATH
- **Do:** read the IDEDistribution log lines `apple build` prints. "rsync error: syntax or usage error" means a
non-Apple rsync (Homebrew 3.x) is first on PATH; storebound runs xcodebuild with /usr/bin first, `storebound doctor`
names the culprit. Never install or `brew link` a global tool as a side effect on a shared machine.
- **Guard:** `xcodePath`, `foreignRsync`, `distributionErrors` (`cli/lib/xcode.ts`), doctor, `publishSteps`
(`tools/desktop-release.ts`, rsync by absolute path).