DEV Community

Cover image for DevOps  - Understanding and applying CI/CD pipeline for Android developers 🚀 - Part 2
Mustafa Khaled
Mustafa Khaled

Posted on

DevOps - Understanding and applying CI/CD pipeline for Android developers 🚀 - Part 2

Welcome once again 🤗
I'm pretty sure that you went through Part 1. If not, check it out.

In part 1 we managed to implement the first 2 steps :
Step 1: Configure GitLab.
Step 2: Configure fastlane.

Hold on ... for step 3,

Step 3 : Configure FirebaseAppDistribution (Our CD Channel)

As we mentioned in part 1, FirebaseAppDistribution is a tool provided by firebase where you can upload your beta .apk files.
You can find many posts that use Slack channels as their CD channel. For me, it isn't a perfect channel because it's limited to plans, so the free plan has storage of 4 GB for all channels within the workspace, which may limit your apk files to be uploaded.

So, what makes FirebaseAppDistribution distinctive? 🤔🤔
With FirebaseAppDistribution you can send your beta deployment with a direct E-mail, by mentioning Emails of testers. Also, you can add your release notes of these deployments. Not to mention, a great dashboard for versions uploaded to FirebaseAppDistribution.

Alt Text

To do so, there are 3 steps

a. Create android firebase application.
Because firebase documentation is outstanding 🤩🤩, we should follow it.
Also, don't forget to Get Started with FirebaseAppDistribution.

Alt Text

b. Install firebase cli to your machine.
Because we are going to use firebase commands that would help us in uploading beta deployments. Following firebase documentation we would manage to install firebase cli.

c. check firebase is installed correctly.

$ firebase --version
Enter fullscreen mode Exit fullscreen mode

Step 4 : Fastfile

Now, it's time to write the steps that fastlane would follow to upload our beta deployments to FirebaseAppDistruibution.


 desc "Submit a new beta build to Firebase App Distribution"
    lane : distribute do
        build_android_app(
          task: "assemble",
          build_type: "debug"
        )

        firebase_app_distribution(
            app: "replace this with app Id. Go to Firebase console ->     Project Overview -> Project Setting",
            testers: "example1@domain.com,     example2@domain.com",
            firebase_cli_token: "firebase token"

        )

      end
Enter fullscreen mode Exit fullscreen mode

In fastlane, it contains lanes where lane is a specific task in fastlane.
We have a lane called distribute that would build a debug apk, and by using firebase_app_distribution it would upload the apk to the specific app in firebase console.

app: As mentioned earlier, go to firebase console -> Project Overview -> Project Setting.

testers: Define testers emails separted by ","

firebase_cli_token: This token required for distribution process, so how could we get this token? 🤔🤔

  • Open your terminal
  • run the following command
$ firebase login:ci
Enter fullscreen mode Exit fullscreen mode
  • Open the link
  • Choose the account where your project is rest
  • Allow permissions for firebase

Now you can see the token generated for firebase cli 🎉🚀
Alt Text

Remark: Please commit&push changes in fastfile. 👌

Now, let's run this task from the android studio terminal ... we run lane by keyword fastlane followed by the lane name.

$ fastlane distribute
Enter fullscreen mode Exit fullscreen mode

Oh 😔😔 , seems like you got some error like that :
Alt Text

Fortunately, the error is very descriptive. fastlane doesn't know what firebase_app_distribution is.

Here is the role of Gemfile mentioned previously. We should add firebase_app_distribution as a dependency for fastlane.
So from android studio terminal, add firebase_app_distribution plugin.

$ fastlane add_plugin firebase_app_distribution
Enter fullscreen mode Exit fullscreen mode

Remark: New files would be generated within fastlane directory of your android project after adding this plugin, So make sure committing & pushing changes

Now, everything is up and running, give another try

$ fastlane distribute
Enter fullscreen mode Exit fullscreen mode

Wohooooo 🎉🎉 We did a great job, please check your emails listed in fastfile to ensure that an Email has been sent with an invitation.

Great Job 🤓, let's make this automating 🚀 this using GitLab CI/CD pipeline. Our goal now is when you push to your origin branch, i.e dev, master , etc... . The pipeline should start its stages.


Step 5: Configure gitlab-ci.yml

You can find gitlab-ci.yml in the root of your android project. so here is the question. What is the gitlab-ci.yml file?
cool, gitlab-ci.yml is a file defines the structure and order of the pipelines.
As we mentioned earlier, our pipeline consists of 3 stages

  • build
  • test
  • deploy
