Deploy your Flutter App to Firebase App Distribution using GitHub Actions - Android
Firebase App Distribution is a great way to distribute your apps efficiently to your testers without making your app validated by Google or Apple.
But it can be even more powerful to automatically deploy your app each time you are making a change to your code so that you can test your app even more frequently.
Even if there are a lot of tools that can help automate everything, like CodeMagic or Bitrise, today I want to show you how to use GitHub Actions for deploying to Firebase App Distribution.
This first part will focus on Android. The second part (which will be longer thanks to the Apple process) will focus on iOS.
Why not use Fastlane
Fastlane is a tool that can help distribute your app to your store and your staging environment (Firebase App Distribution or AppCenter, for example). It can help your CI be fully platform agnostic, but I feel like fastfile is often too complicated for beginners.
Prepare your app
To publish your app on Firebase, you must sign your app. The first step is to create a Keystore. Using Android Studio, you can easily create one.
Go in Build > Generate Signed Bundles / APK; you can create one directly in the assistant.
Remember all the passwords and alias for your Keystore; you'll need them after!
Finally, you need to modify your app/build.gradle
with this in your signingConfig.
signingConfigs {
if (System.getenv("ANDROID_KEYSTORE_PATH")) {
release {
storeFile file(System.getenv("ANDROID_KEYSTORE_PATH"))
keyAlias System.getenv("ANDROID_KEYSTORE_ALIAS")
keyPassword System.getenv("ANDROID_KEYSTORE_PRIVATE_KEY_PASSWORD")
storePassword System.getenv("ANDROID_KEYSTORE_PASSWORD")
}
} else {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
storePassword keystoreProperties['storePassword']
}
}
}
You say that you will be using a local key file if the variable ANDROID_KEYSTORE_PATH
isn't defined. Otherwise, you'll be using the file, reading from environment variables.
The Github Workflow
A GitHub action workflow needs to be defined in a .github/workflows
folder at the root of your project. I'll name mine deploy-android.yaml
.
name: Deploy Android to Firebase App Distribution on merge
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: subosito/flutter-action@v1.5.3
- name: Install Dependencies
run: flutter packages get
- name: Decode Keystore
id: write_file
uses: timheuer/base64-to-file@v1
with:
fileName: "app_keystore.jks"
encodedString: ${{ secrets.KEYSTORE }}
- name: Build
run: flutter build apk
env:
ANDROID_KEYSTORE_PATH: ${{ steps.write_file.outputs.filePath }}
ANDROID_KEYSTORE_ALIAS: ${{ secrets.ANDROID_KEYSTORE_ALIAS }}
ANDROID_KEYSTORE_PRIVATE_KEY_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PRIVATE_KEY_PASSWORD }}
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
- name: Firebase App Distribution
uses: wzieba/Firebase-Distribution-Github-Action@v1.3.2
with:
appId: ${{secrets.FIREBASE_APP_ID_STAGING}}
token: ${{secrets.FIREBASE_TOKEN}}
groups: testers
file: /home/runner/work/{YOUR_REPO}/{YOUR_REPO}/build/app/outputs/flutter-apk/app-release.apk
As you can see, there are several steps that I'll describe here:
- You define your workflow to only work on main push
- You install Flutter thanks to an action (by default, the latest stable)
- You install the dependencies of your project
- You decode your Keystore from a base64 secret to a file named app_keystore.jks
- You build your apk with all the needed environment variables
- You distribute your app to Firebase Distribution to a group called testers
Define your secrets
As you can see in the previous YAML file, you need to define several secrets to properly work the script.
Go into the secret part of your GitHub repository, and add the following secrets:
KEYSTORE
is your Keystore in base 64, this command will copy your key in the clipboard:
base64 app.keystore | pbcopy
ANDROID_KEYSTORE_ALIAS
,ANDROID_KEYSTORE_PRIVATE_KEY_PASSWORD
,ANDROID_KEYSTORE_PASSWORD
are the alias and the password you have defined while creating your Keystore.FIREBASE_TOKEN
is a token you can get with the following command:
firebase login:ci
FIREBASE_APP_ID_STAGING
is the id of your app; you can find it in the Firebase console in the settings
Also, don't forget to change YOUR_REPO
to the name of your repo!
Once pushed to your main
branch, you will have your Android app published to Firebase App Distribution!
Conclusion
As you can see, you can quickly set up a CI to deploy to Firebase App Distribution and get feedback quickly on your project as you go without going through store validation!
You can always subscribe to my newsletter below and follow me on Twitter to not miss my next article!