Effortlessly Implement CD in your iOS Project: A Complete Guide to Setting up Fastlane [Part 3/3] (2023)

Aidos Mukatayev
9 min readJan 23, 2023

--

Welcome to the final part of our three-part series on creating an app in the App Store Connect and automating provisioning profiles and certificates with Fastlane.

In the previous part, you learned how to create an app in the App Store Connect and how to automate provisioning profiles and certificates in Fastlane. In this final installment, I will be showing you how to finally setup the whole fastlane pipeline up to TestFlight upload. So, let’s dive in and get started on setting up your final working Fastlane pipeline for your iOS project.

What will you learn and understand in part 3:

  • How to setup lanes for app build, test, and TestFlight upload 🚀
  • Tips and tricks related to Fastlane 🧠
  • Follow up 🏁

GitHub link

If you want to check the final project, you can access it here: https://github.com/mukatayev1/SomeApp-Fastlane-Tutorial

Lets Continue.

Let’s start from the table of contents.

The following is the table of contents Part 3:

Part 3 Table of contents:

  • Step 4. Fastfile Lane 2: Running tests
  • Step 5. Fastfile Lane 3: Project build
  • Step 6. Fastfile Lane 5: Testflight upload
  • Step 7. Full pipeline test
  • Useful tips and tricks
  • Conclusion and follow up.

Where did we stop?

  • In the last part of the Part 2, we completed the setup of the initial lane known as “match_certificates”. The next phase involves configuring the remaining pipeline stages to enable the capability of uploading the app to TestFlight. Let’s continue

Step 4. Fastfile Lane 2: Running tests

The second lane that we are going to work on is related to unit tests. Whenever you want to do a build delivered to the testflight, you always want to make sure that your project passes all unit tests successfully. And to enable automatic running of the tests in the fastlane we are going to use a fastlane’s tool called “Scan”.

Setup Scan

Fstlane Scan action

The easiest way to run tests of your iOS and Mac app

scan makes it easy to run tests of your iOS and Mac app on a simulator or connected device.

This tool is pretty easy to enable, however, it has a very nice set of configurations that you can acecss with this link: link. But for the sake of simplicity we are going to focus on unit tests here.

Let’s open a Fastfle and create a new lane called ‘run_unit_tests’.

#Tests
desc "Run all the tests"
lane :run_unit_tests do
scan(
scheme: "SomeApp",
clean: true,
devices: ["iPhone 13 Pro"]
)
end

Here is what it does: This lane uses a scan action and we selected a scheme of the main app target “SomeApp” to run the tests, clean the project before tests and the device to run unit tests on needs to be an iPhone 13 Pro.

Let’s test this action by running the following action in the terminal

fastlane run_unit_tests

That’s it. That’s how simple it is to run the tests! The following is the result of the test results.

Fastlane run_unit_tests lane results

Scan + Slack

There is one thing that I really liked about scan its ability to communicate the test results to the slack. If you have a slack workspace, you can simply create a slack web hook, get the url of the webhook and insert to the scan action as argument. Example:

scan(
scheme: "App scheme",
clean: true,
devices: ["iPhone 14"],
slack_url: "https://hooks.slack.com/services/web_hook_id"
)

This is how your channel slack message may look like:

Slack web hook message from Fastlane tests lane

Step 5. Fastfile Lane 3: Project build

Fstlane gym action

gym builds and packages iOS apps for you. It takes care of all the heavy lifting and makes it super easy to generate a signed ipa or appfile 💪

To be able to upload the app, we need to archive or so to say package the app. Here gym action comes in. Gym allows us to easily package the app with all necessary, check more about customizations here: link.

Now let’s implement gym to our build. Open Fastfile and paste the following code:

#Gym/Build app
desc "Build the app"
lane :gym_app do
match_certificates
increment_build_number
gym(scheme: "SomeApp")
git_commit(path: "*", message: "Bump build to #{get_build_number}")
end

This is a Fastlane lane called “gym_app” that does the following:

  1. It runs the match_certificates lane that we created earlier to ensure that all of your development and distribution certificates are valid and up-to-date before starting the build.
  2. It runs the increment_build_number command, which increments the build number of the app. This step is crucial as, when we package the app and want to upload it to TestFlight, the build number of the project must always be unique. To avoid any issues with duplicate build numbers, we always run the increment_build_number action before starting the build. This action is already available in Fastlane and you can learn more about it in the official documentation (link)
  3. It runs the gym command, which is used to build and archive an iOS app. The scheme option is set to "SomeApp", specifying the build scheme to use. The gym command has many other configuration options that you can learn more about in the official documentation.
  4. It runs the git_commit command, which commits the changes made to the codebase with the message "Bump build to #{get_build_number}". get_build_number is the current build number of the app.

What about version number increment?

