fix(signing): exact App ID resolution + regenerate stale profiles on the build path (#291, #292)#293
Conversation
…the build path (#291, #292) findBundleId resolved the wrong App ID for multi-target apps: Apple's filter[identifier] is a substring match, so a query for com.acme.app also returned com.acme.app.widget and data[0] could be the widget. Select the exact identifier and raise the limit off 1. This also fixes ensureAppStoreProfileForBundle binding the main app's profile to the widget's App ID (#291). launch build reused a cached profile without checking staleness — only setup self-healed. resolveSigning now grades each cached profile (main + every extension) against its App ID's live capabilities via staleCachedSigningTargets before silent reuse, and regenerates a stale set instead of failing the archive at exit 65. Best-effort and network-bound, mirroring warnUnreadySigningTargets: a flaky read or off-Mac decode grades as current so reuse stands (#292). 7 unit tests; README/llms/commands test-count badge regenerated (1967 -> 1974). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
|
Warning Review limit reached
Next review available in: 27 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (16)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
1 issue found across 16 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/apple/ascClient.ts">
<violation number="1" location="src/apple/ascClient.ts:984">
P2: `findBundleId` can still return `null` for an existing bundle ID when more than 200 `filter[identifier]` matches are present, because only the first page is searched. Using `requestAll` here would fully close the pagination edge case this change is addressing.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| const { data } = await this.request<ResourceList<{ identifier: string; seedId?: string }>>( | ||
| 'GET', | ||
| `/bundleIds?filter[identifier]=${encodeURIComponent(identifier)}&limit=1`, | ||
| `/bundleIds?filter[identifier]=${encodeURIComponent(identifier)}&limit=200`, |
There was a problem hiding this comment.
P2: findBundleId can still return null for an existing bundle ID when more than 200 filter[identifier] matches are present, because only the first page is searched. Using requestAll here would fully close the pagination edge case this change is addressing.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/apple/ascClient.ts, line 984:
<comment>`findBundleId` can still return `null` for an existing bundle ID when more than 200 `filter[identifier]` matches are present, because only the first page is searched. Using `requestAll` here would fully close the pagination edge case this change is addressing.</comment>
<file context>
@@ -971,18 +971,24 @@ export class AppStoreConnectClient {
const { data } = await this.request<ResourceList<{ identifier: string; seedId?: string }>>(
'GET',
- `/bundleIds?filter[identifier]=${encodeURIComponent(identifier)}&limit=1`,
+ `/bundleIds?filter[identifier]=${encodeURIComponent(identifier)}&limit=200`,
);
- const first = data[0];
</file context>
…the build path (#291, #292) (#293) findBundleId resolved the wrong App ID for multi-target apps: Apple's filter[identifier] is a substring match, so a query for com.acme.app also returned com.acme.app.widget and data[0] could be the widget. Select the exact identifier and raise the limit off 1. This also fixes ensureAppStoreProfileForBundle binding the main app's profile to the widget's App ID (#291). launch build reused a cached profile without checking staleness — only setup self-healed. resolveSigning now grades each cached profile (main + every extension) against its App ID's live capabilities via staleCachedSigningTargets before silent reuse, and regenerates a stale set instead of failing the archive at exit 65. Best-effort and network-bound, mirroring warnUnreadySigningTargets: a flaky read or off-Mac decode grades as current so reuse stands (#292). 7 unit tests; README/llms/commands test-count badge regenerated (1967 -> 1974). Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
Two signing-resolution bugs found while verifying the #289 multi-target fix on a live widget app.
Closes #291. Closes #292.
#291 —
findBundleIdresolved the wrong App ID for multi-target appsApple's
filter[identifier]is a substring match, sofindBundleId('com.acme.app')also matchedcom.acme.app.widget, andlimit=1+data[0]could return the widget's App ID.findBundleIdnow fetches the matches and selects the exact identifier (limit raised off1so the exact row isn't paginated away behind its siblings). This is on the critical path forensureAppStoreProfileForBundle, which otherwise bound the main app's provisioning profile to the widget's App ID resource.#292 —
launch buildreused a stale profile; only setup self-healedThe setup path guards reuse with
profileStaleAgainstCapabilities(#261), but the build path reusedcredentials.signingblind.resolveSigningnow grades each cached profile (main + everyextensionProfilesentry) against its App ID's live capabilities via the newstaleCachedSigningTargets, and regenerates a stale set instead of dying at exit 65. Best-effort and network-bound — a flaky lookup or off-Mac decode grades the target as current, so reuse stands (staleness only ever forces a regenerate, never blocks one). Extracted intoreuseCachedSigningto keepresolveSigningunder the complexity cap.Tests
findBundleId: picks the exact row when the substring filter also returns child bundle ids;nullwhen only siblings match.staleCachedSigningTargets: flags a stale main + extension,[]when covered, best-effort on unreadable/unregistered targets, main-only when the app has no extensions.Validation
npm run typecheck && npm run lint && npm run test && npm run build— all green (1974 tests). README / llms.txt / commands test-count badge regenerated.🤖 Generated with Claude Code
Summary by cubic
Fixes two signing bugs: exact App ID matching for multi-target apps and automatic regeneration of stale provisioning profiles during builds. Prevents binding profiles to the wrong App ID and avoids exit 65 by checking capabilities before reuse.
findBundleId: select the exact identifier and raise the query limit to 200 to avoid substring collisions (e.g., app vs widget).--dry-run. Extracted intostaleCachedSigningTargetsandreuseCachedSigning.Written for commit 363044c. Summary will update on new commits.