Automating Flutter Deployments: Part 1 – Fastlane Configuration

Rachel Walker Development Technologies, Flutter, Tutorial Leave a Comment

Recently, I worked on automating some internal processes for building and releasing Flutter applications. As part of this effort, I configured Fastlane to run tests, build artifacts, and deploy our Flutter app to the Apple and Google Play stores. Fastlane is an open-sourced platform that provides tooling for automating mobile app releases. It can be run locally but is also compatible with many CI/CD platforms.

This blog is Part 1 of a three-part series exploring automating Flutter CI/CD on CircleCI. This post covers setting Fastlane to build and deploy applications, Part 2 will outline automating screenshot capture and test runs, and Part 3 will discuss configuring CircleCI to automate these processes.

The documentation for configuring Fastlane for Flutter is fairly comprehensive, however now that I have done it once, there are some things I wish I had known. As mentioned, this blog post will go through the steps for setting up Fastlane to run locally and provide some advice and resources for structuring the setup to easily migrate to a CI/CD platform.


Prior to jumping in with Fastlane, take a moment to evaluate and understand how the application is currently being deployed and the goals you have for what you want to automate. Run through the full release process manually, if possible, to prioritize which pieces are the most time-intensive or error-prone. Identifying which steps in the process should require manual approval and which should be automated will help with structure.

The automation steps will require an account that has the appropriate privileges in the app stores. Because of this, you may want to set up a dedicated account for automation rather than using an individual’s credentials. This is especially true if you intend to run Fastlane from a CI/CD system.

This account should also have 2FA enabled, and you will need to be able to provide the verification code during setup.

Setting Up Fastlane

Setting up Fastlane to work with Flutter requires a slight modification to the installation instructions they provide. Instead of setting up Fastlane once at the root of the project, Android and iOS will each have a Fastlane file and Gemfile.

First, follow the Fastlane documentation to set up the Ruby Environment, but stop before creating the Gemfile; that will be taken care of later on.

The Flutter team provides comprehensive instructions for initializing Fastlane in their Fastlane Setup Guide. In that guide, fastlane init command in step 4 includes optional prompts that will require app store credentials to be configured.

If you will not be integrating Fastlane with the app stores, I recommend following the steps as written. If you do want to integrate Fastlane with the stores, I suggest collecting login credentials and doing the code setup first.

These are steps 6 and 7 in the guide, but when I was running through them, I referenced some additional resources that were helpful that I suggest reading through first. Collecting the required credentials will make the Fastlane initialization process run more smoothly.



  • Configure code signing and authentication, here.
  • Create an App Store Connect API Key using an Apple Developer Id that you will be able to sign into when you initialize Fastlane. Read more about this authentication, here.
  • I recommend this guide as a comprehensive walkthrough for setting up code signing and certificates. It also provides some helpful Fastlane tips for after initialization is complete.

Reminder: Never check credential files or passwords into version control! They are secret and should be stored securely and protected. You will need them for CI and for other team members to release the app, and if they are compromised, they will need to be changed.

Once you have this information, run the Fastlane setup instructions for Flutter and provide the credentials as prompted.

Prevent Inadvertent Deployments

After running fastlane init, there are some configuration changes to make before running the fastfile. It’s a good idea to modify the upload commands first to prevent accidental deployments.


Locate the upload_to_play_store command in Android/Fastfile. This command is aliased to Supply in the Fastlane documentation. Some options need to be set on the command. First, set validate_only: true to prevent accidental deployments. The track should be set to the appropriate value from Google Play Console.

Locally run fastlane action upload_to_play_store to show the other available options and default values and review the Supply documentation.

If the first version of the app has not been released yet, the app must be uploaded in a draft status. For more information, see this Fastlane discussion.


In the iOS Fastfile, uploading to testflight is configured separately from uploading to the app store.

Testflight upload is done with the upload_to_testflight command, which is aliased to Pilot in the Fastlane documentation. To show the available options locally run fastlane action upload_to_testflight and review the Pilot documentation.

App Store uploads, including screenshot and metadata updates, are done with the upload_to_appstore command. This is aliased to Deliver in the Fastlane documentation. To show the available options locally run fastlane action upload_to_appstore and review the Deliver documentation.

Update Lanes for Flutter

The generated Fastfile lanes use native build commands for the steps that they implement. These should be switched to use Flutter commands instead.

For example, the generated android :test:

 lane :test do
   gradle(task: "test")

…should be updated to:

 lane :test do
   Dir.chdir "../.." do
     sh("flutter", "test")

Remember to go up a directory for all actions that need to be executed at the project root. This will vary significantly depending on your project setup.

Lane Construction

The generated lanes tend to put multiple commands together to create a full path. This is functional, but as more code is added, it can introduce code duplication. I recommend creating modular lanes from the beginning then using those to construct larger workflows.

This helps with the general structure by following DRY. It is also useful when Fastlane runs on CI since each lane change will be reported to the console, and steps are easy to add, reorder, or omit to optimize run times and caching.

As an example, in a lane to deploy a clean build to an internal test lane for Android, our steps can be written as:

 desc "Internal Track Deployment"
 lane :internal_deploy do
   build_number = get_next_build_number(track: 'internal')
   build(build_number: build_number)

Then each of those steps can be implemented as a standalone lane. Each piece can be tested as it is written by running bundle exec fastlane $laneName, then the entire flow can be tested at the end.

This full deployment lane makes sense locally since emulators or devices could be started prior to the run to allow the tests to run. However, it may not be optimized for running on CI depending on the emulator configuration and if steps should be run in parallel.

In the above example, get_next_build_number takes in a parameter to specify the track. This is just one of the advanced lane features available for flow control and reusability.


In conclusion, Fastlane creates more consistent builds, releases, and deployments by automating the steps across developers. I found that its integration with Flutter and the Google and Apple stores was fairly robust and easy to understand after the initial configuration.

Fastlane provided all of the basic functionalities that we needed – building, testing, and deploying – as well as the ability to place app metadata in our version system for more control over updates. Overall, it was a valuable tool in standardizing our build and release process across developers, even when it was just running on local machines.

In our next installment, we’ll outline automating screenshot capture and test runs, and in the post following it, we will discuss configuring CircleCI to automate these processes. Stay tuned by subscribing to the Keyhole Dev Blog!

0 0 votes
Article Rating
Notify of

Inline Feedbacks
View all comments