Building a CI/CD pipeline for Android apps using GitHub actions.

Since its debut in November of 2019, GitHub Actions has demonstrated its dependability in a production setting. GitHub actions ultimately allow us to establish a workflow for our apps to automatically build, test, and deploy them, just like many other CI/CD systems.

The integration of GitHub Actions with GitHub is one of its best features. With the help of GitHub Actions, we can automate the procedure for repositories that are already hosted on GitHub without the need for any additional tools. Your code is on GitHub, your CI/CD is running on GitHub, and if you’d like, you can also have your distribution there. Now that you know what Github actions are let’s dive into using it to build our own android app.

The Config File

Like any other CI/CD tool Github Actions also uses a config file (usually a .yml ) that it uses to understand what actions it needs to perform. These files are kept under .github/workflowsfolder. Here is a simple illustration of how they appear

Overwhelming. I know. Let’s break it down into steps so you understand what’s happening in this config file.

Workflow Trigger

This small little step tells the Github actions when the workflow needs to execute. In our example, the workflow is triggered when some pull request is opened to the develop branch. There are a bunch of other triggers that your try to find the perfect setup for your workflow. You can find them here.

Jobs

Jobs are the different steps that would be executed sequentially to test, build and deploy the project. Let’s dive deep into each one of these steps.

Env Setup

To set up our environment, we must first define what os we would be using to build our app. Since we are building an Android app, using ubuntu should be good enough. We can do this by using the build step likewise.

Now we will define the actual steps we want to execute.

Checkout

We’ll use Checkout v2 from our first Action to do a git checkout of our repository. This is to pull the latest code and checkout to the branch that triggered the workflow.

Permissions

For us to generate a build using the command line we would need to provide gradelw with the required permission to execute.

Static code Analysis & Running test

We may want to run a variety of tests or analysis tools on our CI/CD infrastructure. Thankfully, we can execute our Gradle commands directly with GitHub actions. It is simple to launch, for example, our tests or Detekt by directly invoking the pertinent Gradle command

Additionally, we may use GitHub Actions to execute our Espresso Tests. We will present android-emulator-runner by Reactive Circus, one of the activities that enable us to activate them

Building the app.

Now the step we all have been waiting for actually building the app. Every project starts with gathering all of our artifacts for distribution and/or upload. Android has a unique feature, and that is the ability to produce many APKs/AABs based on our Flavor or BuildTypes. Depending on your team structure, some of them are relevant and some of them are less relevant. Fortunately, we can run Gradle instructions directly and produce the necessary amount of artifacts. To run our Gradle command. One illustration is as follows

Signing Artifacts

The next logical step in producing our Android artifact is signing it so that it can be installed on a device. We will use the old trusty r0adkll to sign our app.

Here are some additional details to help you understand what each line in the above snippet means.

The sign-android-release Action is used by the “Sign AAB” task. This is rather simple for the APK/AAB to be signed, we must give the key-related details.

  • releaseDirectory — The actual directory where the artifact would exist when built. You can get this path by building the app locally on your system and getting the path to the apk or aab from your project root.
  • signingKeyBase64 — Encode your signing key as base64 and store it in GitHub secrets. You can check this on how to add GitHub secrets.
  • alias — Our alias that was provided while generating the signing key.
  • keyStorePassword — Our keystore password that was provided while generating the signing key.
  • keyPassword — Our key password that was provided which generating the signing key.

Converting AABs to APKs (optional)

We might want to test our release builds before we publish them to PlayStore. Since installing an aab is a cumbersome task we can convert them to an apk using the buildtool action created by yours truly.

Archiving Artifacts

Once our apks and aabs are built and signed we might want to save them on GitHub as a release and also maybe post them to slack or another communication tool to indicate to the QA about the release generated.

In the code block, we find the apps, aabs and mapping files of our freshly generated release and then zip them up in a nice clean package so the folks accessing these don’t need to go hunting individually for each file.

Creating a release

The ability to create a Release directly in GitHub itself, which we can then utilise to distribute our artifacts, is an intriguing feature supplied by GitHub. For instance, have a look at the Release page for Timber version 5.0.1

These releases may each include a variety of artifacts, such as source code, documentation, etc. Additionally, it is possible to produce a CHANGELOG or release-specific notes. The fact that this is automatically created by the entire process, is undoubtedly helpful. The portion that will make the release on GitHub is this one.

Notifying the team

We use Slack as our primary tool for communication. One good thing to do would be to send out a nice little message to the team about what was just released. We also attach the zip file created earlier to a slack channel dedicated to builds.

Thanks for reading, if you have my articles feel free to subscribe to my newsletter or share the article.