Skip to content

iOS App Store Fastlane harness and tag-split release CI#331

Merged
auerbachb merged 10 commits into
mainfrom
cursor/ios-app-store-fastlane-3945
May 5, 2026
Merged

iOS App Store Fastlane harness and tag-split release CI#331
auerbachb merged 10 commits into
mainfrom
cursor/ios-app-store-fastlane-3945

Conversation

@auerbachb
Copy link
Copy Markdown
Owner

@auerbachb auerbachb commented May 1, 2026

User description

Summary

Implements the issue #242 automation harness: Bundler-managed Fastlane under ios/ (gym, pilot, deliver), canonical fastlane/metadata/en-US/ source of truth (folds PR #302 / app-store-metadata.md copy into deliver files), a new tag-triggered App Store release workflow, and an evidence log for automated vs manual steps.

Tag model (important)

To avoid two workflows firing on the same tag, tags are split:

  • TestFlight binary upload: ios-v*-build* (example: ios-v1.0.3-build10) → .github/workflows/ios-testflight.yml (unchanged behavior: xcodebuild archive + export upload).
  • App Store automation (Fastlane): strict semver ios-vMAJOR.MINOR.PATCH that must equal MARKETING_VERSION in ios/project.yml (example: ios-v1.0.3) → .github/workflows/ios-app-store-release.ymlbundle exec fastlane release.

