Automate Flutter Android App Deployment with GitHub Actions and fastlane

cp_nandani

Nandani Sharma

Posted on November 26, 2024

Automate Flutter Android App Deployment with GitHub Actions and fastlane

Background

Deploying your Flutter Android app doesn’t have to be a manual, time-consuming process. We’ll guide you through setting up automated deployment using GitHub Actions and Fastlane, enabling you to focus more on building features and less on repetitive tasks.

Previously, we explored deploying Flutter iOS apps; now, we turn our attention to Android, ensuring a smooth and efficient workflow for app distribution.

If you’re interested in further customization or adding other deployment tracks (e.g., production, beta), you can modify the Fastfile and GitHub Actions workflow accordingly.

Now, we’ll set up a Github action for an Android application using fastlane.

Why fastlane?

fastlane is a straightforward and efficient tool for integrating CI/CD pipelines into Android app development. It not only simplifies deployment but also handles tasks like generating screenshots, managing code signing, and automating releasing processes.

Prerequisite

Before diving in, ensure you have a Flutter application and a GitHub repository ready for your project.

A basic workflow setup is also essential to proceed, including checking out the repository and setting up the Flutter environment. Since this setup is covered in our previous article, we won’t repeat it here.

For detailed instructions on setting up the workflow and Flutter environment, refer to our Basic Workflow Setup Guide.

Let’s Get Started

We’ll break down the auto-deployment process into three key parts.

  • Configure Android Code Signing
  • Set Up fastlane
  • Add Jobs for Publishing the App

1. Configure Android Code Signing

To publish your app on the Play Store, it must be signed with a digital certificate. Android uses two signing keys for this process: Upload key and App signing key.

What are these keys, and why are they important?

Upload Key

The Upload Key is used to sign your app when you upload it to the Play Console. After uploading, Google Play will re-sign your app with the App Signing Key before distributing it to users.

  • The Upload Key is essential for authenticating your app during uploads.
  • It needs to be kept secure to prevent unauthorized access and to protect the integrity of your app’s updates.

To generate the Upload Key, follow the official Android Developer Guide on App Signing.

While creating the Upload Key, make sure to remember the password and key alias that you set for the key. You’ll need these later when configuring Fastlane and setting up the deployment process.

App Signing Key

The App Signing Key is the primary key used by Google Play to sign your app before delivering it to users. This key ensures that:

  • Your app updates are trusted by users.
  • Only apps signed with the same key can be installed or updated.
  • This key remains consistent throughout the lifetime of your app, providing security for future updates.

To generate the App Signing Key, follow the step-by-step instructions in the Collect your Google credentials section in the Fastlane setup documentation guide.

When creating the upload key, a JSON file is generated and downloaded. This file contains essential credentials that you will need to authenticate and manage your app on the Play Console. It will be required in the later steps.

2. Set Up Fastlane

Now, that we have the Upload Key and App Signing Key ready, it’s time to set up fastlane.

Install fastlane

To get started, you’ll need to install Fastlane on your machine.

# Using RubyGems(macOS/Linux/Windows)
sudo gem install fastlane

# Alternatively using Homebrew(macOS)
brew install fastlane
Enter fullscreen mode Exit fullscreen mode

Set Up fastlane in Your Project

fastlane is installed, let’s configure it within your Flutter project.

Initialize fastlane

Open your terminal and navigate to your project’s root directory and change the directory to android. Then, run the following command

fastlane init
Enter fullscreen mode Exit fullscreen mode

During the setup process, you’ll be prompted with a series of questions:

Package Name: Provide the package name of your application. You can find it in your android/app/build.gradle file, under defaultConfig > applicationId. For example:

applicationId "io.example.yourapp"
Enter fullscreen mode Exit fullscreen mode
  • Path to JSON Secret File: Press Enter when asked for the path to your JSON secret file. We'll set up it later.
  • Download existing metadata and set up metadata management: Choose the option based on how you plan to manage app metadata and screenshots during deployment.
  • Google Play Upload: When asked if you plan on uploading information to Google Play via fastlane, answer ’n’ (No). We will configure this in a later step.

Now, you can see a newly created ./fastlane directory in your project. Inside this directory, you’ll find two key files:

  • Appfile: This file contains global configuration information for your app, such as the app’s package name and JSON key file.
  • Fastfile: This file defines the “lanes,” which are sets of actions that drive the behavior of fastlane for various tasks.

