Implementation of CI/CD in Android Development

CI/CD is a software development practice that most mobile developers in team projects use daily; However, most of the times, version control exercises (or .) git branching strategy) as well as automated testing/deployment already installed and only minor changes would be needed if anything. On the other hand, when working on individual or personal projects, setting up our own CI/CD pipeline may seem more useful if not for the learning purpose or with the client’s requirement.

As a result, many mobile developers may feel that CI/CD is outside their area of ​​expertise, and may do so without the use of mobile DevOps platforms, but mobile CI/CD automation is easier than ever through use. Has not been. of these platforms.

This article will not focus on CI/CD as a concept, but rather on an overview of the implementation of CI/CD through a mobile DevOps platform, using its simplicity but many configurable features.

CI (Continuous Integration)

When we talk about CI, we regularly integrate or push code into a shared code repository and automatically check against changes to detect any issues before it is merged into the team’s shared repository. Referring to running tests from .

CD (Continuous Delivery/Deployment)

As far as CDs are concerned in the context of mobile app development, we want to build our apps automatically and send them to QA, clients, testers…

DevOps Platform

There are very popular source control platforms like GitHub and Gitlab, and they both provide their own CI/CD pipeline integration. These are certainly viable solutions, especially when your project is already being hosted there, but due to their multi-purpose and multi-platform nature, they are hard to understand when it comes to the only aspect of mobile continuous integration and development. it happens.

The end product of a CI/CD configuration file is a YML file with instructions to be performed by an external machine. Mobile DevOps platforms allow us to use their interfaces and variety of features to optimize our pipeline in a secure manner, as it generates said YML file without editing any line of code in the file. Similarly, modifying the YML manually will also update the UI steps we see in the workflow. It also provides build reports and information to the user more clearly, as the platform is completely focused on CI/CD integration.

Within CI/CD and, in particular, the DevOps platform, there are some general concepts that should be explained:

  • Workflow: The main tool we will use to optimize automation. A workflow is a set of steps that the platform performs for us to implement the CI/CD pipeline. These may include building, testing or deploying an app.
  • Step: Steps are the various actions that our platform can perform within a workflow; These can include Git repository actions, running a build, deploying an APK, modifying a Gradle file, or simply a script, etc. There are many possibilities.
  • Trigger: These are the conditions trigger a workflow. These will most likely be related to push and merge requests from one branch to another.
  • Environment Variables: Like your standard environment variables, these variables can be stored in the project’s location, so they are widely available within the workflow. Examples can include APK directories, package names, app modules, or variants.
  • Mystery: Similar to environment variables, these may be needed at some stage in the workflow, but secrets contain sensitive information secured, for example, tokens to access the Play Store API.
  • Code Signing: This will include all the files required when releasing, such as keystore files, their aliases and passwords. Bitriz will safely store and securely handle these for you.
  • yml file: This is the configuration file that you set through the platform’s interface. It is always accessible for you to read and edit. This will act as an instruction guide for the machine running the pipeline. This file should be stored in the app repository (Bitrise can manage it for you). This is useful if you ever run into CI configuration issues, as you can easily go back to a previous version and update the YML file to BitRise.

Introducing Bitrise

There are many DevOps platforms out there, but Bitrise is a mobile-first provider and arguably one of the simplest yet capable platforms. Plus, you get some free credits for setting up your pipeline and running some builds. You can find Bitrise at the top of many Mobile DevOps Platform lists.

For almost every Android CI/CD action you want to run, the Bitrise docs have a template for that workflow, explaining what steps you should add and why. Some steps may be considered boilerplate because they may be needed in a workflow regardless of platform or target, such as: connecting to our VCS, cloning project repositories, pulling caches from BitRise to speed up build times /pushing, or deploying the build results back to BitRise. However, most other phases will be defined by the target and the platform.

CI/CD in practice