CI behavior

  • fastlane release runs preflight (npm run ios:app-store:dry-run), then gym + deliver (metadata + IPA).
  • App Store Connect submission: CI sets DELIVER_SKIP_SUBMISSION=1 so deliver uploads binary + metadata but does not submit for review (harness / Checklist: AI-assisted iOS App Store submission automation dry run #242 default; Release V1.1 to App Store #296 can remove this guard when a release owner approves live submission).
  • Existing GitHub secrets APPSTORE_API_* are mapped to Fastlane’s standard APP_STORE_CONNECT_API_KEY_ID, APP_STORE_CONNECT_API_ISSUER_ID, APP_STORE_CONNECT_API_KEY_CONTENT in the workflow (same secret values; no renames). Fastfile reads those names first, with fallback to APPSTORE_* for local runs.

Docs

  • ios/RELEASING.md — TestFlight vs App Store tag flow + Fastlane lane table; secrets documented as already wired.
  • docs/operations/automation-evidence.md — automated vs human gates + submission behavior.
  • ios/docs/app-store-metadata.md — points canonical deliverable strings at fastlane/metadata/.

Verification

  • node scripts/ios-app-store-dry-run.mjs passes after workflow/script updates.

Closes #242

Open in Web Open in Cursor 

Summary by CodeRabbit

  • New Features

    • App Store release automation: strict semver tag gating, automated dry‑run evidence, new Fastlane release lanes, and updated App Store metadata and reviewer notes visible on the store.
  • Documentation

    • Expanded runbooks and a new automation-evidence guide describing CI dry‑runs, checklist gates, secret handling, and remaining human review steps.
  • Chores

    • Narrowed TestFlight vs App Store tag triggers, improved CI validation/reporting for releases, and ignored local Ruby vendor gems.

CodeAnt-AI Description

Split iOS release tags between TestFlight uploads and App Store releases

What Changed

  • TestFlight now runs only on ios-v*-build* tags, while strict ios-vMAJOR.MINOR.PATCH tags trigger the App Store release workflow.
  • Added Fastlane-based App Store release support for building the IPA, uploading metadata, and sending the release package to App Store Connect.
  • Added canonical App Store metadata and review notes files under ios/fastlane/metadata/ so release text comes from one source.
  • Updated release docs and the automation evidence log to explain the new tag flow, required checks, and which steps still need a human decision.
  • Added a separate export settings file for Fastlane builds and wired the release workflow to the existing App Store Connect secrets.

Impact

✅ Fewer accidental release triggers
✅ Clearer App Store release steps
✅ More reliable TestFlight vs App Store tagging

🔄 Retrigger CodeAnt AI Review

Details

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

@vercel
Copy link
Copy Markdown

vercel Bot commented May 1, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
still-point Ready Ready Preview, Comment May 5, 2026 2:48pm

Request Review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 1, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a strict App Store release GitHub Actions workflow triggered by semver tags, narrows TestFlight tag triggers, introduces Fastlane configuration and metadata, implements CI preflight/signing and dry-run tooling for both workflows, adds export options and docs, and ignores bundled iOS gems.

Changes

iOS App Store release + TestFlight CI

Layer / File(s) Summary
Config & Metadata
ios/Gemfile, ios/fastlane/Appfile, ios/fastlane/Deliverfile, ios/ExportOptionsFastlane.plist, ios/fastlane/metadata/...
Add Gemfile (fastlane ~>2.227), Appfile (team_id), Deliverfile, ExportOptions plist, and Fastlane metadata/review files (name, subtitle, description, keywords, marketing/support/privacy URLs, release notes, review notes).
Fastlane lanes & helpers
ios/fastlane/Fastfile
Add helpers to construct ASC API key from env vars and lanes: preflight, build, beta, metadata_only, release (release runs optional preflight → build → deliver with env-controlled submit/automatic flags).
Dry-run tooling
scripts/ios-app-store-dry-run.mjs
Extend dry-run to model two workflows (TestFlight + App Store release); validate each workflow's tag trigger and require secret references in both; change machine report shape to report.workflows and emit both workflow URLs.
CI Workflows / Wiring
.github/workflows/ios-app-store-release.yml, .github/workflows/ios-testflight.yml
Add ios-app-store-release.yml (jobs: pre-flight-tests, fastlane-release: node/npm, xcodegen retry, e2e smoke, artifact uploads, tag⇄MARKETING_VERSION validation, checklist grep, SDK >=26 check, temp keychain provisioning, Ruby/bundler, bundle exec fastlane release, cleanup). Narrow TestFlight trigger to ios-v*-build*.
Repo hygiene & docs
.gitignore, README.md, docs/operations/automation-evidence.md, docs/operations/ios-app-store-submission.md, ios/RELEASING.md, ios/docs/app-store-metadata.md
Ignore /ios/vendor/bundle/; add automation-evidence runbook; update README and runbooks to document distinct tag rules, dry-run evidence locations, automation boundaries, and Fastlane locations.

Sequence Diagram(s)

sequenceDiagram
    actor Developer
    participant GHA as GitHub Actions<br/>(ios-app-store-release.yml)
    participant Pre as Preflight Job<br/>(xcodegen, smoke tests)
    participant Runner as macOS Runner
    participant Key as Temp Keychain
    participant FL as Fastlane<br/>(bundle exec fastlane)
    participant ASC as App Store Connect<br/>API

    Developer->>GHA: Push ios-vX.Y.Z tag

    rect rgba(100, 149, 237, 0.5)
    Note over GHA,Pre: Pre-flight
    GHA->>Runner: checkout, setup Node 22, npm ci
    GHA->>Pre: install xcodegen (retry), generate Xcode project
    GHA->>Pre: run iOS smoke e2e (Release)
    GHA->>GHA: upload diagnostics & xcresult artifacts
    end

    rect rgba(144, 238, 144, 0.5)
    Note over GHA,Key: Release (after preflight)
    GHA->>GHA: validate tag vs MARKETING_VERSION, checklists, dry-run evidence
    GHA->>Runner: ensure Xcode SDK >= 26
    GHA->>Key: create temp keychain, import cert & provisioning profile
    GHA->>Runner: setup Ruby 3.3, bundler cache
    GHA->>FL: run `bundle exec fastlane release` with ASC env
    end

    rect rgba(255, 182, 193, 0.5)
    Note over FL,ASC: Fastlane interactions
    FL->>Runner: build archive/export (gym/xcodebuild)
    FL->>ASC: upload IPA / sync metadata (deliver/pilot)
    FL->>ASC: optionally submit for review
    end

    GHA->>Key: delete temp keychain & cleanup secrets
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

  • #242 — Checklist: AI-assisted iOS App Store submission automation dry run — this PR implements the dry-run, Fastlane lanes, workflows, and runbook items referenced by the checklist.

Possibly related PRs

Suggested labels

size:XXL

Suggested reviewers

  • codeant-ai

Poem

🐰 In CI burrows pipelines hum,
Fastlane readies, certs tucked in thumb,
Preflight hops, dry-runs verify,
Tags align — the release aims high,
A tiny rabbit cheers: ship, go—yum!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and specifically describes the main change: adding a Fastlane harness for iOS App Store release automation and splitting release CI by tag patterns.
Linked Issues check ✅ Passed The PR comprehensively implements issue #242 requirements: Fastlane harness with gym/pilot/deliver, tag-split CI (ios-v*-build* for TestFlight, ios-vMAJOR.MINOR.PATCH for App Store), canonical metadata in fastlane/metadata/en-US, preflight checks, API key configuration, checklists, and runbook documentation.
Out of Scope Changes check ✅ Passed All changes are scoped to issue #242 objectives: Fastlane configuration, tag-split workflows, metadata files, runbook updates, dry-run script enhancement, and supporting CI/documentation files. No unrelated modifications detected.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cursor/ios-app-store-fastlane-3945

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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

@auerbachb
Copy link
Copy Markdown
Owner Author

@CodeAnt-AI review
@cursor review
@graphite-app re-review

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 1, 2026

Your free trial PR review limit of 100 PRs has been reached. Please upgrade your plan to continue using CodeAnt AI.

@auerbachb auerbachb marked this pull request as ready for review May 1, 2026 20:38
@auerbachb
Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 1, 2026

✅ Actions performed

Full review triggered.

Comment thread ios/fastlane/Fastfile Outdated
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 1, 2026

User cursoragent@cursor.com does not have a PR Review subscription.

Go to Team management and add this email to the PR Review subscription.

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: 1

🤖 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/docs/app-store-metadata.md`:
- Line 3: The opening paragraph in app-store-metadata.md currently implies the
markdown table and the ios/fastlane/metadata deliver files are both
authoritative; update that paragraph to state explicitly that the
machine-deliverable strings (name, subtitle, description, keywords, release
notes, URLs, review notes) in fastlane/metadata are the single source of truth
for App Store Connect uploads and that this markdown is narrative/reference
only; also change the sentence about reconciling ASC to instruct contributors to
update fastlane/metadata (or ASC) and record the change in the PR or release
notes so the two stay in sync.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9b1356a0-78f5-4829-a4c4-aff0426924e6

📥 Commits

Reviewing files that changed from the base of the PR and between 5ea7ac0 and 70736ac.

⛔ Files ignored due to path filters (1)
  • ios/Gemfile.lock is excluded by !**/*.lock
📒 Files selected for processing (22)
  • .github/workflows/ios-app-store-release.yml
  • .github/workflows/ios-testflight.yml
  • .gitignore
  • README.md
  • docs/operations/automation-evidence.md
  • docs/operations/ios-app-store-submission.md
  • ios/Gemfile
  • ios/RELEASING.md
  • ios/docs/app-store-metadata.md
  • ios/fastlane/Appfile
  • ios/fastlane/Deliverfile
  • ios/fastlane/Fastfile
  • ios/fastlane/metadata/en-US/description.txt
  • ios/fastlane/metadata/en-US/keywords.txt
  • ios/fastlane/metadata/en-US/marketing_url.txt
  • ios/fastlane/metadata/en-US/name.txt
  • ios/fastlane/metadata/en-US/privacy_url.txt
  • ios/fastlane/metadata/en-US/release_notes.txt
  • ios/fastlane/metadata/en-US/subtitle.txt
  • ios/fastlane/metadata/en-US/support_url.txt
  • ios/fastlane/metadata/review_information/notes.txt
  • scripts/ios-app-store-dry-run.mjs

Comment thread ios/docs/app-store-metadata.md
@auerbachb
Copy link
Copy Markdown
Owner Author

Please address the open review thread from CodeRabbit:

  1. Fix the finding in a single commit and push.
  2. Reply to the thread with what was changed (e.g. "Fixed in abc1234: ").
  3. After pushing, check whether GitHub automatically marks the thread as Resolved (it does this when the commented line is changed). If it is not auto-resolved, manually resolve it via the GitHub UI (click "Resolve conversation").
  4. Do not request a new review until the thread is resolved.

Open thread to address:

  • 🟡 Minor — Clarify source-of-truth wording on line 3 to avoid doc drift

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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/ios-app-store-dry-run.mjs (1)

554-559: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Populate intendedTag from the actual release tag.

Now that the report distinguishes TestFlight vs. App Store workflows, the default intendedTag fallback is misleading for App Store runs: unless callers override it, the generated summary.json / summary.md still reports ios-v<marketing>-build<build>, even when the workflow was triggered by a strict semver tag like ios-v1.0.3. That makes the release evidence wrong on the path this PR is adding.

💡 Suggested fix
+  const ciTag =
+    process.env.GITHUB_REF_TYPE === "tag" && process.env.GITHUB_REF_NAME?.startsWith("ios-v")
+      ? process.env.GITHUB_REF_NAME
+      : undefined;
-  const intendedTag = args.intendedTag ?? `ios-v${project.marketingVersion}-build${project.buildNumber}`;
+  const intendedTag =
+    args.intendedTag ?? ciTag ?? `ios-v${project.marketingVersion}-build${project.buildNumber}`;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/ios-app-store-dry-run.mjs` around lines 554 - 559, The summary
currently sets intendedTag to a generated fallback
(“ios-v<marketing>-build<build>”) which is misleading for App Store runs; update
report.preflightSummary so intendedTag is populated from the actual release tag
(e.g., the tag variable used to detect the workflow trigger such as releaseTag /
tagName / the parsed git ref) when present, and only fall back to the generated
ios-v... value if that actual tag is absent; change the assignment near
report.preflightSummary (alongside intendedTag, testflightWorkflowUrl,
appStoreReleaseWorkflowUrl) to prefer the real release tag value and preserve
existing behavior when callers explicitly override intendedTag.
🧹 Nitpick comments (1)
ios/fastlane/Fastfile (1)

29-33: ⚡ Quick win

Require shellwords before calling shellescape.

String#shellescape is provided via Ruby’s shellwords stdlib, so this lane is relying on Fastlane to load that extension transitively. If it does not, preflight dies with NoMethodError before the dry run starts. (ruby-doc.org)

💡 Suggested fix
 # frozen_string_literal: true
+require "shellwords"
 
 default_platform(:ios)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ios/fastlane/Fastfile` around lines 29 - 33, The lane preflight calls
String#shellescape (via repo_root.shellescape and release_owner.shellescape) but
never requires Ruby's shellwords stdlib; add a require 'shellwords' near the top
of the Fastfile (before lane :preflight or at file top) so the Shellwords
extension that provides shellescape is loaded and avoids a NoMethodError when
running preflight.
🤖 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-app-store-release.yml:
- Around line 195-201: The workflow uses the wrong `security` subcommand name:
replace the incorrect `security list-keychain -d user -s $KEYCHAIN_PATH
$(security list-keychains -d user | tr -d '"')` invocation with the correct
plural `list-keychains` usage so the keychain search list is set properly;
update the line containing `security list-keychain` to call `security
list-keychains` (and keep the existing flags and subshell) so certificate import
and Fastlane steps can proceed.

---

Outside diff comments:
In `@scripts/ios-app-store-dry-run.mjs`:
- Around line 554-559: The summary currently sets intendedTag to a generated
fallback (“ios-v<marketing>-build<build>”) which is misleading for App Store
runs; update report.preflightSummary so intendedTag is populated from the actual
release tag (e.g., the tag variable used to detect the workflow trigger such as
releaseTag / tagName / the parsed git ref) when present, and only fall back to
the generated ios-v... value if that actual tag is absent; change the assignment
near report.preflightSummary (alongside intendedTag, testflightWorkflowUrl,
appStoreReleaseWorkflowUrl) to prefer the real release tag value and preserve
existing behavior when callers explicitly override intendedTag.

---

Nitpick comments:
In `@ios/fastlane/Fastfile`:
- Around line 29-33: The lane preflight calls String#shellescape (via
repo_root.shellescape and release_owner.shellescape) but never requires Ruby's
shellwords stdlib; add a require 'shellwords' near the top of the Fastfile
(before lane :preflight or at file top) so the Shellwords extension that
provides shellescape is loaded and avoids a NoMethodError when running
preflight.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f80d9f7c-4561-416d-8313-c1a6c1362315

📥 Commits

Reviewing files that changed from the base of the PR and between 70736ac and fa501f1.

⛔ Files ignored due to path filters (1)
  • ios/Gemfile.lock is excluded by !**/*.lock
📒 Files selected for processing (22)
  • .github/workflows/ios-app-store-release.yml
  • .github/workflows/ios-testflight.yml
  • .gitignore
  • README.md
  • docs/operations/automation-evidence.md
  • docs/operations/ios-app-store-submission.md
  • ios/Gemfile
  • ios/RELEASING.md
  • ios/docs/app-store-metadata.md
  • ios/fastlane/Appfile
  • ios/fastlane/Deliverfile
  • ios/fastlane/Fastfile
  • ios/fastlane/metadata/en-US/description.txt
  • ios/fastlane/metadata/en-US/keywords.txt
  • ios/fastlane/metadata/en-US/marketing_url.txt
  • ios/fastlane/metadata/en-US/name.txt
  • ios/fastlane/metadata/en-US/privacy_url.txt
  • ios/fastlane/metadata/en-US/release_notes.txt
  • ios/fastlane/metadata/en-US/subtitle.txt
  • ios/fastlane/metadata/en-US/support_url.txt
  • ios/fastlane/metadata/review_information/notes.txt
  • scripts/ios-app-store-dry-run.mjs
✅ Files skipped from review due to trivial changes (14)
  • ios/fastlane/metadata/en-US/subtitle.txt
  • ios/fastlane/metadata/en-US/marketing_url.txt
  • .gitignore
  • ios/fastlane/metadata/en-US/name.txt
  • ios/fastlane/metadata/en-US/keywords.txt
  • ios/fastlane/metadata/en-US/support_url.txt
  • ios/fastlane/metadata/en-US/release_notes.txt
  • ios/Gemfile
  • ios/fastlane/metadata/en-US/privacy_url.txt
  • .github/workflows/ios-testflight.yml
  • ios/fastlane/Deliverfile
  • ios/fastlane/Appfile
  • ios/docs/app-store-metadata.md
  • ios/fastlane/metadata/en-US/description.txt

Comment thread .github/workflows/ios-app-store-release.yml Outdated
@auerbachb
Copy link
Copy Markdown
Owner Author

Fixed in 1f4654f: corrected security list-keychainsecurity list-keychains (plural is the valid macOS subcommand) and quoted $KEYCHAIN_PATH.

@auerbachb
Copy link
Copy Markdown
Owner Author

@cursor review

@auerbachb
Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 2, 2026

✅ Actions performed

Full review triggered.

Comment thread ios/fastlane/Fastfile
@auerbachb
Copy link
Copy Markdown
Owner Author

Fixed in 187c092: created ios/ExportOptionsFastlane.plist with destination=export and updated the build lane to use it. ExportOptions.plist (destination=upload) is preserved for the direct xcodebuild TestFlight workflow; deliver now handles the App Store binary upload exclusively.

@auerbachb
Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@auerbachb
Copy link
Copy Markdown
Owner Author

@graphite-app re-review

@auerbachb
Copy link
Copy Markdown
Owner Author

@cursor review

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: 3

🧹 Nitpick comments (1)
ios/Gemfile (1)

5-5: Tighten the Fastlane version range for more predictable patch updates.

On Line 5, ~> 2.227 allows any 2.* release. Although a committed Gemfile.lock pins to 2.233.1 today, tightening to ~> 2.227.0 constrains future updates to patch releases within the 2.227.x series for added safety.

Proposed change
-gem "fastlane", "~> 2.227"
+gem "fastlane", "~> 2.227.0"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ios/Gemfile` at line 5, Update the Fastlane gem declaration in the Gemfile:
replace the loose version specifier gem "fastlane", "~> 2.227" with a tighter
patch-only constraint (e.g., "~> 2.227.0") so future Bundler updates stay within
the 2.227.x series; edit the line containing gem "fastlane" to use the new
version specifier and run bundle install to update Gemfile.lock.
🤖 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-app-store-release.yml:
- Around line 192-193: The macOS runner's base64 is BSD and doesn't accept
--decode; update the two decode commands that use BUILD_CERTIFICATE_BASE64 and
BUILD_PROVISION_PROFILE_BASE64 to use the BSD flag -D and quote the output path
variables CERTIFICATE_PATH and PP_PATH (e.g., use -D and "$CERTIFICATE_PATH",
"$PP_PATH") to ensure compatibility and safe handling of spaces/special chars.

In `@ios/fastlane/Deliverfile`:
- Around line 6-7: The comment above the submit_for_review call is out of sync
with the actual default; update the comment to match the setting used by
submit_for_review(false) (or if CI should auto-submit, change the call to
submit_for_review(true)). Specifically, either revise the comment to state
“Default: do not auto-submit; CI sets submit_for_review(true) when releasing” to
match submit_for_review(false), or change the submit_for_review(...) invocation
to true so the code matches the existing comment.

In `@ios/RELEASING.md`:
- Around line 84-97: The docs currently state that "bundle exec fastlane
release" is screenshots-only but Fastfile defines the release lane as preflight
+ gym + deliver (which uploads the IPA); remove or update the stale
screenshots-only reference and explicitly note that fastlane release runs
preflight, builds (gym) and runs deliver (which will upload binaries), and add
the correct command/lane for screenshots-only (e.g., metadata_only or a
dedicated screenshots lane) so readers use metadata_only (or the named
screenshots lane) when they only intend to push screenshots; refer to the lane
names release, preflight, build/gym, deliver, and metadata_only in the Fastfile
to locate and align the documentation.

---

Nitpick comments:
In `@ios/Gemfile`:
- Line 5: Update the Fastlane gem declaration in the Gemfile: replace the loose
version specifier gem "fastlane", "~> 2.227" with a tighter patch-only
constraint (e.g., "~> 2.227.0") so future Bundler updates stay within the
2.227.x series; edit the line containing gem "fastlane" to use the new version
specifier and run bundle install to update Gemfile.lock.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b49c57b2-a95b-4aee-84cb-616d3c57bdeb

📥 Commits

Reviewing files that changed from the base of the PR and between b0e5473 and a25eecb.

⛔ Files ignored due to path filters (1)
  • ios/Gemfile.lock is excluded by !**/*.lock
📒 Files selected for processing (23)
  • .github/workflows/ios-app-store-release.yml
  • .github/workflows/ios-testflight.yml
  • .gitignore
  • README.md
  • docs/operations/automation-evidence.md
  • docs/operations/ios-app-store-submission.md
  • ios/ExportOptionsFastlane.plist
  • ios/Gemfile
  • ios/RELEASING.md
  • ios/docs/app-store-metadata.md
  • ios/fastlane/Appfile
  • ios/fastlane/Deliverfile
  • ios/fastlane/Fastfile
  • ios/fastlane/metadata/en-US/description.txt
  • ios/fastlane/metadata/en-US/keywords.txt
  • ios/fastlane/metadata/en-US/marketing_url.txt
  • ios/fastlane/metadata/en-US/name.txt
  • ios/fastlane/metadata/en-US/privacy_url.txt
  • ios/fastlane/metadata/en-US/release_notes.txt
  • ios/fastlane/metadata/en-US/subtitle.txt
  • ios/fastlane/metadata/en-US/support_url.txt
  • ios/fastlane/metadata/review_information/notes.txt
  • scripts/ios-app-store-dry-run.mjs

Comment thread .github/workflows/ios-app-store-release.yml Outdated
Comment thread ios/fastlane/Deliverfile Outdated
Comment thread ios/RELEASING.md
- Add '!ios-v*-build*' exclusion so TestFlight build tags
  (ios-v*-build*) no longer trigger the App Store release workflow
- Fix base64 --decode → -D for macOS BSD base64 compatibility;
  quote CERTIFICATE_PATH and PP_PATH variables
- Update dry-run A4 check to match new glob pattern 'ios-v*.*.*'
- Fix Deliverfile comment: CI does not submit unless SUBMIT_FOR_REVIEW=1
- Fix RELEASING.md stale alias: fastlane release now runs
  preflight + gym + deliver, not screenshots-only

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@auerbachb
Copy link
Copy Markdown
Owner Author

Fixed in c55bbc6: ios/RELEASING.md line 156 — removed stale 'fastlane release = screenshots-only' alias; clarified that 'fastlane release' now runs preflight + gym + deliver. Screenshot-only uploads use 'fastlane upload_app_store_screenshots'.

@auerbachb
Copy link
Copy Markdown
Owner Author

@cursor review

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: 1

🤖 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-app-store-release.yml:
- Around line 135-136: The workflow currently runs the "Generate App Store
submission dry-run evidence" step without APPSTORE_APP_ID/ASC credentials and
also sets SKIP_PREFLIGHT="1", so queryAsc() returns { live: false } and no live
preflight validation runs; to fix, either remove SKIP_PREFLIGHT or ensure the
dry-run step is executed with the ASC env vars (APPSTORE_APP_ID and API
credentials) so queryAsc() can detect live=true and Fastlane's preflight/dry-run
actually validates the build before deliver; update the step that sets
SKIP_PREFLIGHT (env SKIP_PREFLIGHT) or the step named "Generate App Store
submission dry-run evidence" to include the necessary APPSTORE_*/ASC env
variables accordingly.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7def8293-ea6c-4e2e-82e1-e3f786c1c513

📥 Commits

Reviewing files that changed from the base of the PR and between a25eecb and c55bbc6.

📒 Files selected for processing (4)
  • .github/workflows/ios-app-store-release.yml
  • ios/RELEASING.md
  • ios/fastlane/Deliverfile
  • scripts/ios-app-store-dry-run.mjs
✅ Files skipped from review due to trivial changes (1)
  • ios/fastlane/Deliverfile
🚧 Files skipped from review as they are similar to previous changes (1)
  • scripts/ios-app-store-dry-run.mjs

Comment thread .github/workflows/ios-app-store-release.yml
Comment thread .github/workflows/ios-app-store-release.yml
Comment thread .github/workflows/ios-app-store-release.yml Outdated
- Add actions/setup-node@v4 (node-version: 22) to fastlane-release job
  before the dry-run step, matching the version pinned in pre-flight-tests
- Pipe MARKETING_VERSION sed extraction through xargs to trim trailing
  whitespace — unquoted YAML values with trailing spaces would cause a
  false version mismatch

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@auerbachb
Copy link
Copy Markdown
Owner Author

@cursor review

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 6ceb4c2. Configure here.

const workflowSecretRefs = requiredWorkflowSecrets.filter((secret) => workflow.includes(`secrets.${secret}`));
const workflowSecretRefs = requiredWorkflowSecrets.filter(
(secret) => workflow.includes(`secrets.${secret}`) && releaseWorkflow.includes(`secrets.${secret}`),
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Secret check requires both workflows causing fragile validation

Low Severity

The workflowSecretRefs filter uses && requiring every secret to appear in both workflow files. If a future refactor removes a secret reference from one workflow (e.g., TestFlight stops needing APPSTORE_API_* directly), the dry-run would report all those secrets as "missing" even though the App Store release workflow still references them. An || (either workflow references the secret) would correctly validate that at least one workflow uses each required secret.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 6ceb4c2. Configure here.

The dry-run treated a secret as present only when both TestFlight and
App Store release workflows referenced it. Use OR so a secret
referenced by either workflow satisfies B2, matching how secrets are
actually consumed when workflows diverge.

Co-authored-by: Bretton Auerbach <auerbachb@users.noreply.github.com>
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 5, 2026

User cursoragent@cursor.com does not have a PR Review subscription.

Go to Team management and add this email to the PR Review subscription.

@auerbachb auerbachb merged commit a5e5ba5 into main May 5, 2026
15 checks passed
@auerbachb auerbachb deleted the cursor/ios-app-store-fastlane-3945 branch May 5, 2026 15:28
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 8, 2026

CodeAnt AI is running the review.

@codeant-ai codeant-ai Bot added size:XL This PR changes 500-999 lines, ignoring generated files and removed size:XL This PR changes 500-999 lines, ignoring generated files labels May 8, 2026
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 8, 2026

Sequence Diagram

This PR introduces a separate tag-triggered GitHub workflow for App Store releases using Fastlane and refines the dry-run evidence flow, while splitting tags so TestFlight uploads and App Store metadata plus binary uploads are triggered independently.

sequenceDiagram
    participant Dev as Developer
    participant GH as GitHub
    participant TF as TestFlight workflow
    participant AS as App Store release workflow
    participant DryRun as Dry run script
    participant FL as Fastlane
    participant ASC as App Store Connect

    Dev->>GH: Push ios-v*-build* tag
    GH->>TF: Trigger TestFlight build upload

    Dev->>GH: Push ios-vMAJOR.MINOR.PATCH tag
    GH->>AS: Trigger App Store release workflow
    AS->>DryRun: Run ios app store dry run
    AS->>FL: Run fastlane release lane
    FL->>ASC: Upload metadata and binary without submission
    ASC-->>FL: Accept upload
    FL-->>AS: Report release upload status
Loading

Generated by CodeAnt AI

Comment thread ios/fastlane/Fastfile
Comment on lines +7 to +17
def asc_api_key_id
ENV["APP_STORE_CONNECT_API_KEY_ID"] || ENV.fetch("APPSTORE_API_KEY_ID")
end

def asc_api_key_issuer_id
ENV["APP_STORE_CONNECT_API_ISSUER_ID"] || ENV.fetch("APPSTORE_API_ISSUER_ID")
end

def asc_api_key_content
raw = ENV["APP_STORE_CONNECT_API_KEY_CONTENT"] || ENV.fetch("APPSTORE_API_PRIVATE_KEY")
raw.gsub("\\n", "\n")
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: These environment fallbacks use || with ENV[...], but in Ruby an empty string is truthy, so a missing/misconfigured secret that resolves to "" will not fall back to APPSTORE_* and will pass empty credentials into Fastlane. This causes authentication to fail later with less clear errors; treat empty strings as unset before choosing the fallback. [incorrect condition logic]

Severity Level: Major ⚠️
- ❌ TestFlight uploads fail when new env secrets misconfigured.
- ❌ App Store release lane `:release` breaks with empty API key.
- ⚠️ Metadata-only uploads via `:metadata_only` can also fail.
- ⚠️ Debugging failures harder due to deferred auth errors.
Steps of Reproduction ✅
1. Configure environment so `APP_STORE_CONNECT_API_KEY_ID` is defined but empty (e.g.,
GitHub secret set to `\"\"`), while legacy `APPSTORE_API_KEY_ID` remains correctly
populated; this is consumed by `asc_api_key_id` at `ios/fastlane/Fastfile:7-9`.

2. From `ios/`, run `bundle exec fastlane beta` which executes lane `:beta` at
`ios/fastlane/Fastfile:138-147`.

3. During `:beta`, `stillpoint_api_key` at `ios/fastlane/Fastfile:20-27` calls
`asc_api_key_id`, which returns the empty string from
`ENV["APP_STORE_CONNECT_API_KEY_ID"]` and never falls back to
`ENV.fetch("APPSTORE_API_KEY_ID")`.

4. `pilot` at `ios/fastlane/Fastfile:142-146` receives an `api_key` constructed with an
empty `key_id`, causing App Store Connect authentication to fail at upload time with a
less-direct error instead of failing fast on missing configuration.

Fix in Cursor | Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** ios/fastlane/Fastfile
**Line:** 7:17
**Comment:**
	*Incorrect Condition Logic: These environment fallbacks use `||` with `ENV[...]`, but in Ruby an empty string is truthy, so a missing/misconfigured secret that resolves to `""` will not fall back to `APPSTORE_*` and will pass empty credentials into Fastlane. This causes authentication to fail later with less clear errors; treat empty strings as unset before choosing the fallback.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment thread ios/fastlane/Fastfile
export_options: "ExportOptionsFastlane.plist",
output_directory: ENV["GYM_OUTPUT_DIRECTORY"] || "build",
output_name: "StillPoint.ipa",
clean: !ENV["GYM_NO_CLEAN"]
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: clean: !ENV["GYM_NO_CLEAN"] treats any non-nil string (including "0" or "false") as truthy, so setting GYM_NO_CLEAN=false still disables cleaning. Parse this env var explicitly to avoid inverted behavior and accidental dirty builds. [incorrect condition logic]

Severity Level: Major ⚠️
- ⚠️ Build lane `:build` may skip cleaning unexpectedly.
- ⚠️ TestFlight uploads via `:beta` risk using dirty builds.
- ⚠️ App Store release lane `:release` may reuse stale artifacts.
- ⚠️ Env flag semantics confusing for CI configuration owners.
Steps of Reproduction ✅
1. Set the environment variable `GYM_NO_CLEAN=false` (or `GYM_NO_CLEAN=0`) in the shell or
CI environment used to run Fastlane; this value is read at `ios/fastlane/Fastfile:134`.

2. From `ios/`, run `bundle exec fastlane build` to execute lane `:build` defined at
`ios/fastlane/Fastfile:125-136`.

3. Inside `:build`, `gym` is invoked with `clean: !ENV["GYM_NO_CLEAN"]` at
`ios/fastlane/Fastfile:134`; because any non-nil string is truthy in Ruby,
`ENV["GYM_NO_CLEAN"]` is `"false"`, so `!ENV["GYM_NO_CLEAN"]` evaluates to `false` and
cleaning is disabled despite the variable being set to `"false"`.

4. The same behavior occurs when running `bundle exec fastlane beta` (lane `:beta` at
`ios/fastlane/Fastfile:138-147`) or `bundle exec fastlane release` (lane `:release` at
`ios/fastlane/Fastfile:161-175`), both of which call `build`, leading to unintentionally
dirty builds when operators expect cleaning to occur.

Fix in Cursor | Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** ios/fastlane/Fastfile
**Line:** 134:134
**Comment:**
	*Incorrect Condition Logic: `clean: !ENV["GYM_NO_CLEAN"]` treats any non-nil string (including `"0"` or `"false"`) as truthy, so setting `GYM_NO_CLEAN=false` still disables cleaning. Parse this env var explicitly to avoid inverted behavior and accidental dirty builds.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment on lines +399 to +400
const releaseTagOk =
releaseWorkflow.includes("tags:") && releaseWorkflow.includes("'ios-v*.*.*'");
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: The tag-split validation for the App Store workflow only checks for the positive glob and does not verify the required exclusion pattern for build tags. This can incorrectly mark A4 as passing even when ios-v*-build* would also trigger the App Store workflow, causing both workflows to run on the same tag. Include an explicit check for the negative pattern ('!ios-v*-build*') as part of the A4 validation. [logic error]

Severity Level: Major ⚠️
- ❌ Dry-run A4 passes despite overlapping tag triggers.
- ⚠️ Both TestFlight and App Store workflows can run together.
- ⚠️ Tag-split contract in docs is not reliably enforced.
Steps of Reproduction ✅
1. In the App Store release workflow at `.github/workflows/ios-app-store-release.yml:3-8`,
observe the tag configuration:

   - `tags:` with patterns `'ios-v*.*.*'` and ` '!ios-v*-build*'` (lines 6-8) intended to
   run only on semver tags, excluding `ios-v*-build*` build tags.

2. In the dry-run script `scripts/ios-app-store-dry-run.mjs`, `main()` (lines 366-383)
reads both workflows into `workflow` and `releaseWorkflow` and then computes
`testflightTagOk` and `releaseTagOk` at lines 397-400:

   - `const testflightTagOk = workflow.includes("tags:") &&
   workflow.includes("'ios-v*-build*'");`

   - `const releaseTagOk = releaseWorkflow.includes("tags:") &&
   releaseWorkflow.includes("'ios-v*.*.*'");`

3. Note that `releaseTagOk` (line 399-400) only asserts that the App Store workflow
contains `tags:` and `'ios-v*.*.*'`; it does not require the exclusion pattern
`'!ios-v*-build*'`, even though the workflow itself currently has that line.

4. If a future edit removes the negative pattern from
`.github/workflows/ios-app-store-release.yml` but leaves `'ios-v*.*.*'`, then running `npm
run ios:app-store:dry-run` (script defined in `package.json:22` to invoke `node
scripts/ios-app-store-dry-run.mjs`) will still set `releaseTagOk = true`, causing
`testflightTagOk && releaseTagOk` to pass at lines 2-7 (file view 400+), and `pass("A4",
...)` is recorded, even though the App Store workflow would now also trigger on
`ios-v*-build*` tags and run concurrently with `.github/workflows/ios-testflight.yml`.

Fix in Cursor | Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** scripts/ios-app-store-dry-run.mjs
**Line:** 399:400
**Comment:**
	*Logic Error: The tag-split validation for the App Store workflow only checks for the positive glob and does not verify the required exclusion pattern for build tags. This can incorrectly mark A4 as passing even when `ios-v*-build*` would also trigger the App Store workflow, causing both workflows to run on the same tag. Include an explicit check for the negative pattern (`'!ios-v*-build*'`) as part of the A4 validation.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment on lines +420 to +422
const workflowSecretRefs = requiredWorkflowSecrets.filter(
(secret) => workflow.includes(`secrets.${secret}`) || releaseWorkflow.includes(`secrets.${secret}`),
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: Secret-reference validation now treats a secret as present if it appears in either workflow, which allows missing TestFlight references to be masked by App Store workflow references. This can produce a false B2 pass even though the TestFlight workflow is misconfigured and will fail when it needs that secret. Validate required TestFlight secrets against the TestFlight workflow itself (or check both workflows independently and fail the one that is missing refs). [logic error]

Severity Level: Major ⚠️
- ❌ TestFlight workflow can lack required secrets while B2 passes.
- ⚠️ Dry-run checklist misrepresents per-workflow secret wiring.
- ⚠️ Secret regressions in one workflow are harder to detect.
Steps of Reproduction ✅
1. In the TestFlight workflow `.github/workflows/ios-testflight.yml`, note that the upload
step at lines 222-242 sets:

   - `APPSTORE_API_KEY_ID`, `APPSTORE_API_ISSUER_ID`, `APPSTORE_API_PRIVATE_KEY` from `${{
   secrets.* }}` and uses them to create `AuthKey_${APPSTORE_API_KEY_ID}.p8` for
   `xcodebuild` upload.

2. In the App Store release workflow `.github/workflows/ios-app-store-release.yml`,
observe that the `Fastlane release` job (lines 213-223) also references the same
`APPSTORE_API_*` secrets in its environment.

3. In `scripts/ios-app-store-dry-run.mjs`, `main()` (lines 366-383) reads both workflows
into `workflow` and `releaseWorkflow`, then computes `workflowSecretRefs` at lines 21-23
(view 400+), using:

   - `const workflowSecretRefs = requiredWorkflowSecrets.filter((secret) =>
   workflow.includes(\`secrets.${secret}\`) ||
   releaseWorkflow.includes(\`secrets.${secret}\`));`

   This OR condition treats a secret as "covered" if it appears in either workflow file.

4. If `.github/workflows/ios-testflight.yml` is later edited so that, for example,
`APPSTORE_API_PRIVATE_KEY` is no longer referenced there (breaking the upload step) but
`.github/workflows/ios-app-store-release.yml` still references
`secrets.APPSTORE_API_PRIVATE_KEY`, then running `npm run ios:app-store:dry-run`
(entrypoint at `package.json:22`) will:

   - Still include `APPSTORE_API_PRIVATE_KEY` in `workflowSecretRefs` because it appears
   in `releaseWorkflow`.

   - Produce `missingWorkflowRefs.length === 0` and therefore call `pass("B2", ...)` or
   `warn("B2", ...)` at lines 39-56 (view 400+), setting `reportSecretStatus.status`
   accordingly.

   - Classify checklist item B2 via `classifyIssueChecklist()` (lines 266-311) using
   `reportSecretStatus`, so the dry-run report in
   `artifacts/ios-app-store-dry-run/summary.md` shows B2 as satisfied even though the
   TestFlight workflow is misconfigured and will fail when it reaches the `Upload to App
   Store Connect` step that now lacks a valid secret binding.

Fix in Cursor | Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** scripts/ios-app-store-dry-run.mjs
**Line:** 420:422
**Comment:**
	*Logic Error: Secret-reference validation now treats a secret as present if it appears in either workflow, which allows missing TestFlight references to be masked by App Store workflow references. This can produce a false B2 pass even though the TestFlight workflow is misconfigured and will fail when it needs that secret. Validate required TestFlight secrets against the TestFlight workflow itself (or check both workflows independently and fail the one that is missing refs).

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 8, 2026

CodeAnt AI finished running the review.

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 8, 2026

CodeAnt AI is running the review.

@codeant-ai codeant-ai Bot added size:XL This PR changes 500-999 lines, ignoring generated files and removed size:XL This PR changes 500-999 lines, ignoring generated files labels May 8, 2026
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 8, 2026

Sequence Diagram

This PR introduces a new tag-split model where strict ios-vMAJOR.MINOR.PATCH tags trigger an App Store release workflow that runs preflight tests, generates an evidence log, and then uses Fastlane to build and upload the binary and metadata without auto-submitting for review.

sequenceDiagram
    participant Developer
    participant GitHubActions as iOS App Store release workflow
    participant Fastlane
    participant AppStoreConnect

    Developer->>GitHubActions: Push ios-vMAJOR.MINOR.PATCH tag
    GitHubActions->>GitHubActions: Run release-config smoke tests
    GitHubActions->>GitHubActions: Validate tag and checklists; generate dry-run evidence
    GitHubActions->>Fastlane: Invoke release lane with App Store API key
    Fastlane->>Fastlane: Build IPA with gym
    Fastlane->>AppStoreConnect: Upload metadata and binary with deliver (no submit for review)
    AppStoreConnect-->>Developer: Binary and metadata available for manual submission
Loading

Generated by CodeAnt AI

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 8, 2026

CodeAnt AI finished running the review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL This PR changes 500-999 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Checklist: AI-assisted iOS App Store submission automation dry run

2 participants