Now, open the Appfile and add the following line to specify the path to your JSON key file, which will be used for authenticating with the Google Play API.

Also, ensure that the package_name is set to the correct value for your app and set the JSON file path in the Appfile as follows

json_key_file("google_play_api_key.json") # Path to the json secret file
package_name("com.exapmle.appname")
Enter fullscreen mode Exit fullscreen mode

🤔 Don’t worry!! We will add the google_play_api_key.json file in the next steps. Stay tuned!

Add Secrets to the Repository

In this step, we’ll add all the necessary environment variables and secrets that fastlane and the app will use during deployment.

To add new secrets and variables to your repository, go to Settings > Secrets and Variables.

Github Action Secrets

  • APKSIGN_KEYSTORE_PASS: The password for the keystore that is set when creating the development.jks file.
  • APKSIGN_KEY_ALIAS: The alias created for the key inside the keystore .
  • APKSIGN_KEY_PASS: The password associated with the alias created for app’s signing key.
  • APKSIGN_KEYSTORE_BASE64: We need to convert the development.jks keystore file, which is generated during the creation of the App Signing Key, into Base64 format to store it as a secret. For that, open the terminal and navigate to the directory where the development.jks file is located. base64 -i <File name>| pbcopy Now that the Keystore is copied to your clipboard, paste this Base64 content as the value.
  • APP_PLAY_SERVICE_JSON_BASE64: Convert JSON file downloaded while creating Upload key to Base64 format in a similar way as the keystore file and add it as secret.

Set up environment variables

We will set up the environment variables for the deployment job. These variables will reference the secrets you added to your GitHub repository.

jobs:
  android_deployment:
    runs-on: ubuntu-latest
    env:
      APP_PLAY_SERVICE_JSON: ${{ secrets.APP_PLAY_SERVICE_JSON_BASE64 }}
      APKSIGN_KEYSTORE_BASE64: ${{ secrets.APKSIGN_KEYSTORE_BASE64 }}
      APKSIGN_KEYSTORE_PASS: ${{ secrets.APKSIGN_KEYSTORE_PASS }}
      APKSIGN_KEY_ALIAS: ${{ secrets.APKSIGN_KEY_ALIAS }}
      APKSIGN_KEY_PASS: ${{ secrets.APKSIGN_KEY_PASS }}
Enter fullscreen mode Exit fullscreen mode

Configure build.gradle for Signing

To enable the Android build system to use these environment variables during the build process, add the following configuration to your android/app/build.gradle file.

signingConfigs {
    if (System.getenv("APKSIGN_KEYSTORE") != null) {
        release {
            storeFile file(System.getenv("APKSIGN_KEYSTORE"))
            storePassword System.getenv("APKSIGN_KEYSTORE_PASS")
            keyAlias System.getenv("APKSIGN_KEY_ALIAS")
            keyPassword System.getenv("APKSIGN_KEY_PASS")
        }
    } else {
        release {
            // Signing with the debug keys for now, so `flutter run --release` works.
            // Generate Debug keystore and add it here
        }
    }
}

 buildTypes {
            release {
            minifyEnabled true
            debuggable false
            shrinkResources true

            signingConfig signingConfigs.release
        }
        debug {
            minifyEnabled true
            debuggable true

            signingConfig signingConfigs.release
        }
    }
Enter fullscreen mode Exit fullscreen mode

Whenever we initiate a release build, the system will look for the Keystore in the specified environment variables and use them to sign the build with the provided Keystore.

For local testing in release mode, you should generate a debug Keystore. The app will use this debug keystore if the release keystore is not available.

We've discussed further steps to define jobs for distribution of the Android app in our complete guide.

To read the step-by-step setup & implementation, check out our complete guide on Automate Flutter Android App Deployment with GitHub Actions and fastlane.


If you like what you read, be sure to hit 💖 button! — as a writer it means the world!

I encourage you to share your thoughts in the comments section below. Your input not only enriches our content but also fuels our motivation to create more valuable and informative articles for you.

Happy coding!👋

💖 💪 🙅 🚩
cp_nandani
Nandani Sharma

Posted on November 26, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related