June 2, 2022

My first contribution to Fastlane

Read Time: 📖 5 minutes

Found a mistake? Edit on Github!

I have recently contributed for the first time to one of the tools that I have used the most in my career as an iOS developer: fastlane. Fastlane is a CI/CD tool which allows iOS and Android developers to automate processes such as uploading binaries to App Store Connect (or Play Store), screenshot generation or running tests and building projects, amongst many others.

In the following sections, I will walk through the changes and the motivation behind them as well as sharing a couple of thoughts on the process.

Motivation and context

A couple of weeks ago, I embarked on a journey at work to modernise the way we upload app archives to App Store Connect. Specifically, our implementation relied on the use of the Application Loader Tool, most commonly known as altool, and its --upload-app flag. We used a combination of username and password for authentication and a path to an App Store signed ipa file to be uploaded.

# This command uploads a binary to App Store Connect
xcrun altool --upload-app -f ipa_path -t ios -u username -p password

While this had been working fine, we wanted to move towards a more modern and robust approach and make use of a fastlane action that would achieve the same result. The main reason for the change was to have better access to feedback and support from the fastlane community when encountering any issues and the improvements we could make as part of this process, such as sharing authentication between multiple fastlane actions and teams across our company and improving our CI's performance and reliability.

Making this leap forward would also allow us to make use of the App Store Connect API (which is what fastlane uses under the hood when provided with an api key) and replace our username/password authentication credentials with a generated key, which can be revoked at any time.

After doing some research, we chose to make use of fastlane's deliver action, as it would allow us to submit binaries to App Store Connect while also future-proofing our implementation, as it has features such as uploading the app's metadata and screenshots as part of the release pipeline and check it against community-gathered guidelines, to reduce the chances of our app being rejected by Apple.

We then proceeded to create an api key and replace our usage of altool with the new deliver action in our Fastfile, which I have to say was very straight-forward.

That's it, job done! ⭐️ Well,... not quite. We had another usage of altool that we ideally wanted to replace with a fastlane action. In this particular case, altool was used to validate an App Store signed ipa with the App Store Connect without actually uploading it (by calling it with the --validate-app flag) — much like a dry run of --upload-app. We run this workflow on a nightly basis and it has proven very useful to us as it can warn us of any issues before it is time for us to do a release.

# This command verifies a binary with App Store Connect
xcrun altool --validate-app -f ipa_path -t ios -u username -p password

After digging through fastlane's documentation, issues and reading through Apple forums trying to find replacements for the altool --validate-app command I could not find anything that suited our needs. I then decided to start a Github Discussion in fastlane's repo to ask if there was something I could use that would suit my needs or if the contributors thought that this would be a nice feature to have within deliver.

The process

Not long after asking — literally on the same day! 🤩 — Lukas Grabowsky (@lucgrabowski), one of fastlane's contributors, replied saying that, while such feature did not exist, it was possible to add it to deliver by making use of an iTunes Transporter flag called verify. This looked ideal!

iTunes Transporter is a tool provided by Apple to handle content delivery to multiple Apple platforms, one of them being App Store Connect. This is the tool which fastlane uses under the hood to deliver any application archives or metadata to App Store Connect.

After being pointed in the right direction as to where the iTunes Transporter and deliver code could be found, I forked the fastlane repo and began with my implementation. It was surprisingly simple to get to grips with the deliver/transporter code (won't go into much detail about it, will link to the Pull Request below) and create a new verify command, as it was not too dissimilar from the upload command that already existed in the iTunes Transporter runner class.

Once I had a prototype working, I went over and read the CONTRIBUTING.md file and the guide on opening a first PR, which helped me tidy up the code, write tests around the implementation and get the changes ready for a pull request to be opened. This eventually made its way into the 2.206.0 release, courtesy of the awesome Josh Holtz (@joshholtz), in the form of a new flag for the deliver command called verify_only. If you are interested in the implementation details, you can find the pull request here.

The resulting flag can be used as follows form version 2.206.0 of fastlane (or alternatively form a project's Fastfile):

bundle exec fastlane deliver --verify_only --ipa <path_to_your_api>

This command would then report errors such as the binary being built with a toolchain which was not suitable for the App Store — such as a beta version of Xcode:

A screenshot showing the captured output of an error generated by the new verify-only flag.


To sum up and give a couple of thoughts after doing this work, I would like to say that I thoroughly enjoyed working on adding this flag to the repo, as it helped me get a better understanding of the way the tool works and it ultimately solved a particular use case that might prove useful to other developers.

I would also like to encourage any developer to go ahead and submit pull requests or open discussions on any open source projects that they have an idea/improvement/fix for. Maintainers will really appreciate it and, aside from it being a great learning process, it is a way of giving back to tools that we take for granted and we can help support. I will definitely be keeping my eyes peeled for any changes I can make and not hesitate to submit bug fixes or feature requests going forward! 🚀