DevOps  - Understanding and applying CI/CD pipeline for Android developers 🚀 - Part 2
Tags: gitlab, firebaseappdistribution, fastlane, android
Published: 2020-01-27 13:55:55

Welcome once again 🤗 
I'm pretty sure that you went through [Part 1](https://dev.to/mustafakhaled/devops-understanding-and-applying-ci-cd-pipeline-for-android-developers-part-1-3o7l). If not, check it out.

In [part 1](https://dev.to/mustafakhaled/devops-understanding-and-applying-ci-cd-pipeline-for-android-developers-part-1-3o7l) 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](https://dev.to/mustafakhaled/devops-understanding-and-applying-ci-cd-pipeline-for-android-developers-part-1-3o7l), 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](https://thepracticaldev.s3.amazonaws.com/i/sfbj92w0z8086womra0c.jpg)

To do so, there are 3 steps 


**a. Create android firebase application.**
Because firebase documentation is outstanding 🤩🤩, we should follow [it](https://firebase.google.com/docs/android/setup/).
Also, don't forget to **Get Started** with FirebaseAppDistribution.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/74y8om1332btuu5ztm03.jpg)



**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](https://firebase.google.com/docs/cli) we would manage to install firebase cli.


c. check firebase is installed correctly.

```bash
$ firebase --version
```
---------------------------------

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

```bash

 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
```

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
```bash
$ firebase login:ci
```

- 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](https://thepracticaldev.s3.amazonaws.com/i/areqtcpsjxyjysngngeq.png)


**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.
```bash
$ fastlane distribute
```


Oh 😔😔 , seems like you got some error like that : 
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/tqu1m3gjii736deatiwj.png)


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.

```bash
$ fastlane add_plugin firebase_app_distribution
```

**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
```bash
$ fastlane distribute
```

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

![](https://media.giphy.com/media/ckeHl52mNtoq87veET/giphy.gif)



#### 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

```yaml
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

```

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


```yaml
image:     mustafakhaled/android-fastlane-firebase:1.0
```
As we mentioned in [part 1](https://dev.to/mustafakhaled/devops-understanding-and-applying-ci-cd-pipeline-for-android-developers-part-1-3o7l), 
**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](https://hub.docker.com/repository/docker/mustafakhaled/android-fastlane-firebase). 
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.


```yaml
stages:
  - build
  - test
  - deploy
```
In this part, we just define the stages of the pipeline.

```yaml

lintDebug:
  stage: build
  script:
    - ./gradlew -Pci --console=plain :app:lintDebug -PbuildDir=lint
```
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.


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

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.

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

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


```yaml
  stage: deploy
 
  script:
    - fastlane distribute
```

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.

```yaml
  stage: deploy

  only:
    - master
 
  script:
    - fastlane distribute
```

**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](https://thepracticaldev.s3.amazonaws.com/i/6g17svsg6zpitra0y4s2.png)




Wait for the pipeline.


![Wait](https://media.giphy.com/media/tXL4FHPSnVJ0A/giphy.gif)



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

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/a3b4x9h3aeqisvfosedv.png)


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

Check the full repository on my [GitLab](https://gitlab.com/MustafaKhaled/gitlab-cicd-fastlane-firebaseappdistribution)

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


Reach me out through:

- Email: mustafakhaledmustafa@outlook.com
- [GitHub](https://github.com/MustafaKhaled)
- Twitter : [@mus_khaled](https://twitter.com/Mus_Khaled)