image:     mustafakhaled/android-fastlane-firebase:1.0

stages:
  - build
  - test
  - deploy

lintDebug:
  stage: build
  script:
    - ./gradlew -Pci --console=plain :app:lintDebug -PbuildDir=lint

assembleDebug:
  stage: build
  script:
    - ./gradlew assembleDebug
  artifacts:
    paths:
    - app/build/outputs/

debugTests:
  stage: test
  script:
    - ./gradlew -Pci --console=plain :app:testDebug

deploy_internal:


  stage: deploy

  script:
    - fastlane distribute

Enter fullscreen mode Exit fullscreen mode

Maybe seems like weird syntax, but don't worry we will go through this file in details 😄😁.

image:     mustafakhaled/android-fastlane-firebase:1.0
Enter fullscreen mode Exit fullscreen mode

As we mentioned in part 1,
Docker: it is a containerization tool that allows a developer to package up an application with all of the parts it needs.
I wrapped up all parts need for our application in a docker image, where we can use it in our continuous integration.You can check it out in Dokcer Hub.
This image contains basic tools that serve our main goal. it contains:

  • Linux
  • Android SDK
  • Fastlane
  • Firebase tools

If you think about it, you would find this environment is like your machine environment where you were able to build and send your app to firebaseAppDistrubution.

stages:
  - build
  - test
  - deploy
Enter fullscreen mode Exit fullscreen mode

In this part, we just define the stages of the pipeline.


lintDebug:
  stage: build
  script:
    - ./gradlew -Pci --console=plain :app:lintDebug -PbuildDir=lint
Enter fullscreen mode Exit fullscreen mode

This job is run on build stage, it run lint check. It helps find poorly structured code that can impact the reliability and efficiency of your Android apps and make your code harder to maintain.

assembleDebug:
  stage: build
  script:
    - ./gradlew assembleDebug
  artifacts:
    paths:
    - app/build/outputs/
Enter fullscreen mode Exit fullscreen mode

This job is on the build stage also. It's responsible for building debug apk. you could find artifacts, it is a list of files and directories to attach to a job on success.

debugTests:
  stage: test
  script:
    - ./gradlew -Pci --console=plain :app:testDebug
Enter fullscreen mode Exit fullscreen mode

This job is on the test stage. It 's responsible for run unit tests if found in your projects.

  stage: deploy

  script:
    - fastlane distribute
Enter fullscreen mode Exit fullscreen mode

This job is on the deploy stage. It's responsible to deploy your beta deployment to firebaseAppDistribution as we accomplished it locally(without CI).

Enhancement: We want this pipeline to run only if I pushed to master branch, not all branches. This could be done in gitlab-ci.yml by modifying stage of deploy.

  stage: deploy

  only:
    - master

  script:
    - fastlane distribute
Enter fullscreen mode Exit fullscreen mode

Remark: You can define any branch you want.

The last step is to push your gitlab-ci.yml and your pipeline would start.

Open GitLab, your pipeline should be like this:

Alt Text

Wait for the pipeline.

Wait

WOHOOOOOOOOO .. Finally ! 🎉🎉🎉🎉🎉🎉🎉🎉

Alt Text

Celebrate 🎉🎉🎉🎉💃💃💃💃 .. Now you automated your beta deployments to testers emails with no hassle. 🚀🚀🚀🚀

Check the full repository on my GitLab

Waiting for your feedback 😄😄 in the comments below and for any questions as well.

Reach me out through:

Top comments (4)

Collapse
 
abdorahmanmahmoudd profile image
Abdelrahman

Well done Mustafa! :clap :clap

I have a suggestion regarding the linting script, wouldn't it be cleaner to create a stage called "format"
and then make that lane at that "format" stage?

Also, how about creating a lane to automatically update your app version number and accumulate release notes from your commits before uploading the build to your channel!

finally give a look at "gym" its really cool tool that would make it easier for you.
docs.fastlane.tools/actions/gym/#gym

Collapse
 
mustafakhaled profile image
Mustafa Khaled

Thanks Abdelrahman.
I think this good and I'll put this into considerations.
For updating the app version number, I think this is out of the scope of this article as we are here work with beta deployments but definitely this is very important.
I'll have a look at this also.
Thank you again

Collapse
 
mbkfa93 profile image
mbkfa93

Easy to understand and quick to the point, many thanks 👏

Collapse
 
mustafakhaled profile image
Mustafa Khaled

thanks for this 😄😄
I hope this benefit