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:

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 init
fastlane 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.

Comparison of manual Xcode upload process vs Fastlane terminal automation
Comparison of manual Xcode upload process vs Fastlane terminal automation

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

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.