Add TestFlight CI/CD workflow and update signing config#52
Conversation
- Update bundle ID to com.brettonauerbach.stillpoint and set Team ID - Create ExportOptions.plist for App Store distribution - Add GitHub Actions workflow triggered by ios-v* tags - Add RELEASING.md with setup and release instructions Closes #51 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Update bundleIdPrefix to match new bundle ID - Remove dead notarytool credentials step - Add IPA path validation before upload - Simplify upload step to use altool directly Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove API key file (~/.private_keys/) in cleanup step - Scope provisioning profile cleanup to the specific file installed Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use xcodebuild -exportArchive with auth flags for direct upload - Remove separate Export IPA step (now combined with upload) - Fix bundleIdPrefix to be a true prefix (com.brettonauerbach) - Track provisioning profile install path explicitly Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Preserve existing keychains when adding temp keychain to search list - Remove decoded .p12 certificate in cleanup step Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Team ID and signing style are already set in project.yml. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
📝 WalkthroughWalkthroughAdds TestFlight release automation: a GitHub Actions workflow triggered by Changes
Sequence Diagram(s)sequenceDiagram
participant Contributor
participant GitHubActions as GitHub Actions
participant XcodeGen
participant Keychain
participant Xcode
participant AppStoreConnect as App Store Connect
Contributor->>GitHubActions: Push `ios-v*` tag
GitHubActions->>XcodeGen: Run XcodeGen in `ios/`
XcodeGen-->>GitHubActions: Project generated
GitHubActions->>Keychain: Create & unlock temp keychain
GitHubActions->>Keychain: Import decoded .p12 certificate
GitHubActions->>GitHubActions: Install provisioning profile
GitHubActions->>Xcode: xcodebuild archive (uses keychain & profiles)
Xcode->>Keychain: Request signing key access
Keychain-->>Xcode: Provide signing key
Xcode-->>GitHubActions: Produce .xcarchive
GitHubActions->>AppStoreConnect: xcodebuild -exportArchive + upload (API key)
AppStoreConnect-->>GitHubActions: Confirm upload
GitHubActions->>Keychain: Delete temp keychain & cleanup files
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 📋 Issue PlannerBuilt with CodeRabbit's Coding Plans for faster development and fewer bugs. View plan used: ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/ios-testflight.yml:
- Around line 70-90: Add an explicit IPA existence/validation step after the
xcodebuild -exportArchive export (the exportPath $RUNNER_TEMP/export) that
verifies an .ipa was produced and is non-empty before attempting upload: check
for a single .ipa (e.g. glob $RUNNER_TEMP/export/*.ipa), confirm the file exists
and has size >0, log a clear error including the expected path if the check
fails, and exit non-zero to stop the job; place this check immediately after the
xcodebuild -exportArchive invocation so subsequent upload using the same
exportPath and authenticationKeyPath only runs when the IPA validation passes.
- Around line 21-22: The "Install XcodeGen" step repeatedly runs brew install
xcodegen which slows CI; modify the workflow by adding a Homebrew cache step
before the "Install XcodeGen" job (or replace the step with a cached-install
approach) so cached Homebrew bottles and Cellar/Cache paths are restored (e.g.,
cache paths under the runner Homebrew cache and Cellar) and only run brew
install xcodegen when the cache is missing or stale; update the job that
contains the "Install XcodeGen" step to restore the cache, run brew install
conditionally, and save the cache afterward.
In `@ios/project.yml`:
- Line 3: The committed Xcode project is out of sync with project.yml
(bundleIdPrefix: com.brettonauerbach); run xcodegen in the ios directory to
regenerate ios/StillPoint.xcodeproj/project.pbxproj so its bundle identifier and
other generated settings match project.yml, then stage and commit the updated
project.pbxproj (verify the old value com.stillpoint.app is replaced with
com.brettonauerbach).
In `@ios/RELEASING.md`:
- Around line 18-34: Add a blank line before and after each fenced code block in
the RELEASING.md snippet: ensure there is an empty line preceding and following
the ```yaml block that contains MARKETING_VERSION and CURRENT_PROJECT_VERSION,
and likewise add blank lines before and after each ```bash block that contains
the git add/commit and git tag/push commands so the fenced blocks are surrounded
by blank lines per MD031.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 514f1ee6-eced-4257-81b8-ffd91c2bf09f
📒 Files selected for processing (4)
.github/workflows/ios-testflight.ymlios/ExportOptions.plistios/RELEASING.mdios/project.yml
| - name: Install XcodeGen | ||
| run: brew install xcodegen |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Consider caching Homebrew packages for faster builds.
The brew install xcodegen step runs on every workflow execution. Caching can reduce build time.
📝 Optional: Add Homebrew caching
+ - name: Cache Homebrew
+ uses: actions/cache@v4
+ with:
+ path: |
+ ~/Library/Caches/Homebrew
+ /usr/local/Cellar/xcodegen
+ key: ${{ runner.os }}-brew-xcodegen-${{ hashFiles('.github/workflows/ios-testflight.yml') }}
+ restore-keys: |
+ ${{ runner.os }}-brew-xcodegen-
+
- name: Install XcodeGen
- run: brew install xcodegen
+ run: brew install xcodegen || true🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/ios-testflight.yml around lines 21 - 22, The "Install
XcodeGen" step repeatedly runs brew install xcodegen which slows CI; modify the
workflow by adding a Homebrew cache step before the "Install XcodeGen" job (or
replace the step with a cached-install approach) so cached Homebrew bottles and
Cellar/Cache paths are restored (e.g., cache paths under the runner Homebrew
cache and Cellar) and only run brew install xcodegen when the cache is missing
or stale; update the job that contains the "Install XcodeGen" step to restore
the cache, run brew install conditionally, and save the cache afterward.
| - name: Upload to App Store Connect | ||
| env: | ||
| APPSTORE_API_KEY_ID: ${{ secrets.APPSTORE_API_KEY_ID }} | ||
| APPSTORE_API_ISSUER_ID: ${{ secrets.APPSTORE_API_ISSUER_ID }} | ||
| APPSTORE_API_PRIVATE_KEY: ${{ secrets.APPSTORE_API_PRIVATE_KEY }} | ||
| run: | | ||
| # Write API key to file for authentication | ||
| mkdir -p ~/.private_keys | ||
| printf '%s\n' "$APPSTORE_API_PRIVATE_KEY" > ~/.private_keys/AuthKey_${APPSTORE_API_KEY_ID}.p8 | ||
|
|
||
| # Export and upload in one step using xcodebuild | ||
| # The ExportOptions.plist has destination=upload and method=app-store-connect | ||
| # which makes xcodebuild upload directly to App Store Connect / TestFlight | ||
| xcodebuild -exportArchive \ | ||
| -archivePath $RUNNER_TEMP/StillPoint.xcarchive \ | ||
| -exportOptionsPlist ios/ExportOptions.plist \ | ||
| -exportPath $RUNNER_TEMP/export \ | ||
| -allowProvisioningUpdates \ | ||
| -authenticationKeyPath ~/.private_keys/AuthKey_${APPSTORE_API_KEY_ID}.p8 \ | ||
| -authenticationKeyID "$APPSTORE_API_KEY_ID" \ | ||
| -authenticationKeyIssuerID "$APPSTORE_API_ISSUER_ID" |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Consider adding explicit IPA validation before upload.
The PR objectives mention "IPA path validation" but there's no explicit check that the export produced a valid IPA. While xcodebuild -exportArchive will fail if the archive is invalid, adding an explicit check improves debuggability.
📝 Optional: Add IPA existence check
xcodebuild -exportArchive \
-archivePath $RUNNER_TEMP/StillPoint.xcarchive \
-exportOptionsPlist ios/ExportOptions.plist \
-exportPath $RUNNER_TEMP/export \
-allowProvisioningUpdates \
-authenticationKeyPath ~/.private_keys/AuthKey_${APPSTORE_API_KEY_ID}.p8 \
-authenticationKeyID "$APPSTORE_API_KEY_ID" \
-authenticationKeyIssuerID "$APPSTORE_API_ISSUER_ID"
+
+ # Verify export produced an IPA
+ if ! ls $RUNNER_TEMP/export/*.ipa 1>/dev/null 2>&1; then
+ echo "Error: No IPA file found in export directory"
+ exit 1
+ fi📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - name: Upload to App Store Connect | |
| env: | |
| APPSTORE_API_KEY_ID: ${{ secrets.APPSTORE_API_KEY_ID }} | |
| APPSTORE_API_ISSUER_ID: ${{ secrets.APPSTORE_API_ISSUER_ID }} | |
| APPSTORE_API_PRIVATE_KEY: ${{ secrets.APPSTORE_API_PRIVATE_KEY }} | |
| run: | | |
| # Write API key to file for authentication | |
| mkdir -p ~/.private_keys | |
| printf '%s\n' "$APPSTORE_API_PRIVATE_KEY" > ~/.private_keys/AuthKey_${APPSTORE_API_KEY_ID}.p8 | |
| # Export and upload in one step using xcodebuild | |
| # The ExportOptions.plist has destination=upload and method=app-store-connect | |
| # which makes xcodebuild upload directly to App Store Connect / TestFlight | |
| xcodebuild -exportArchive \ | |
| -archivePath $RUNNER_TEMP/StillPoint.xcarchive \ | |
| -exportOptionsPlist ios/ExportOptions.plist \ | |
| -exportPath $RUNNER_TEMP/export \ | |
| -allowProvisioningUpdates \ | |
| -authenticationKeyPath ~/.private_keys/AuthKey_${APPSTORE_API_KEY_ID}.p8 \ | |
| -authenticationKeyID "$APPSTORE_API_KEY_ID" \ | |
| -authenticationKeyIssuerID "$APPSTORE_API_ISSUER_ID" | |
| - name: Upload to App Store Connect | |
| env: | |
| APPSTORE_API_KEY_ID: ${{ secrets.APPSTORE_API_KEY_ID }} | |
| APPSTORE_API_ISSUER_ID: ${{ secrets.APPSTORE_API_ISSUER_ID }} | |
| APPSTORE_API_PRIVATE_KEY: ${{ secrets.APPSTORE_API_PRIVATE_KEY }} | |
| run: | | |
| # Write API key to file for authentication | |
| mkdir -p ~/.private_keys | |
| printf '%s\n' "$APPSTORE_API_PRIVATE_KEY" > ~/.private_keys/AuthKey_${APPSTORE_API_KEY_ID}.p8 | |
| # Export and upload in one step using xcodebuild | |
| # The ExportOptions.plist has destination=upload and method=app-store-connect | |
| # which makes xcodebuild upload directly to App Store Connect / TestFlight | |
| xcodebuild -exportArchive \ | |
| -archivePath $RUNNER_TEMP/StillPoint.xcarchive \ | |
| -exportOptionsPlist ios/ExportOptions.plist \ | |
| -exportPath $RUNNER_TEMP/export \ | |
| -allowProvisioningUpdates \ | |
| -authenticationKeyPath ~/.private_keys/AuthKey_${APPSTORE_API_KEY_ID}.p8 \ | |
| -authenticationKeyID "$APPSTORE_API_KEY_ID" \ | |
| -authenticationKeyIssuerID "$APPSTORE_API_ISSUER_ID" | |
| # Verify export produced an IPA | |
| if ! ls $RUNNER_TEMP/export/*.ipa 1>/dev/null 2>&1; then | |
| echo "Error: No IPA file found in export directory" | |
| exit 1 | |
| fi |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/ios-testflight.yml around lines 70 - 90, Add an explicit
IPA existence/validation step after the xcodebuild -exportArchive export (the
exportPath $RUNNER_TEMP/export) that verifies an .ipa was produced and is
non-empty before attempting upload: check for a single .ipa (e.g. glob
$RUNNER_TEMP/export/*.ipa), confirm the file exists and has size >0, log a clear
error including the expected path if the check fails, and exit non-zero to stop
the job; place this check immediately after the xcodebuild -exportArchive
invocation so subsequent upload using the same exportPath and
authenticationKeyPath only runs when the IPA validation passes.
| name: StillPoint | ||
| options: | ||
| bundleIdPrefix: com.stillpoint | ||
| bundleIdPrefix: com.brettonauerbach |
There was a problem hiding this comment.
Regenerate ios/StillPoint.xcodeproj/project.pbxproj to match these changes.
The relevant code snippet shows ios/StillPoint.xcodeproj/project.pbxproj still contains the old bundle ID com.stillpoint.app. While the CI workflow runs xcodegen generate before building (which will produce the correct values), the committed project.pbxproj is now out of sync with project.yml.
Run xcodegen generate locally in the ios directory and commit the updated project.pbxproj to keep the repository consistent for local development.
Also applies to: 33-33
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@ios/project.yml` at line 3, The committed Xcode project is out of sync with
project.yml (bundleIdPrefix: com.brettonauerbach); run xcodegen in the ios
directory to regenerate ios/StillPoint.xcodeproj/project.pbxproj so its bundle
identifier and other generated settings match project.yml, then stage and commit
the updated project.pbxproj (verify the old value com.stillpoint.app is replaced
with com.brettonauerbach).
| 1. Update the version in `ios/project.yml`: | ||
| ```yaml | ||
| MARKETING_VERSION: "1.1.0" | ||
| CURRENT_PROJECT_VERSION: 2 | ||
| ``` | ||
|
|
||
| 2. Commit the version bump: | ||
| ```bash | ||
| git add ios/project.yml | ||
| git commit -m "Bump iOS version to 1.1.0 (build 2)" | ||
| ``` | ||
|
|
||
| 3. Tag and push: | ||
| ```bash | ||
| git tag ios-v1.1.0 | ||
| git push origin main --tags | ||
| ``` |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Add blank lines around fenced code blocks.
Per markdown linting (MD031), fenced code blocks should be surrounded by blank lines for better rendering compatibility.
📝 Proposed fix
1. Update the version in `ios/project.yml`:
+
```yaml
MARKETING_VERSION: "1.1.0"
CURRENT_PROJECT_VERSION: 2
```
+
2. Commit the version bump:
+
```bash
git add ios/project.yml
git commit -m "Bump iOS version to 1.1.0 (build 2)"
```
+
3. Tag and push:
+
```bash
git tag ios-v1.1.0
git push origin main --tags
```🧰 Tools
🪛 markdownlint-cli2 (0.22.0)
[warning] 19-19: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
[warning] 25-25: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
[warning] 31-31: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@ios/RELEASING.md` around lines 18 - 34, Add a blank line before and after
each fenced code block in the RELEASING.md snippet: ensure there is an empty
line preceding and following the ```yaml block that contains MARKETING_VERSION
and CURRENT_PROJECT_VERSION, and likewise add blank lines before and after each
```bash block that contains the git add/commit and git tag/push commands so the
fenced blocks are surrounded by blank lines per MD031.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
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 `@ios/RELEASING.md`:
- Line 10: Update the RELEASING.md entry for P12_PASSWORD to stop instructing
users to store the secret in the project root `.env`; instead state that
P12_PASSWORD should be kept in a secure credential store (e.g., Keychain,
password manager) and, if a local file is absolutely required, explicitly
require that file to be gitignored and never checked into source control
(mention to add it to .gitignore). Reference the P12_PASSWORD variable name in
the note and remove the current text that normalizes storing it in the project
root `.env`.
- Around line 32-33: The docs currently show using "git push origin main --tags"
which can publish unintended local tags; replace that command with a scoped tag
push for the specific release (after running "git tag ios-v1.1.0") by using "git
push origin ios-v1.1.0" (or "git push origin refs/tags/ios-v1.1.0") instead of
"git push origin main --tags" so only the ios-v1.1.0 tag is published.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 6e13494e-38e8-486f-b5ca-c1a1511fbc17
📒 Files selected for processing (1)
ios/RELEASING.md
| | Secret | Description | How to get it | | ||
| |--------|-------------|---------------| | ||
| | `BUILD_CERTIFICATE_BASE64` | Base64-encoded `.p12` distribution certificate | Export from Keychain Access, then `base64 -i cert.p12 \| pbcopy` | | ||
| | `P12_PASSWORD` | Password used when exporting the `.p12` | Stored in the project root `.env` file as `P12_PASSWORD` | |
There was a problem hiding this comment.
Avoid documenting secret storage in project root .env.
Stating that P12_PASSWORD is kept in a project-root .env normalizes a pattern that can lead to accidental secret commits. Prefer documenting secure local storage (e.g., password manager/Keychain) and, if a file is used, explicitly require it to be gitignored.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@ios/RELEASING.md` at line 10, Update the RELEASING.md entry for P12_PASSWORD
to stop instructing users to store the secret in the project root `.env`;
instead state that P12_PASSWORD should be kept in a secure credential store
(e.g., Keychain, password manager) and, if a local file is absolutely required,
explicitly require that file to be gitignored and never checked into source
control (mention to add it to .gitignore). Reference the P12_PASSWORD variable
name in the note and remove the current text that normalizes storing it in the
project root `.env`.
- Remove P12_PASSWORD .env storage reference from RELEASING.md - Push specific tag instead of --tags to avoid unintended publishes Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
@coderabbitai Fixed in
|
|
Tip For best results, initiate chat on the files or code changes.
✏️ Learnings added
|
There was a problem hiding this comment.
♻️ Duplicate comments (2)
ios/RELEASING.md (2)
19-34: 🧹 Nitpick | 🔵 TrivialMarkdown linting: Add blank lines around fenced code blocks.
Per MD031, fenced code blocks should be surrounded by blank lines. This was already flagged in a previous review.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@ios/RELEASING.md` around lines 19 - 34, Add blank lines before and after the fenced YAML code block that contains MARKETING_VERSION and CURRENT_PROJECT_VERSION so the block is separated from surrounding text per MD031; specifically, ensure there is an empty line immediately above the opening ```yaml and an empty line immediately below the closing ``` to fix the linting error for the MARKETING_VERSION/CURRENT_PROJECT_VERSION block.
18-22:⚠️ Potential issue | 🟡 MinorClarify the nested path to version fields in project.yml.
The instruction "Update the version in
ios/project.yml" and the example YAML snippet don't show thatMARKETING_VERSIONandCURRENT_PROJECT_VERSIONare nested undertargets.StillPoint.settings.base(not at the root level). Users unfamiliar with the project structure might be confused about where to update these values.📝 Suggested clarification
-1. Update the version in `ios/project.yml`: +1. Update the version in `ios/project.yml` under `targets.StillPoint.settings.base`: ```yaml + targets: + StillPoint: + settings: + base: - MARKETING_VERSION: "1.1.0" - CURRENT_PROJECT_VERSION: 2 + MARKETING_VERSION: "1.1.0" + CURRENT_PROJECT_VERSION: 2 ```Alternatively, keep the simplified example but add a note:
1. Update the version in `ios/project.yml`: ```yaml MARKETING_VERSION: "1.1.0" CURRENT_PROJECT_VERSION: 2 ``` + _(These are located under `targets.StillPoint.settings.base` in the YAML structure)_Based on learnings: The snippet from
ios/project.yml:13-45shows that MARKETING_VERSION and CURRENT_PROJECT_VERSION are nested undertargets.StillPoint.settings.base(lines 34-35), not at the top level of the file.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@ios/RELEASING.md` around lines 18 - 22, The doc currently shows MARKETING_VERSION and CURRENT_PROJECT_VERSION at top-level; update the instruction/snippet to show they live under the nested path targets.StillPoint.settings.base (i.e., place MARKETING_VERSION and CURRENT_PROJECT_VERSION inside targets -> StillPoint -> settings -> base) or add a short parenthetical note saying "_These fields are located under targets.StillPoint.settings.base in project.yml_" so readers know exactly where to change them.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@ios/RELEASING.md`:
- Around line 19-34: Add blank lines before and after the fenced YAML code block
that contains MARKETING_VERSION and CURRENT_PROJECT_VERSION so the block is
separated from surrounding text per MD031; specifically, ensure there is an
empty line immediately above the opening ```yaml and an empty line immediately
below the closing ``` to fix the linting error for the
MARKETING_VERSION/CURRENT_PROJECT_VERSION block.
- Around line 18-22: The doc currently shows MARKETING_VERSION and
CURRENT_PROJECT_VERSION at top-level; update the instruction/snippet to show
they live under the nested path targets.StillPoint.settings.base (i.e., place
MARKETING_VERSION and CURRENT_PROJECT_VERSION inside targets -> StillPoint ->
settings -> base) or add a short parenthetical note saying "_These fields are
located under targets.StillPoint.settings.base in project.yml_" so readers know
exactly where to change them.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 0aa39953-441c-4ffa-8145-1ef043ec7de0
📒 Files selected for processing (1)
ios/RELEASING.md
Summary
com.brettonauerbach.stillpointand sets Team IDT5UU4BP6AVinios/project.ymlios/ExportOptions.plistfor App Store Connect distribution.github/workflows/ios-testflight.yml) triggered byios-v*tags that builds, archives, and uploads to TestFlightios/RELEASING.mdwith setup instructions and release workflow documentationCloses #51
Test plan
ios/project.ymlmatches registered App ID (com.brettonauerbach.stillpoint)ios/project.ymlmatches Apple Developer account (T5UU4BP6AV)app-store-connectmethod with automatic signingios-v*tagsxcodebuild -exportArchivewith authentication flags for upload🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation
Chores
New Config