Skip to content

Commit 9621905

Browse files
committed
fix(apple): make a named provisioning profile earn its reason
One bare `provisioning profile` substring was the shipped sniffer's trigger, and it is a phrase a failing build prints while talking about something else: the codesign invocation, a settings dump, a note about the profile it used. Each row now requires the profile plus the complaint Xcode attaches to it — its `IDEProvisioningErrorDomain` diagnostic, "doesn't include", "has expired" — and a mention that says nothing keeps the cache-recovery advice it already had.
1 parent 664e785 commit 9621905

3 files changed

Lines changed: 89 additions & 10 deletions

File tree

‎.device-evidence/CHECKLIST.md‎

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,13 @@ env AGENT_DEVICE_IOS_TEAM_ID="<your team id>" \
7171
prepare ios-runner --platform ios --device "<physical iPhone name>"
7272
```
7373

74-
Expected: `details.reason` is `signing_provisioning_profile_missing`. If a different reason appears,
75-
say which one did and treat the fixture as unconfirmed rather than editing the rule to fit.
74+
Expected: `details.reason` is `signing_provisioning_profile_missing`, and the profile row only fires
75+
when xcodebuild also says what is wrong with the profile — one of its `IDEProvisioningErrorDomain`
76+
diagnostics, "doesn't include ...", or "has expired" (#2688 review). Paste the whole error: which of
77+
those lines printed is what promotes the `profile-xcode-signing-error`,
78+
`profile-does-not-cover-app-id` and `profile-expired` fixtures from `invented-shape` to `captured`. A
79+
different reason is worth recording just as much: say which one and treat the fixtures as unconfirmed
80+
rather than editing the rules to fit.
7681

7782
### 4. The line that claims no reason yet -> `build_failed_unclassified`
7883

@@ -88,7 +93,8 @@ env AGENT_DEVICE_IOS_TEAM_ID="<your team id>" \
8893
prepare ios-runner --platform ios --device "<physical iPhone name>"
8994
```
9095

91-
Expected: either `signing_provisioning_profile_missing` (xcodebuild complained about the profile
92-
first) or `build_failed_unclassified`. Paste the error and the `xcodebuild -version` either way: a
96+
Expected: either `signing_provisioning_profile_missing` (xcodebuild complained about the profile and
97+
said what was wrong with it) or `build_failed_unclassified` — which is also what a run that merely
98+
mentions the profile it used gets, since a name is not a complaint (#2688 review). Paste the error and the `xcodebuild -version` either way: a
9399
capture of the conflicting-settings line is what would let a follow-up name the cause, and the
94100
capture must show which build setting disagrees before any hint naming a lever is written.

‎packages/platform-apple/src/runner/__tests__/runner-startup-failure-fixtures.ts‎

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,49 @@ export const RUNNER_STARTUP_FAILURE_FIXTURES: readonly RunnerStartupFailureFixtu
148148
],
149149
note: 'The argv we were asked to run is not xcodebuild evidence: a caller who pinned a profile still gets cache-recovery advice for a compile error (#2680).',
150150
},
151+
// Narrowed profile rows (#2688 review): each of these requires the profile AND the complaint Xcode
152+
// attaches to it. The bare phrase alone was the shipped sniffer's trigger and is not evidence, so the
153+
// negative entry below is what keeps those rows honest.
154+
{
155+
id: 'profile-xcode-signing-error',
156+
reason: 'signing_provisioning_profile_missing',
157+
site: 'build-for-testing',
158+
xcodeVersion: UNOBSERVED,
159+
provenance: 'invented-shape',
160+
output:
161+
"error: Provisioning profile \"match-development\" is not a valid provisioning profile (in target 'AgentDeviceRunner' from project 'AgentDeviceRunner')\nError Domain=IDEProvisioningErrorDomain Code=17\n** TEST BUILD FAILED **\n",
162+
note: "Xcode names the profile beside its own IDEProvisioningErrorDomain diagnostics. Sentence and domain code are our reconstruction; Phase B capture has to record the real wording and this entry's xcodeVersion.",
163+
},
164+
{
165+
id: 'profile-does-not-cover-app-id',
166+
reason: 'signing_provisioning_profile_missing',
167+
site: 'build-for-testing',
168+
xcodeVersion: UNOBSERVED,
169+
provenance: 'invented-shape',
170+
output:
171+
"error: Provisioning profile \"match-development\" doesn't include application identifier 'com.yourname.agentdevice.runner' (in target 'AgentDeviceRunner' from project 'AgentDeviceRunner')\n** TEST BUILD FAILED **\n",
172+
note: 'The installed profile that does not cover this app id. Advice is the same lever, so the same reason is published; wording unrecorded.',
173+
},
174+
{
175+
id: 'profile-expired',
176+
reason: 'signing_provisioning_profile_missing',
177+
site: 'build-for-testing',
178+
xcodeVersion: UNOBSERVED,
179+
provenance: 'invented-shape',
180+
output:
181+
"error: Provisioning profile \"match-development\" has expired (in target 'AgentDeviceRunner' from project 'AgentDeviceRunner')\n** TEST BUILD FAILED **\n",
182+
note: 'Reinstalling the same profile clears nothing; "a valid profile" in the hint is the operative word. Wording unrecorded.',
183+
},
184+
{
185+
id: 'profile-mentioned-while-compiling',
186+
reason: 'build_failed_unclassified',
187+
site: 'build-for-testing',
188+
xcodeVersion: UNOBSERVED,
189+
provenance: 'invented-shape',
190+
output:
191+
"note: Using provisioning profile \"match-development\" to sign the app bundle (in target 'AgentDeviceRunner' from project 'AgentDeviceRunner')\nerror: cannot find 'AgentDeviceRunnerCommand' in scope (in target 'AgentDeviceRunnerUITests' from project 'AgentDeviceRunner')\n** TEST BUILD FAILED **\n",
192+
note: 'The hazard the bare `provisioning profile` trigger carried (#2688 review): a failing build can print the profile it used while the failure is a compile error. A benign mention must keep cache-recovery advice; it also says nothing Xcode calls code signing, which is its own honest row.',
193+
},
151194
{
152195
id: 'devtools-security-disabled',
153196
reason: 'devtools_security_developer_mode_disabled',

‎packages/platform-apple/src/runner/runner-contract.ts‎

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,15 @@ type RunnerErrorRule = {
269269
};
270270
};
271271

272+
/**
273+
* The advice the provisioning-profile rows share (#2688). Named once so the three rows that require a
274+
* different complaint cannot drift into three different fixes for one lever.
275+
*/
276+
const PROFILE_UNUSABLE: RunnerErrorRule['buildFailure'] = {
277+
reason: 'signing_provisioning_profile_missing',
278+
hint: 'Install/select a valid iOS provisioning profile, or set AGENT_DEVICE_IOS_PROVISIONING_PROFILE.',
279+
};
280+
272281
/**
273282
* The one declaration of runner error classes (#1631), mirroring
274283
* RUNNER_COMMAND_TRAIT_MANIFEST's role for commands: every recovery predicate
@@ -433,14 +442,35 @@ export const RUNNER_ERROR_RULES: readonly RunnerErrorRule[] = [
433442
hint: 'Install/select a valid iOS provisioning profile, or set AGENT_DEVICE_IOS_PROVISIONING_PROFILE.',
434443
},
435444
},
445+
// A profile named in the tool's output is only evidence when the output also says what is wrong with
446+
// it (#2688 review). One bare `provisioning profile` substring was the shipped sniffer's trigger, and
447+
// it is a phrase a failing build can print while talking about something else: the codesign command
448+
// line, a build-settings dump, a note about the profile that was used. Each row below therefore
449+
// requires the profile plus the complaint Xcode attaches to it, and a failure that merely mentions a
450+
// profile stays unclassified rather than being sent to install a profile it already has.
436451
{
437-
reason: 'signing_provisioning_profile_unusable',
438-
match: { toolTextIncludesAll: ['provisioning profile'] },
452+
// Xcode's own signing-error domain beside the profile it rejected: the machine-readable half of its
453+
// `IDEProvisioningErrorDomain` diagnostics, which accompanies the prose rather than replacing it.
454+
reason: 'signing_provisioning_profile_xcode_error',
455+
match: { toolTextIncludesAll: ['provisioning profile', 'ideprovisioningerrordomain'] },
439456
verdicts: {},
440-
buildFailure: {
441-
reason: 'signing_provisioning_profile_missing',
442-
hint: 'Install/select a valid iOS provisioning profile, or set AGENT_DEVICE_IOS_PROVISIONING_PROFILE.',
443-
},
457+
buildFailure: PROFILE_UNUSABLE,
458+
},
459+
{
460+
// "Provisioning profile \"X\" doesn't include application identifier ..." — the profile that is
461+
// installed but does not cover this app or capability.
462+
reason: 'signing_provisioning_profile_does_not_cover',
463+
match: { toolTextIncludesAll: ['provisioning profile', "doesn't include"] },
464+
verdicts: {},
465+
buildFailure: PROFILE_UNUSABLE,
466+
},
467+
{
468+
// "Provisioning profile \"X\" has expired" — installing it again is not the fix; replacing it is,
469+
// which is what the hint's "valid" is for.
470+
reason: 'signing_provisioning_profile_expired',
471+
match: { toolTextIncludesAll: ['provisioning profile', 'expired'] },
472+
verdicts: {},
473+
buildFailure: PROFILE_UNUSABLE,
444474
},
445475
{
446476
// Signing is involved but nothing above names how: the reason says signing and the hint stays

0 commit comments

Comments
 (0)