How to set up a CI for multiple iOS and tvOS Apps using Fastlane and Bitrise

Tiago Martinho had to set up a continuous integration (CI) pipeline for multiple versions of an iOS and tvOS app and he shares how to do this in a simple way in this guest blog post.

Lately, I had to set up a continuous integration (CI) pipeline for multiple versions of an iOS and tvOS app. Since I didn’t find a lot of information on how to do this in a simple way I decided to write this blog post.

Guest post by Tiago Martinho, software entrepreneur. The original post appeared on Medium.

Tiago is a Portuguese Software entrepreneur currently working with ThoughtWorks in Barcelona. He hosts a Swift Peer lab every Saturday and loves to build mobile applications. Currently, he is trying to bootstrap a podcast about iOS and Swift with his friend Lewis.

Use Case

This post is useful if you have:

  • A White Label Application (WLA) that contains multiple variations of the same application;
  • An application that targets multiple platforms (iOS/tvOS/macOS);

And you don’t want to have duplication in your CI pipeline or have to define your environment variables in the pipeline.

In my case I have two versions (lite and premium) of a universal app (iOS and tvOS) so in total four variations.


I used the Fastlane tool to automate the tasks needed to deploy the app.

Like all tools, it has advantages and disadvantages.


  • Your pipeline is not tied to any particular service;
  • It can be run locally, in a service or in a remote machine;
  • It depends on an open-source project;


  • You need time to configure it;
  • You need time to maintain it;

If you are not familiar with Fastlane please refer to their documentation.

Fastlane Configuration

Reading the documentation of fastlane the use of environment variables seemed the best fit for my use case.

In order to load different variables for each variation of the app, you need to define a file for each variation.

In my case I defined 4 files with the following names:

  • .env.ios
  • .env.iosfree
  • .env.tvos
  • .env.tvosfree

Each file contains the variables needed to build that specific version of the application:

Copy code

For tvOS the platform is:


These variables are loaded by adding the option env when invoking fastlane:

bundle exec fastlane release --env ios
Copy code

The pipeline reads these variables and is defined in the Fastfile:

fastlane_require ‘dotenv’
before_all do
cocoapods(clean: true, repo_update: true)
 run_tests(workspace: ENV[‘WORKSPACE’], scheme: ENV[‘SCHEME’])
desc “Push a new release build to the App Store”
lane :release do
 increment_build_number(build_number: ENV[‘BITRISE_BUILD_NUMBER’], xcodeproj: ENV[‘PROJECT’])
 build_app(workspace: ENV[‘WORKSPACE’], scheme: ENV[‘SCHEME’], configuration: “Release”, clean: true)
 upload_to_app_store(skip_metadata: true, skip_screenshots: true, platform: ENV[‘PLATFORM’], app_identifier: ENV[‘APP_IDENTIFIER’], run_precheck_before_submit: false)
Copy code

This pipeline is doing the following five steps:

  • cocoapods: installing all the project dependencies with Cocoapods
  • run_tests: running the tests that verify our app works correctly
  • increment_build_number: incrementing the build number since iTunes Connect requires an ever incrementing build number
  • build_app: building our application
  • upload_to_app_store: deploying our application to iTunes Connect

Continuous Integration

Fastlane integrates effortlessly into existing CI services

I used Bitrise, but you could also use CircleCI, Travis CI, or Jenkins.

After following the guided setup from Bitrise when adding a new app you end up with all the configuration needed (Webhook, Setup of Workflow, etc.)

After this, you need to remove all the steps you don’t need. In my case, the pipeline is very simple and after cloning the project and installing the certificates it calls the appropriate Fastlane lane ‘release’:

Bitrise Pipeline

It’s also needed to setup the Secrets to build the app (FASTLANE_USER, FASTLANE_APPLE_ID, FASTLANE_PASSWORD) and verify the correct stack is selected in my case is Xcode 9.3.x on macOS 10.13.

If you also want to use Bitrise and this post was helpful please use my referral link so I can win a Bitrise t-shirt 😄.


In this blog post we saw how to automate the deploy of multiple versions of the same application for different platforms, iOS and tvOS, using Fastlane and Bitrise.

No items found.
The Mobile DevOps Newsletter

Explore more topics

App Development

Learn how to optimize your mobile app deployment processes for iOS, Android, Flutter, ReactNative, and more

Bitrise & Community

Check out the latest from Bitrise and the community. Learn about the upcoming mobile events, employee spotlights, women in tech, and more

Mobile App Releases

Learn how to release faster, better apps on the App Store, Google Play Store, Huawei AppGallery, and other app stores

Mobile DevOps

Learn Mobile DevOps best practices such as DevOps for iOS, Android, and industry-specific DevOps tips for mobile engineers

Mobile Testing & Security

Learn how to optimize mobile testing and security — from automated security checks to robust mobile testing and more.

Product Updates

Check out the latest product updates from Bitrise — Build Insights updates, product news, and more.

The Mobile DevOps Newsletter

Join 1000s of your peers. Sign up to receive Mobile DevOps tips, news, and best practice guides once every two weeks.