Continuous Integration for Android
- Getting Started
- Understanding Continuous Integration
- Workings of a Continuous Integration System
- Working With a Docker Container
- GitHub Actions
- Understanding the GitHub Actions Workflow
- Setting up GitHub Actions for Android
- Defining Workflows and Jobs
- Running Unit Tests
- Running Instrumentation Tests
- Generating the APK File
- Code Coverage
- Setting up the JaCoCo Plugin
- Making the Build Fail
- Where to Go From Here?
GitHub recently started providing a workflow automation feature named GitHub Actions. You’ll find it under the Actions tab of your repository.
You’ll require a GitHub account to be able to use GitHub Actions. Open GitHub and sign in to your account.
Then create a new repository – name it SimpleCalculator and follow the instructions provided by GitHub to push the starter project to the newly created GitHub repository.
Great! You have your GitHub repository ready.
There should be several tabs at the top of your repo, the Actions tab is where the progress of workflow for the current repository is displayed. If you click on it you will see that it’s empty right now as you haven’t defined any workflows yet. You’ll learn to do so in the upcoming sections.
But before you can dive into using GitHub Actions, here are some important terms you should know:
For example, you might have a rule that says: Before running a job to generate an APK file, first run the job that runs test cases.
Unit tests and instrumentation tests can run in parallel.
Events are specific activities that trigger the workflow. Define them using the
- Jobs are a set of steps that execute on a fresh instance of a virtual environment. You can have multiple jobs and run them sequentially or in parallel by defining their dependency rules.
- Runners are machines that execute jobs defined in the workflow file. GitHub hosts Linux, Windows and macOS runners with commonly-used software pre-installed, but you can create custom runners as well. Basically, these are equivalent to the containers or virtual machines mentioned in the section above.
- Actions are the smallest portable building blocks of a workflow, which you include as a step. The popular one is actions/checkout@v2, which you use to check out the current repository into the runner’s file system. Use actions/setup-java@v1 to set up a specified version of Java in the runner.
- Artifacts are files like APKs, screenshots, test reports, logs and so on, which the workflow generates. You can upload and download artifacts to the current workflow using actions/upload-artifact@v2 and actions/download-artifact@v2 respectively.
These terms should be enough to get you through this tutorial. If you’d like to learn more important concepts, visit the GitHub Actions official documentation.
Understanding the GitHub Actions Workflow
As mentioned earlier, you’re limited to CLI when working with any automated tools — otherwise, they wouldn’t be “automated”.
In GitHub Actions, you specify these CLI commands using a YAML file. YAML is a human-friendly data serialization language like JSON, but cleaner, more readable and more expressive.
Here’s an example of a GitHub Actions workflow configuration file:
name: Simple Workflow Example
- name: Hello world step
run: echo Hello, World!
name: Print date
- run: echo "It is $(date)"
So, what does this YAML snippet do? Let’s go over this step by step.
- Here you give Simple Workflow Example as a name to the workflow using the
- Using the
onkey, list all the events that will trigger the workflow. Current workflow is triggered only on push events i.e. whenever you push the changes to GitHub repository.
- Define jobs using the
jobskey. build and time are the two jobs in this workflow.
- Inside a job, give it a name using the
- Define the runners on which the current job will be executed on. The greet and the time jobs both run in different instance of ubuntu-latest runner.
- In previous section, you learned that commands are only way to instruct the runners what they need to do. These are defined in
stepskey using the
runkey. Optionally, you can use
namekey to give a name or a description to the step.
needskey specifies that the time job will run only after the build job completes. By default, the independent jobs run in parallel to each other.
Create a directory .github in the root of the Git repository. Inside it, create another directory called workflows. This is where all the GitHub Actions configuration files go.
Now, save the YAML file mentioned above as simple-workflow.yaml and put it inside .github/workflows and add, commit, then push it to GitHub. GitHub Actions will then start this workflow. Go to GitHub and navigate to current project’s Actions tab to see the workflow in action.
As you can see, the jobs both executed successfully. Click on one of the jobs to see the logs of its execution. Take your time to understand how workflows, jobs and steps are laid out by GitHub Actions.
Setting up GitHub Actions for Android
As mentioned in above section, GitHub Actions requires that you must have the workflow YAML files in .github/workflows. You can have multiple workflow files that are triggered by events defined in those files.
For Android development, you’ll need to set up a JDK in the runner, then check out your source code in the runner’s file system. As for Gradle, Android Studio projects, by default, has a Gradle wrapper shell script gradlew and a Windows batch script gradlew.bat – which can be invoked using
Next, you’ll see how to design the workflows for your project.
Defining Workflows and Jobs
To define a workflow, start by creating android-workflow.yaml inside .github/workflows. Add the following code to the file:
name: CI Workflow
Here, you name the workflow CI Workflow and make it trigger when a user pushes a commit to this repository.
Next, you’ll define the jobs you need in the current workflow. Remember that the runner’s file system doesn’t have the code yet. So, you need to check out the code from the current repository and set up the Java environment in the runner. You’ll use actions to accomplish this. Recall that the actions are written as a part of job’s steps. After the
on key, add the following lines:
name: Build and run tests
- name: Checkout current repository in ubuntu's file system
- name: Setup JDK 1.8
- name: Print contents in current directory
run: ls -la
Here you’ve used actions/checkout@v1 and actions/setup-java@v1 to checkout the current GitHub repository and setup Java Development Kit in your runner respectively. The third step, as its
name says, prints the contents of current working directory.
Add, commit and push the changes to trigger the workflow. The current runner contains the following files: