If you’ve ever spent your Friday afternoon manually dragging a build into Transporter, filling out the same metadata for the tenth time, and praying the upload doesn’t fail at 99%, you know that the manual process is broken. Learning how to automate app store submission isn’t just about saving time; it’s about removing the human error that leads to rejected builds and stressful release days.
In my experience managing multiple mobile projects, I found that manual submissions were the biggest bottleneck in my workflow. That’s why I moved everything to Fastlane. Whether you’re a solo dev or part of a large team, automating your pipeline allows you to focus on writing code rather than fighting with App Store Connect.
Prerequisites
Before we dive into the automation logic, ensure you have the following ready:
- A Mac with Xcode installed (for iOS automation).
- A valid Apple Developer Program membership.
- Ruby installed on your system (Fastlane is built on Ruby).
- An App Store Connect API Key (the modern way to authenticate without relying on 2FA prompts).
If you’re new to the ecosystem, I highly recommend starting with my fastlane tutorial for ios beginners to get the environment configured correctly.
Step 1: Installing and Initializing Fastlane
First, install Fastlane via RubyGems. Open your terminal and run:
gem install fastlane
Navigate to your project’s root directory and initialize Fastlane. This will create a fastlane folder containing your Fastfile and Appfile.
fastlane init
During initialization, Fastlane will ask for your Apple ID and team ID. I recommend using the App Store Connect API Key method here to avoid the dreaded two-factor authentication prompts during CI/CD runs.
Step 2: Automating Code Signing
You can’t submit a build if it isn’t signed. Managing certificates manually is a nightmare. I use match, which implements the “codesigning-as-a-service” philosophy by storing certificates in a private Git repo.
Run the following to set up your certificates:
fastlane match initfastlane match appstore
For a deeper dive into how to keep your team synced, check out my guide on automated code signing for ios best practices.
Step 3: Configuring the Fastfile for Submission
The Fastfile is where the magic happens. Instead of running individual commands, we create a “lane” that chains everything together. Here is the production-ready lane I use for my apps:
lane :release do
# 1. Sync certificates
match(type: "appstore")
# 2. Increment build number
increment_build_number(build_number: ENV["GITHUB_RUN_NUMBER"])
# 3. Build the app
build_app(scheme: "YourAppName")
# 4. Upload to TestFlight
upload_to_testflight
# 5. Submit for Review
upload_to_app_store(
submit_for_review: true,
force: true
)
end
As shown in the image below, the process transforms from a series of manual clicks in Xcode and App Store Connect into a single terminal command.
Step 4: Handling Metadata and Screenshots
One of the most tedious parts of the submission is updating the “What’s New” text and screenshots. Fastlane allows you to keep these in your Git repo. Run fastlane deliver to download your current metadata locally.
Once the files are in your fastlane/metadata folder, you can simply commit your changes to Git and run your release lane. Fastlane will push the updated text and images to the store automatically.
Pro Tips for Seamless Automation
- Environment Variables: Never hardcode your API keys in the Fastfile. Use a
.envfile or your CI/CD secrets (like GitHub Actions Secrets). - TestFlight First: Always push to TestFlight first. I’ve added a
betalane in my setup that only handles the upload to internal testers before the finalreleaselane is triggered. - Automated Screenshots: If you have dozens of languages, use
snapshotto automate the taking of screenshots across different device sizes.
Troubleshooting Common Issues
Issue: “Authentication failed”
This usually happens due to expired session cookies. Switch to the App Store Connect API Key (.p8 file) to permanently solve this.
Issue: “Version number already exists”
Ensure your increment_build_number logic is pulling from a source of truth, like a CI build counter, rather than a static number.
What’s Next?
Now that you know how to automate app store submission, the next logical step is integrating this into a CI/CD pipeline. I recommend using GitHub Actions or Bitrise to trigger these lanes automatically whenever you merge a pull request into your main branch.
Ready to scale your productivity? Explore more Mobile CI/CD tutorials to fully automate your development lifecycle.