Note: When it comes to incrementing the version number, there is an action available in Fastlane called increment_version_number which can be used to increment the version number across major, minor, or patch numbers. However, I personally prefer to manage version numbers manually as it allows for more control and the ability to review and confirm the version number before making any changes.

Manually managing version numbers also allows for more flexibility in terms of when and how the version number is incremented. If you prefer to implement version increment automatically, you can insert the increment_version_number action in the provided lane and refer to the official documentation for guidance on how to configure it.

Let’s navigate to our project directory and run the lane in the command line.

fastlane gym_app

After running the lane, you will notice that this lane is slightly more complex than previous ones, as it includes several steps that are executed one after the other. However, upon completion of the process, you will find the new .ipa and .dSYM files in the specified directory. This indicates that the project has been successfully exported and you can proceed to upload the exported file to TestFlight for beta testing.

new package files generated.

Let’s move on to our last steps of our pipeline!

Step 6. Fastfile Lane 5: TestFlight upload

The final step in the process is to upload the packaged file to TestFlight. To accomplish this, we will be using an action called pilot. This action is specifically designed for uploading builds to TestFlight, and it can be configured to handle various options that you can access here.

Fastlane Pilot action

Pilot makes it easier to manage your app on Apple’s TestFlight. You can:

Upload & distribute builds

Add & remove testers

Retrieve information about testers & devices

Import/export all available testers

To use the pilot action, you will need to have the App Store Connect API key ID, issuer ID, and .p8 authentication key file. While there are other methods of authentication available like Apple ID, using App Store Connect API is considered to be a best practice as it is secure and efficient. Let’s start executing it.

First of all, we need to import the following values to the Fastfile from our .env.default file:

  • App Store Connect API’s key ID
app_store_connect_api_key_id = "#{ENV["APP_STORE_CONNECT_API_KEY_KEY_ID"]}"
  • App Store Connect API’s issuer ID
app_store_connect_api_issuer_id = "#{ENV["APP_STORE_CONNECT_API_KEY_ISSUER_ID"]}"
  • App Store Connect API’s .p8 authentication key content
app_store_connect_api_p8_contents = File.read("#{ENV["app_store_connect_api_file_path"]}")

So totally in the top of the Fastfile you need to have something like this:

Fastfile variables

Next, we will create a lane that utilizes the App Store Connect API key, along with the variables we previously defined, to initiate the upload to TestFlight.

    #TestFlight upload
desc "Upload to TestFlight"
lane :pilot_to_testflight do
api_key = app_store_connect_api_key(
key_id: app_store_connect_api_key_id,
issuer_id: app_store_connect_api_issuer_id,
key_content: app_store_connect_api_p8_contents
)

pilot(api_key: api_key)
end

This lane is called “upload_to_testflight” and it uses the App Store Connect API key and values that were created earlier to initiate the pilot action. The lane creates the API key and then passes it as an argument to the pilot action, thus automating the process of uploading builds to TestFlight.

Let’s test this lane and see the results! Type the following command to terminal

fastlane pilot_to_testflight

The result is success!

And if we go to App Store Connect TestFlight section, we can see that our build was successfully uploaded!

App Store Connect TestFlight!

Great job! You have successfully uploaded your app to TestFlight. The final step of the pipeline is complete and you can now invite testers to test your app. You can do this either by using fastlane, as outlined in the documentation, or by manually setting up testers on the App Store Connect portal.

Step 7. Full pipeline test

Since we completed the last step of the pipeline, now we can put everything together into one lane that will be called “beta_upload”.

Just copy and paste the code below:

desc "Upload beta to TestFlight"
lane :beta_upload do
run_unit_tests
gym_app
pilot_to_testflight
end

This lane is designed for uploading new versions of the app to TestFlight. To use it, simply enter “fastlane beta_upload” in the terminal and the entire pipeline will automatically execute. It’s that easy! Make sure you have configure the pipeline properly before using the command.

Congratulations on finishing the fastlane setup and configuration! You can now use this pipeline as a template for your project and customize it to fit the needs of your own app. Keep in mind that the provided pipeline is tailored specifically for the needs of this app, and you will need to ensure that your pipeline meets the distribution requirements of your own app.

Useful tips and tricks

Slack Integration

Integrating Slack with fastlane creates a powerful combination that allows for easy viewing of fastlane logs, errors, results, and upload notifications. To learn more about using Slack with fastlane, refer to the following link: link

GitHub Fastfile References

For additional inspiration, check out this useful but slightly dated GitHub repository that contains a variety of Fastfile example setups for you to explore and analyze. Check out the link: link

Conclusion and follow up

Thank you for reading my article on implementing Fastlane for iOS project. I hope you found it informative and helpful. If you have any further questions or would like to share your thoughts on the topic, please leave a comment below. Thanks for your support and you can contact me everywhere:

You can check the Part 1 and Part 2 too!

LinkedIn: https://www.linkedin.com/in/aidosmukatayev/

GitHub: https://github.com/mukatayev1

--

--