apple signing: every signable target (extensions, App Group check), build keychain unlock over SSH, api confirm docs
This commit is contained in:
parent
2e1c7cdc3c
commit
779cbdfcfd
17 changed files with 829 additions and 42 deletions
|
|
@ -19,7 +19,7 @@ when the owner said so for this run). The MCP server offers only `apple_signing_
|
|||
1. **Read.** `storebound apple signing status`: is the bundle id registered (else `storebound apple bundle`), which
|
||||
capabilities it has vs `apple.signing.capabilities`, the distribution certificates of the team and whether this
|
||||
Mac holds a private key for one (a key file in `.storebound/signing/` or an identity in the keychain), App Store
|
||||
profiles per bundle id (app + `apple.signing.extraBundleIds` for extensions) and whether Xcode has them installed.
|
||||
profiles per bundle id (the app and every extension / widget / watch app / App Clip found in the Xcode project, or `apple.signing.extensions`; `extraBundleIds` adds more) and whether Xcode has them installed. `signing ensure` registers the extensions' bundle ids, enables the capabilities their entitlements need and (manual style) makes their profiles; an App Group the profile lacks is reported with the developer portal link and steps (the API cannot assign a group; then `signing ensure --refresh-profile`, store-pitfalls 120).
|
||||
It also compares three places a capability must be and names what is missing where: the App ID, the config's
|
||||
`apple.signing.capabilities` and the iOS project's `.entitlements` (`aps-environment` = PUSH_NOTIFICATIONS,
|
||||
`com.apple.developer.game-center` = GAME_CENTER, associated domains, Sign in with Apple, iCloud, app groups, ...;
|
||||
|
|
@ -57,7 +57,12 @@ when the owner said so for this run). The MCP server offers only `apple_signing_
|
|||
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).
|
||||
flags it). Over SSH or in CI (no GUI session) codesign fails with errSecInternalComponent on a locked keychain:
|
||||
`apple build` stops first and names the fixes. `STOREBOUND_KEYCHAIN_PASSWORD=... storebound apple build
|
||||
--keychain-unlock` unlocks the login keychain and sets its key partition list (the password is read from the
|
||||
environment and never printed); `--keychain <path>` signs with a build keychain (`--keychain <path> --keychain-unlock`
|
||||
unlocks that one; `signing ensure --keychain <path>` imports the key + certificate into it). With manual signing it
|
||||
also stops when a target's App Group is missing from its installed profile (store-pitfalls 120).
|
||||
- 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
|
||||
|
|
|
|||
|
|
@ -42,7 +42,9 @@ storebound api apple salesReports_getCollection --param ... --out report.gz #
|
|||
on stderr (store-pitfalls 78). Never pipe or redirect a write; use the dedicated command the message names.
|
||||
An agent without a terminal sends a plain (non-owner) write with `--yes --confirm <operationId>`, the id equal
|
||||
to the one the call resolved to (store-pitfalls 92), after showing the dry run. `--confirm` never applies to
|
||||
owner-only operations.
|
||||
owner-only operations. Both flags are needed, and `--confirm` repeats the operation id:
|
||||
`storebound api apple bundleIds_createInstance --body bundle.json --yes --confirm bundleIds_createInstance`
|
||||
(without `--yes` it stays a dry run; a `--confirm` that differs from the id is refused).
|
||||
3. Owner-only operations (cli/api/gate.ts: every DELETE, submissions and their cancel, release requests, phased
|
||||
release changes, product page test start / stop, price schedules and price migrations, review replies, tester and
|
||||
user invitations, Play `edits.commit`, product activation, refunds, revokes and cancels, app signing) also ask for
|
||||
|
|
|
|||
|
|
@ -1229,8 +1229,13 @@ that fails without the fix (see CONTRIBUTING.md).
|
|||
(and read relative to the working directory, not the project).
|
||||
- **Do:** run the build in the Mac's logged-in session: a CI agent started there, or from SSH a `.command` file opened
|
||||
with `open -a Terminal <file>` (unset SSH_CONNECTION SSH_CLIENT SSH_TTY inside). `--allow-ssh` after
|
||||
`security unlock-keychain` skips the check.
|
||||
- **Guard:** `remoteBuildSession` in `cli/lib/xcode.ts` stops `apple build` before the archive; `credPath` in
|
||||
`security unlock-keychain` skips the check. To build over SSH or in CI anyway: export `STOREBOUND_KEYCHAIN_PASSWORD`
|
||||
(never printed, never an argument of storebound) and add `--keychain-unlock` (unlocks the login keychain and runs
|
||||
`security set-key-partition-list -S apple-tool:,apple:,codesign:`), or `--keychain <path> --keychain-unlock` for a
|
||||
build keychain that holds the Apple Distribution key + certificate (`apple signing ensure --keychain <path>` imports
|
||||
them); `--keychain` also signs the archive with `OTHER_CODE_SIGN_FLAGS=--keychain <path>` and puts the keychain on the search list.
|
||||
- **Guard:** `remoteBuildSession` in `cli/lib/xcode.ts` stops `apple build` before the archive, and its message names
|
||||
these fixes (`sshBuildRefusal`, `cli/lib/keychain.ts`; `tests/signing-targets.test.ts`); `credPath` in
|
||||
`cli/lib/credentials.ts` resolves relative credential paths from the project and `ascKeyFile` hands xcodebuild an
|
||||
absolute path (`tests/build-sign.test.ts`).
|
||||
|
||||
|
|
@ -1441,3 +1446,29 @@ that fails without the fix (see CONTRIBUTING.md).
|
|||
--platform macos` refuses an unsigned .pkg or one not signed with an installer certificate before any network call
|
||||
(`tests/mas-build.test.ts`). The `com.apple.pkg` file type of the API build upload is taken from Apple's schema and has not
|
||||
been exercised against the live API yet; `--via altool` (`--type macos`) is the fallback.
|
||||
|
||||
## 120. An app extension (share extension, widget, watch app) could not be signed: bundle id not registered, capabilities missing, App Group not in the profile
|
||||
|
||||
- **Symptom:** an iOS app with a share extension archived, then failed at export / codesign: "No profile for team 'X'
|
||||
matching 'com.example.app.share' found", "Provisioning profile ... doesn't include the App Groups capability" or
|
||||
"doesn't match the entitlements file's value for the com.apple.security.application-groups entitlement". `apple
|
||||
signing ensure` knew only the app's bundle id and refused (`not registered`) for `extraBundleIds`.
|
||||
- **Cause:** every signable target of the archive (app, app extension, widget, watch app, App Clip) is its own bundle id
|
||||
with its own capabilities and profile. And Apple's API can switch the APP_GROUPS capability on for a bundle id but
|
||||
cannot assign a group container to it: the profile carries `com.apple.security.application-groups` only after the
|
||||
group was ticked in the developer portal (Identifiers > the bundle id > App Groups > Configure).
|
||||
- **Do:** `storebound apple signing ensure --dry` lists every target found in the Xcode project (PRODUCT_BUNDLE_IDENTIFIER
|
||||
and CODE_SIGN_ENTITLEMENTS of the Release configuration) and what it would register, enable and create; without
|
||||
`--dry` it registers the extension bundle ids, enables the capabilities its entitlements need (the entitlement-to-
|
||||
capability table; `keychain-access-groups` needs none) and, for manual signing, creates an App Store profile per
|
||||
target. It then decodes each profile and compares its App Groups with the target's entitlements: a gap fails with
|
||||
the developer portal deep link `https://developer.apple.com/account/resources/identifiers/bundleId/edit/<id>` and the
|
||||
steps to tick the group (drive it in the signed-in browser; never press Remove / Delete / Revoke). After that
|
||||
`storebound apple signing ensure --refresh-profile` makes the profile again (a normal run reuses the active one, so it
|
||||
does not pile up profiles while the group is unassigned). `apple build` (manual signing) stops before the archive on the
|
||||
same gap (`--allow-app-group-gap` overrides). A variable bundle id (set in an xcconfig) is not resolvable: list the
|
||||
extension in `apple.signing.extensions` (`bundleId`, `capabilities`, `appGroups`), which replaces the detected ones.
|
||||
- **Guard:** `cli/lib/targets.ts` (pbxproj targets, App Group comparison, portal link and steps), `discoverTargets` in
|
||||
`cli/apple/signing.ts`, `tests/signing-targets.test.ts` (fixture pbxproj with an app, a share extension and app group
|
||||
entitlements, a decoded profile plist, a fake App Store Connect). There is no `console plan` form for the portal page:
|
||||
the steps are in the error and the warning.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue