How do I automatically submit and release production apps to the App Store and Google Play from my Codemagic pipeline?
Last updated: August 3, 2026
Context
When publishing apps to the App Store and Google Play, you may want your Codemagic pipeline to automatically submit builds for production review and release them after approval — without any manual steps in the store consoles. This article covers how to configure this, including scenarios where the submission decision needs to be made dynamically at runtime (e.g., based on whether a live version already exists in the store).
Answer
There are two approaches depending on whether your submission logic is static or determined at runtime during the build.
Option 1: Static configuration via the publishing block
If your submission settings are fixed and do not need to change based on runtime conditions, you can configure the publishing section of your codemagic.yaml directly:
publishing:
app_store_connect:
auth: integration
submit_to_testflight: true
submit_to_app_store: true # sends the build to App Store review, not just TestFlight
release_type: AFTER_APPROVAL # MANUAL (default), AFTER_APPROVAL, or SCHEDULED
google_play:
credentials: $GOOGLE_PLAY_SERVICE_ACCOUNT_CREDENTIALS
track: production
submit_as_draft: false # set to false so the build is submitted, not left as a draft
Key points:
iOS: Setting
submit_to_app_store: truepushes the build to full App Store review rather than stopping at TestFlight. Settingrelease_type: AFTER_APPROVALmakes the version go live automatically once Apple approves it. Other options areMANUAL(you release it yourself) andSCHEDULED(release on a date set viaearliest_release_date). See the App Store Connect publishing docs for more details.Android: Ensure
$GOOGLE_PLAY_SERVICE_ACCOUNT_CREDENTIALSis set as a secure environment variable containing the JSON key for your Google Play service account. See the Google Play publishing docs for setup instructions. Note that whether an approved release goes live automatically is also controlled by the Managed publishing setting in the Play Console — if Managed publishing is off, changes are published as soon as Google approves them; if it's on, you must manually publish from the Publishing overview page.
Important: Environment variables used in the publishing block must be defined statically under the environment.vars section of your workflow. They cannot be set or overridden by scripts running during the build, as the publishing block is evaluated as a pre-build configuration. For example:
environment:
vars:
SUBMIT_TO_APP_STORE: true
publishing:
app_store_connect:
auth: integration
submit_to_app_store: $SUBMIT_TO_APP_STORE
If you need to toggle these values without editing the YAML, you can pass them in the API trigger payload when starting a build — variables provided at trigger time are available at build start and will resolve correctly in the publishing block.
Option 2: Runtime submission using Codemagic CLI tools
If your submission decision depends on runtime conditions (e.g., checking whether a live version already exists in the store), you should remove the publishing block and handle submission directly in a build script using the Codemagic CLI tools, which are pre-installed on the build VM.
For iOS, add a script step after your build:
PUBLISH_FLAGS="--testflight"
LIVE_BUILD=$(app-store-connect get-latest-app-store-build-number "$APP_APPLE_ID" || true)
if [ -n "$LIVE_BUILD" ]; then
PUBLISH_FLAGS="$PUBLISH_FLAGS --app-store --release-type AFTER_APPROVAL"
fi
app-store-connect publish --path "build/ios/ipa/*.ipa" $PUBLISH_FLAGS
The --app-store flag pushes the build to full App Store review instead of stopping at TestFlight. The --release-type AFTER_APPROVAL flag makes it go live automatically once Apple approves.
For Android, add a script step after your build:
DRAFT_FLAG="--draft"
PRODUCTION_BUILD=$(google-play get-latest-build-number --package-name "$BUNDLE_IDENTIFIER" --tracks production)
if [ -n "$PRODUCTION_BUILD" ]; then
DRAFT_FLAG="" # omit --draft so it's a real submission, not a draft
fi
google-play bundles publish \
--bundle "android/app/build/outputs/**/*.aab" \
--track production \
$DRAFT_FLAG
Important: If you switch to the CLI approach, make sure to remove the corresponding publishing: block from your YAML — otherwise the build will submit to the store twice.
For further reference, see the CLI tool documentation for app-store-connect publish and google-play bundles publish.