DEV Community

孫昊
孫昊

Posted on

The 1-line Fastlane fix that auto-releases your iOS app when Apple approves

Three of my iOS apps auto-released this morning while I was asleep.

  • DaysUntil v1.0.20 — LIVE 11:32 JST
  • HabitHash v1.0.1 — LIVE 11:32 JST
  • FocusFlow Lite v1.0.10 — LIVE 11:32 JST (propagating)

I did not click "Release this Version" in App Store Connect. The release fired automatically the moment Apple's reviewer marked the version approved.

That is releaseType: AFTER_APPROVAL. Here is the 1-line Fastlane fix that turns it on.

What MANUAL release type costs you

By default, every App Store version you create has releaseType: MANUAL. That means after Apple approves, the version sits in state PENDING_DEVELOPER_RELEASE until you click a button.

For a launch with a marketing window, MANUAL makes sense — you want to control the timing.

For a fix tagged at 2am after a 2.1(b) rejection? You don't want to be the bottleneck. But MANUAL forces you to be.

Real numbers from my own ops log:

  • 6 of my last 8 rejections were on metadata or IAP relationship strings
  • All 6 were fixed within 20 minutes once I had the diagnosis
  • Apple approval came back within hours, often while I was asleep in JST
  • Each one sat in PENDING_DEVELOPER_RELEASE for 4–8 hours waiting for me to wake up and click

That is dead time I do not need to own.

The fix in Fastfile

lane :release do
  api_key = app_store_connect_api_key(
    key_id:      ENV["ASC_KEY_ID"],
    issuer_id:   ENV["ASC_ISSUER_ID"],
    key_content: ENV["ASC_API_KEY_CONTENT"],
  )

  upload_to_app_store(
    api_key:                  api_key,
    skip_binary_upload:       true,
    skip_screenshots:         true,
    skip_metadata:            false,
    automatic_release:        true,   # <- this is the line
    submit_for_review:        true,
    submission_information:   { add_id_info_uses_idfa: false },
    precheck_include_in_app_purchases: false,
  )
end
Enter fullscreen mode Exit fullscreen mode

automatic_release: true is what flips the releaseType from MANUAL to AFTER_APPROVAL. That is it. One line, one bool.

Verifying the change at the API level

After upload, hit the ASC API and check the version detail:

GET https://api.appstoreconnect.apple.com/v1/appStoreVersions/{version_id}
Enter fullscreen mode Exit fullscreen mode

You want to see:

{
  "attributes": {
    "appStoreState": "WAITING_FOR_REVIEW",
    "releaseType": "AFTER_APPROVAL",
    "earliestReleaseDate": null,
    ...
  }
}
Enter fullscreen mode Exit fullscreen mode

If releaseType says MANUAL after upload, the Fastlane lane did not pass automatic_release: true through to ASC. Re-check the lane.

What happens after approval

Apple's reviewer flips the ASV state to READY_FOR_DISTRIBUTION (in some accounts it briefly passes through PENDING_DEVELOPER_RELEASE before auto-firing). Then within minutes:

  • ASV state → READY_FOR_SALE
  • iTunes Lookup (per-region) updates within 5–30 minutes, sometimes up to 90 minutes for the US/JP storefronts

You will not get a separate "release fired" email. The same approval email is the LIVE signal. Check iTunes Lookup to confirm:

curl -s "https://itunes.apple.com/lookup?bundleId=com.your.bundle&country=us" | jq '.results[0].version'
Enter fullscreen mode Exit fullscreen mode

If that returns your new version string, you are LIVE.

When MANUAL is still the right choice

Two cases where AFTER_APPROVAL is wrong:

  1. Coordinated marketing launch. You want LIVE timed with a tweet, an email, a podcast. Stay on MANUAL and trigger via POST /v1/appStoreVersionReleaseRequests when ready.

  2. Phased release. If you are using App Store phased rollout (7-day automatic ramp), the release request triggers the rollout — you want manual control of when the phasing starts.

For everything else — bug fixes, rejection resubmits, point updates — automatic_release: true removes you from the critical path.

Why nobody talks about this

Fastlane's docs mention automatic_release but bury it in the deliver reference. The Apple docs mention releaseType but describe it as a one-time choice at submission. Nothing in either source connects them as the cause-and-effect they actually are.

I learned this after rejecting myself the 8th time and finally noticing that one of my apps auto-released while the other three sat waiting. Same Fastfile, different copy of the upload_to_app_store call. The auto-releaser had automatic_release: true. The waiters did not.

Today's auto-release wave was the first time I had it consistent across all in-flight apps. Three approved + released without me touching anything.

If you are shipping iOS apps as an indie or small team, this one line removes one of the most common reasons you wake up at 6am to "release this version."


About this article: part of an ongoing log of what I have learned shipping 8 iOS apps in 90 days with one Claude Code agent driving the App Store Connect API. Verified LIVE on App Store — all 8 apps, links on https://jiejuefuyou.github.io/b2b-pipeline.html

If you have an Apple rejection in flight and want a second pair of eyes, the Calendly is on the pipeline page. 15-min calls, fixed fee, no pitch deck.

Top comments (0)