To integrate pipelines, we first need to define version control or git branching strategy. Next, we’ll describe a general sample* strategy that will help us define our workflows.

This will include the following branches and their roles:

  • Development: This is the base branch with a stable shared codebase for the devs in the team. Every time we want to add code, we checkout this branch and do a push or pull request to revert the changes DevelopmentTrigger unit tests as well as UI tests which, when passed, will allow MR or PUSH to succeed.
  • Staged: When we want our code to pass a QA check, we’ll merge Development In staging; QA should use this branch only for passing their tests. This step can generate an unsigned APK build to be deployed on platforms such as Firebase for testers and/or clients to test. No testing is needed in this workflow as we will be repeating the same tests against the same codebase Development workflow.
  • Release: When our app is ready to be deployed, we can merge scaffolding In release, This can trigger a release on the Play Store, but even though some people prefer to manually update the app and skip this trigger, you can also use it to release on an alpha or beta channel, if necessary. Not production.

*This strategy is just an example and not a best practice; It provides a good foundation and understanding for CI/CD to be implemented through Mobile DevOps Platform. The best or most optimal strategy can depend on many factors and will vary from project to project.

our workflow

Next, we’ll see how in three different workflows Development,scaffolding,release What will the VC strategy described above look like and how will they be triggered.

1. Development Workflow

  • Role: Merging to this branch means adding changes to the code that need to pass tests before merging to make sure the new code doesn’t break anything.
  • Trigger: a. Pushing or creating a merge request from development/feature_branch (or any other) Development branch.
  • Specific Steps: This workflow will run all the Android steps required to run Unit Tests and UI Tests if we have any. For this, we can read the Bitrise docs and find out what steps we need, and configure them accordingly. For example, when testing for UI tests, we might need a AVD Manager step, and if we are using an emulator, we need a . is required wait for android emulator Step.

2. Staging Workflow

  • Role: Merging into this branch may mean that the APK must be made available to a group of interest, such as QA or clients.
  • Trigger: to push scaffolding branch.
  • Specific Steps: This workflow does not include any test phases, as no changes are made to the code from the codebase Development, This workflow is characterized by an Android build phase that generates an unsigned APK and another phase that distributes it to Firebase.

To showcase some interesting features, we’ve also added steps to automatically modify the version code and version name of our app. To do this, we need to run a script that will modify the Gradle file dynamically. However, this requires the branch name to contain the desired version name, and the version code can only be updated to the Bitriz build number, so it has obvious limitations.

3. Release Workflow

  • Role: Merging in this branch means that one APK should be deployed in one channel(s) on Play Store.
  • Trigger: to push release branch.
  • Specific steps: This workflow is characterized by adding an Android sign step to the build (this will require a keystore JKS file and app signing information such as alias keys and passwords) and another step to distribute to the Play Store (play store console Requires a service account) to set up, as well as a file with release notes, if desired, and other specifications such as channels, apks or bundles … etc.).

set trigger

Now that we’ve defined our workflows, we can configure triggers, which means specifying which actions will trigger each workflow. Bitrise has a tab for us to specify these actions easily.

for Development workflow, we set up a trigger for pull requests (or push), in which we say any branch creating a PR Development will start Development (called development_test In the screenshot) Workflow:

The next time we create a PR, our VC website will display a message indicating that a bitrise pipeline is underway. Depending on the success of the build, it will show a green check or error.

for scaffolding (called staging_deployment_firebase_apk in the screenshot) and release (called release_deploy In the screenshot) workflow, we have similar triggers. Both will be triggered when a push action occurs in their respective branches:

all set

Once we’ve defined the workflows and triggers, we’ve essentially created our pipeline, and all we need to do is respect the branching strategy to implement CI/CD correctly.

We didn’t dive into the details of each stage configuration and platform feature to keep it short and sweet. Hopefully, this article will provide some insight into how simple CI/CD can look like in an Android project and the capabilities of the Mobile DevOps platform.

Leave a Comment