Hey, everyone! 👋🏻
I want to start talking about my decision for this year, which is to start to write more tech articles to help people, increase my knowledges (cuz I need to study either ^^) and also improve my english writting skills. So, this will be the beggining of this journey and I hope you all could enjoy it :)
Summary
1. Why am I writting this article?
2. Firebase App Distribution
3. The manually way
4. The GitHub workflows way (main topic)
5. Final workflow yaml file result
6. Testing it!
1. Why am I writting this article?
Few months ago I started to develop a Flutter app side-project, which is not available yet, but I intend to publish it on app stores when I feel that it is ready for MVP release.
On this project, I'm using Firebase database to store the app data, authentication, files storaging and some other features. BUT we have one that is the main topic of this article: Firebase App Distribution.
2. Firebase App Distribution
Firebase has it own functionality whose job is literally distribute your app to an user (or a group of users).
When we're talking about Flutter apps, we're also talking about downloading this apps at our mobile devices (in case mobile apps, I'm not going to talk about Flutter Web at this article). Maybe you or your team wanna test it or show it for the team manager or team leader, whatever.
This is the "nice" but rough way to do it. Uploading your app file to Firebase App Distribution.
3. The manually way
First of all, of course, you'll need to generate a build of your Flutter app.
flutter build apk
or
flutter build aab
When you get into your Firebase project console, you have in the left side a shortcuts list, and you will probably see an option named 'App Distribution'. Click on it.
You'll see a big dashed blue box asking you to upload your app APK or AAB file.
After that, it will appear a card with a text field to put the tester e-mail or the name of a tester group (which you can create by clicking at third top navigation bar).
Then, you'll just need to press 'Next' and 'Send to testers'.
Well done! Now, your app is on the devices of all the testers you sent it.
But... Doing this EVERY time sounds like a waste of time. Isn't? Maybe. Maybe not.
But we can do it better. Follow me to the next topic!
4. The GitHub Actions way
Now, in the main topic of this article, I'll show you how automate this process of uploading your app to Firebase App Distribution and send it to testers.
In the end of this topic, you'll know how to do this process just by pushing or opening a pull request on a specific Git branch of your project.
In your project, create a path named .github/workflows
, just like that:
Inside of it, create a .yaml
file with the name of your workflow. I named mine as 'firebase_workflow.yaml'.
Let's beggin by giving a name to the workflow.
name: Firebase APP Workflow
Then, we will need to determine when this workflow will be triggered. Pushing to a branch? Creating a pull request to a branch?
Exemple of how it should looks like the yaml file until here:
name: Firebase APP workflow
on:
push:
branches:
- main
pull_request:
branches:
- main
We need to put jobs on our workflow file. Above we have an exemple of setting that is very important for the whole workflow operation.
I created a key named firebase_distribution
and gave it the name "Firebase App Distribution". Then, I setted the virtual machine which would it runs on. You can read more about this here.
jobs:
firebase_distribution:
name: Firebase App Distribution
runs-on: ubuntu-latest ## virtual machine
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
with:
java-version: "12.x"
Then, we have two important initial steps to define. The first one is an official GitHub Action used to check-out a repository so a workflow can access it. The second one it's pretty more complex but, briefly, downloads and set up a requested version of Java.
Continuing the steps:
Give a name to this step, now we gonna make our workflow decode the most important file which makes Firebase work on our project: the google-services.json
.
- name: Decode google-services.json
env:
GOOGLE_SERVICES_JSON: ${{ secrets.GOOGLE_SERVICES_JSON }}
run: echo "$GOOGLE_SERVICES_JSON" > android/app/google-services.json
Inside env key we put another key called GOOGLE_SERVICES_JSON. But, for now, I'll need to explain what is this "secrets.GOOGLE_SERVICES_JSON" here.
For this, open your Github project repository and get into settings page.
On the left side options, look for the security session and click on "Secrets" > "Actions".
We need to create 3 secret keys. Each one for:
- Firebase App ID
- Firebase Token
- Google Services Json
Name them by your preference.
The Firebase App ID can be found by following this short click steps on your Firebase project console:
We just need to copy and paste it on our secret key.
Firebase token can be obtained by running a few commands on your machine.
At first, we'll need to install npm and run the following command:
npm install -g firebase-tools
Then, run this second command:
firebase login:ci
After that, the token will be shown by your CLI.
For the last key, we just need to open the google-services.json
on our project in path "android/app/google-services.json", copy the whole content inside and paste it on the respective secret key in your Github project repository.
Now, we can get back into our workflow and understand what will happen from now:
- name: Decode google-services.json
env:
GOOGLE_SERVICES_JSON: ${{ secrets.GOOGLE_SERVICES_JSON }}
run: echo "$GOOGLE_SERVICES_JSON" > android/app/google-services.json
Basically, using secrets.KEY_NAME allows us to access our project secret keys.
We're accessing the secret key named GOOGLE_SERVICES_JSON
and running a command on it.
Now, we can continue writting our workflow:
- uses: subosito/flutter-action@v1
with:
channel: "stable"
subosito/flutter-actions@v1 is just a Flutter enviroment running on our workflow. So, now we have 'access' to Flutter enviroment, we can choose a Flutter channel to use. Read about this action here.
From now, we will run Flutter commands inside our workflow:
- run: flutter pub get
- run: flutter build apk
- uses: actions/upload-artifact@v1
with:
name: release-apk
path: build/app/outputs/apk/release/app-release.apk
Notice that already known commands like flutter pub get
and flutter build apk
now it shows up on our workflow. But, to upload the generated app file (artifact), we'll need to use the action upload-artifact@v1 and parse the build path which it will be storing the app file.
To finally finish this (I swear), we complete our workflow with a Firebase action that will have the responsability to upload the app to Firebase App Distribution. Read about wzieba/Firebase-Distribution-Github-Action. This action uploads your artifacts with .apk, .aab and .ipa (this last one for iOS) extensions to Firebase App Distribution.
- name: upload artifact to Firebase App Distribution
uses: wzieba/Firebase-Distribution-Github-Action@v1
with:
appId: ${{secrets.FIREBASE_APP_ID}}
token: ${{secrets.FIREBASE_TOKEN}}
groups: testers
file: build/app/outputs/flutter-apk/app.apk
We'll need to parse the remeaning secret keys, the tester group name (which you created at your Firebase project console) and the file path. In Flutter, by default, it is stored at build/app/outputs/apk/release/app-release.apk
.
That's it! Our workflow process file is done!
5. Final workflow yaml file result
This is how your workflow file should looks like:
name: Firebase APP workflow
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
firebase_app:
name: Run Firebase Workflow
runs-on: ubuntu-latest ## virtual machine
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
with:
java-version: "12.x"
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Decode google-services.json</span>
<span class="na">env</span><span class="pi">:</span>
<span class="na">GOOGLE_SERVICES_JSON</span><span class="pi">:</span> <span class="s">${{ secrets.GOOGLE_SERVICES_JSON }}</span>
<span class="na">run</span><span class="pi">:</span> <span class="s">echo "$GOOGLE_SERVICES_JSON" > android/app/google-services.json</span>
<span class="pi">-</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">subosito/flutter-action@v1</span>
<span class="na">with</span><span class="pi">:</span>
<span class="na">channel</span><span class="pi">:</span> <span class="s2">"</span><span class="s">stable"</span>
<span class="pi">-</span> <span class="na">run</span><span class="pi">:</span> <span class="s">flutter pub get</span>
<span class="pi">-</span> <span class="na">run</span><span class="pi">:</span> <span class="s">flutter build apk</span>
<span class="pi">-</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/upload-artifact@v1</span>
<span class="na">with</span><span class="pi">:</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">release-apk</span>
<span class="na">path</span><span class="pi">:</span> <span class="s">build/app/outputs/apk/release/app-release.apk</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Upload to Firebase App Distribution</span>
<span class="na">uses</span><span class="pi">:</span> <span class="s">wzieba/Firebase-Distribution-Github-Action@v1</span>
<span class="na">with</span><span class="pi">:</span>
<span class="na">appId</span><span class="pi">:</span> <span class="s">${{secrets.FIREBASE_APP_ID}}</span>
<span class="na">token</span><span class="pi">:</span> <span class="s">${{secrets.FIREBASE_TOKEN}}</span>
<span class="na">groups</span><span class="pi">:</span> <span class="s">testers</span>
<span class="na">file</span><span class="pi">:</span> <span class="s">build/app/outputs/flutter-apk/app.apk</span>
Now, we just need to push our project to github's project branch which we had chosen or merge pull request (it depends on what did you choose to do) to trigger the workflow.
After that, you can see the process working by clicking at "Actions" tab in your project repository.
This is how it should your workflow alert looks like:
That's it!
Thanks A LOT for reading until here! I hope this article may help you create github actions workflows to upload your app to Firebase APP Distribution.
Top comments (1)
how can i use github actions with my flutter app using google auth and requires a sha1