Skip to content
This repository was archived by the owner on May 1, 2026. It is now read-only.

feat: make App Store Connect API key optional for iOS builds#527

Merged
WcaleNieWolny merged 4 commits into
mainfrom
feat/optional-ios-appstore-key
Feb 26, 2026
Merged

feat: make App Store Connect API key optional for iOS builds#527
WcaleNieWolny merged 4 commits into
mainfrom
feat/optional-ios-appstore-key

Conversation

@WcaleNieWolny
Copy link
Copy Markdown
Contributor

@WcaleNieWolny WcaleNieWolny commented Feb 26, 2026

Summary

  • Makes APPLE_KEY_ID, APPLE_ISSUER_ID, and APPLE_KEY_CONTENT optional for iOS builds
  • Users who only want to build an IPA for download (via --output-upload) no longer need App Store Connect API key credentials
  • Mirrors PR feat: make Google Play config optional for Android builds #520 which made PLAY_CONFIG_JSON optional for Android builds

Validation rules

  • No API key + no --output-uploaderror (no output destination)
  • No API key + no --skip-build-number-bumperror (can't auto-increment without API key)
  • No API key + both flags set → warn and proceed

What stays required

  • Certificate, provisioning profile (code signing)
  • APP_STORE_CONNECT_TEAM_ID (Xcode project config)
  • APPLE_PROFILE_NAME (Xcode project config)

Companion PR

  • Cap-go/capgo_builder — Fastlane template conditionally skips TestFlight upload when API key is missing

Test plan

  • Run build credentials save --platform ios without API key + --output-upload → should succeed with warning
  • Run build credentials save --platform ios without API key and without --output-upload → should error
  • Run a build without API key + --output-upload + --skip-build-number-bump → should build IPA and skip TestFlight upload

Summary by CodeRabbit

  • Bug Fixes
    • Apple App Store Connect API credentials are now optional; builds no longer require them to proceed
    • Enhanced validation messages provide clearer guidance on configuring auto-upload to TestFlight

Users who want to build an IPA for download via Capgo output upload link
no longer need to provide APPLE_KEY_ID, APPLE_ISSUER_ID, and
APPLE_KEY_CONTENT. These are now only required for TestFlight upload.

Mirrors the pattern from PR #520 which made PLAY_CONFIG_JSON optional
for Android builds.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 26, 2026

Warning

Rate limit exceeded

@WcaleNieWolny has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 8 minutes and 35 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 989a4cd and 067038a.

📒 Files selected for processing (3)
  • src/build/credentials-command.ts
  • src/build/request.ts
  • test/test-credentials-validation.mjs
📝 Walkthrough

Walkthrough

The PR makes App Store Connect API key credentials optional by introducing conditional validation logic. When credentials are absent, it prompts users to either provide Apple key parameters for auto-upload or enable alternative upload mechanisms via BUILD_OUTPUT_UPLOAD_ENABLED or SKIP_BUILD_NUMBER_BUMP flags.

Changes

Cohort / File(s) Summary
Credential Validation & Messaging
src/build/credentials-command.ts, src/build/request.ts
Converts mandatory App Store Connect API key credentials to optional. Introduces hasAppleApiKey check and conditional logic that either warns or requires BUILD_OUTPUT_UPLOAD_ENABLED/SKIP_BUILD_NUMBER_BUMP when Apple credentials are absent. Updates error messages and diagnostic output to reflect optional credential behavior.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 Keys once locked, now dance with grace,
Apple credentials find their place—
Optional now, yet still held true,
Build flows flexible, workflows new! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: making App Store Connect API key optional for iOS builds, which is the primary focus of changes across both modified files.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/optional-ios-appstore-key

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@WcaleNieWolny WcaleNieWolny marked this pull request as ready for review February 26, 2026 14:17
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Makes App Store Connect API key credentials optional for iOS build flows when the user is only generating an IPA for download (via output upload), aligning iOS behavior with the earlier Android “optional store upload config” change.

Changes:

  • Updates iOS build request validation to allow missing APPLE_* API key fields when output upload is enabled and build-number bumping is skipped.
  • Updates build credentials save --platform ios validation to warn (instead of hard-fail) when the App Store Connect API key is omitted and output upload is enabled.
  • Adjusts iOS credential-save example output to reflect that App Store Connect API key flags are optional.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
src/build/request.ts Conditional iOS build validation: App Store Connect API key is optional depending on output upload + skip-build-number-bump.
src/build/credentials-command.ts Conditional iOS credential-save validation and updated CLI guidance when API key is omitted.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/build/request.ts
Comment thread src/build/credentials-command.ts Outdated
missingCreds.push('--apple-key/--apple-key-id/--apple-issuer-id OR --output-upload (Build has no output destination - enable either TestFlight upload or Capgo download link)')
}
else {
log.warn('⚠️ App Store Connect API key not provided - builds will succeed but cannot auto-upload to TestFlight')
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the App Store Connect API key is omitted but --output-upload is enabled, this warns only about TestFlight upload. Builds will also fail later unless build-number auto-increment is disabled (per request validation requiring --skip-build-number-bump). Consider warning here that the user must set --skip-build-number-bump (either when saving or when running the build) when no API key is provided.

Suggested change
log.warn('⚠️ App Store Connect API key not provided - builds will succeed but cannot auto-upload to TestFlight')
log.warn('⚠️ App Store Connect API key not provided - builds will succeed but cannot auto-upload to TestFlight')
log.warn(' If you continue without an API key, you must also set --skip-build-number-bump when saving credentials or running the build, otherwise builds will fail during App Store Connect validation.')

Copilot uses AI. Check for mistakes.
Comment thread src/build/request.ts Outdated
const hasAppleApiKey = mergedCredentials.APPLE_KEY_ID && mergedCredentials.APPLE_ISSUER_ID && mergedCredentials.APPLE_KEY_CONTENT
if (!hasAppleApiKey) {
if (mergedCredentials.BUILD_OUTPUT_UPLOAD_ENABLED !== 'true') {
missingCreds.push('APPLE_KEY_ID/APPLE_ISSUER_ID/APPLE_KEY_CONTENT or BUILD_OUTPUT_UPLOAD_ENABLED=true (build has no output destination - enable either TestFlight upload or Capgo download link)')
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new combined missing-credentials message for iOS output destination doesn't mention the CLI flag users can actually set. Consider including --output-upload (and/or BUILD_OUTPUT_UPLOAD_ENABLED) so the error is actionable from the command line, similar to other messages in this block that include their --... equivalents.

Suggested change
missingCreds.push('APPLE_KEY_ID/APPLE_ISSUER_ID/APPLE_KEY_CONTENT or BUILD_OUTPUT_UPLOAD_ENABLED=true (build has no output destination - enable either TestFlight upload or Capgo download link)')
missingCreds.push('APPLE_KEY_ID/APPLE_ISSUER_ID/APPLE_KEY_CONTENT or BUILD_OUTPUT_UPLOAD_ENABLED=true (or --output-upload) (build has no output destination - enable either TestFlight upload or Capgo download link)')

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Already addressed in 99ce905 — the message now includes (or --output-upload):

APPLE_KEY_ID/APPLE_ISSUER_ID/APPLE_KEY_CONTENT or BUILD_OUTPUT_UPLOAD_ENABLED=true (or --output-upload) (build has no output destination - ...)

Comment thread src/build/request.ts Outdated
Comment on lines +1029 to +1039
const hasAppleApiKey = mergedCredentials.APPLE_KEY_ID && mergedCredentials.APPLE_ISSUER_ID && mergedCredentials.APPLE_KEY_CONTENT
if (!hasAppleApiKey) {
if (mergedCredentials.BUILD_OUTPUT_UPLOAD_ENABLED !== 'true') {
missingCreds.push('APPLE_KEY_ID/APPLE_ISSUER_ID/APPLE_KEY_CONTENT or BUILD_OUTPUT_UPLOAD_ENABLED=true (build has no output destination - enable either TestFlight upload or Capgo download link)')
}
else if (mergedCredentials.SKIP_BUILD_NUMBER_BUMP !== 'true') {
missingCreds.push('APPLE_KEY_ID/APPLE_ISSUER_ID/APPLE_KEY_CONTENT or --skip-build-number-bump (App Store Connect API key not provided - build numbers cannot be auto-incremented without it)')
}
else if (!silent) {
log.warn('⚠️ App Store Connect API key not provided - build will succeed but cannot auto-upload to TestFlight')
}
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Grouping the App Store Connect API key fields into a single "APPLE_KEY_ID/APPLE_ISSUER_ID/APPLE_KEY_CONTENT" requirement makes it hard to diagnose partial configuration (e.g., key id + issuer set but missing key content). Consider detecting partial presence and reporting which specific field(s) are missing, while still allowing the fully-missing-key optional path when --output-upload is enabled and build number bump is skipped.

Suggested change
const hasAppleApiKey = mergedCredentials.APPLE_KEY_ID && mergedCredentials.APPLE_ISSUER_ID && mergedCredentials.APPLE_KEY_CONTENT
if (!hasAppleApiKey) {
if (mergedCredentials.BUILD_OUTPUT_UPLOAD_ENABLED !== 'true') {
missingCreds.push('APPLE_KEY_ID/APPLE_ISSUER_ID/APPLE_KEY_CONTENT or BUILD_OUTPUT_UPLOAD_ENABLED=true (build has no output destination - enable either TestFlight upload or Capgo download link)')
}
else if (mergedCredentials.SKIP_BUILD_NUMBER_BUMP !== 'true') {
missingCreds.push('APPLE_KEY_ID/APPLE_ISSUER_ID/APPLE_KEY_CONTENT or --skip-build-number-bump (App Store Connect API key not provided - build numbers cannot be auto-incremented without it)')
}
else if (!silent) {
log.warn('⚠️ App Store Connect API key not provided - build will succeed but cannot auto-upload to TestFlight')
}
const hasAppleKeyId = !!mergedCredentials.APPLE_KEY_ID
const hasAppleIssuerId = !!mergedCredentials.APPLE_ISSUER_ID
const hasAppleKeyContent = !!mergedCredentials.APPLE_KEY_CONTENT
const anyAppleApiField = hasAppleKeyId || hasAppleIssuerId || hasAppleKeyContent
const hasCompleteAppleApiKey = hasAppleKeyId && hasAppleIssuerId && hasAppleKeyContent
if (!hasCompleteAppleApiKey) {
if (anyAppleApiField) {
const missingAppleFields: string[] = []
if (!hasAppleKeyId)
missingAppleFields.push('APPLE_KEY_ID (or --apple-key-id)')
if (!hasAppleIssuerId)
missingAppleFields.push('APPLE_ISSUER_ID (or --apple-issuer-id)')
if (!hasAppleKeyContent)
missingAppleFields.push('APPLE_KEY_CONTENT (or --apple-key-content)')
missingCreds.push(`Incomplete App Store Connect API key configuration – missing: ${missingAppleFields.join(', ')}`)
}
else {
// No App Store Connect API key fields provided at all
if (mergedCredentials.BUILD_OUTPUT_UPLOAD_ENABLED !== 'true') {
missingCreds.push('APPLE_KEY_ID/APPLE_ISSUER_ID/APPLE_KEY_CONTENT or BUILD_OUTPUT_UPLOAD_ENABLED=true (build has no output destination - enable either TestFlight upload or Capgo download link)')
}
else if (mergedCredentials.SKIP_BUILD_NUMBER_BUMP !== 'true') {
missingCreds.push('APPLE_KEY_ID/APPLE_ISSUER_ID/APPLE_KEY_CONTENT or --skip-build-number-bump (App Store Connect API key not provided - build numbers cannot be auto-incremented without it)')
}
else if (!silent) {
log.warn('⚠️ App Store Connect API key not provided - build will succeed but cannot auto-upload to TestFlight')
}
}

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 067038a — the validation now distinguishes between "no API key fields" (optional path) and "partial API key" (always an error with specific missing fields listed). Added test coverage for both scenarios (2 of 3 fields present, 1 of 3 fields present).

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/build/credentials-command.ts`:
- Around line 290-292: Update the iOS example printed by the credentials command
so it includes the required --output-upload destination flag instead of implying
--apple-key alone is sufficient; modify the log.error messages around the iOS
example (the two log.error calls shown) to include a full example invocation
that contains --output-upload along with the optional --apple-key,
--apple-key-id, and --apple-issuer-id flags so copy-pasting will not trigger the
“no output destination” error.
- Around line 243-245: The warning emitted via log.warn that says builds will
succeed but cannot auto-upload to TestFlight is misleading because build
validation later requires skipping the build-number bump when no App Store
Connect API key is provided; update the log.warn messages (the two calls
currently emitting the API-key absence and the suggested --apple-key flags) to
also instruct users to skip the build-number bump when they do not provide an
API key (e.g., "and add --skip-build-number-bump when not using an Apple API
key") so the next validation step won't fail; modify the message strings in the
existing log.warn calls to include this constraint while preserving the existing
guidance about --apple-key, --apple-key-id and --apple-issuer-id.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6324242 and 989a4cd.

📒 Files selected for processing (2)
  • src/build/credentials-command.ts
  • src/build/request.ts

Comment thread src/build/credentials-command.ts Outdated
Comment thread src/build/credentials-command.ts
Updates credential validation tests to cover the new conditional paths:
- No API key + no output upload → error (no destination)
- No API key + output upload + no skip-build-number-bump → error
- No API key + output upload + skip-build-number-bump → allow
- Partial API key (2 of 3 fields) + no output upload → error

Extracts shared validateIosCredentials() helper matching request.ts logic.
- Warning now mentions --skip-build-number-bump requirement when no API key
- Example includes --output-upload so copy-paste works without errors
- Error message in request.ts mentions --output-upload CLI flag
await test('iOS validation errors when no API key with output upload but no skip-build-number-bump', () => {
const credentials = {
BUILD_CERTIFICATE_BASE64: 'cert',
P12_PASSWORD: 'pass',

Check failure

Code scanning / SonarCloud

Credentials should not be hard-coded High test

Review this potentially hard-coded password. See more on SonarQube Cloud
await test('iOS validation allows no API key when output upload and skip-build-number-bump are set', () => {
const credentials = {
BUILD_CERTIFICATE_BASE64: 'cert',
P12_PASSWORD: 'pass',

Check failure

Code scanning / SonarCloud

Credentials should not be hard-coded High test

Review this potentially hard-coded password. See more on SonarQube Cloud
When users provide some but not all API key fields (e.g. key ID + issuer
but no key content), the validation now reports exactly which fields are
missing instead of suggesting output-upload as an alternative.

Adds 2 test cases for partial API key detection scenarios.
@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
23.1% Duplication on New Code (required ≤ 3%)
E Security Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@WcaleNieWolny WcaleNieWolny merged commit 125b573 into main Feb 26, 2026
16 of 19 checks passed
@riderx riderx deleted the feat/optional-ios-appstore-key branch March 17, 2026 14:51
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants