We’ve launched a new Android template in Bitbucket Pipelines. This template helps you automate building and testing an Android project in a Docker container, using Gradle as your build tool.
Access the template code here or go to the Pipelines tab of your repo and select the Android template.
This blog walks you through how this template is structured and has tips on how you can scale it.
Prerequisites
- Android Project with an empty bitbucket-pipelines.yml file in the root folder of the repo.
- Bitbucket Pipelines should be enabled in your repository. Simply navigate to your repository and click on Settings, and under Pipelines click on Settings again, and select the toggle to enable Pipelines.
If you’d prefer to quickly import a demo repository with a working pipeline to experiment with, have a look at our demo android repo.
Build an Android Project
Bitbucket Pipelines runs all your builds in Docker containers using an image that you specify at the beginning of your configuration file. In this guide, we are going to use Docker for Android SDK 30 with preinstalled build tools and emulator image from the Docker Hub.
Basic configuration
Once you have selected your Docker image, you can start adding a basic configuration to build an Android application:
image: androidsdk/android-30
pipelines:
default:
- step:
name: Android Debug Application
script:
- ./gradlew assembleDebug
bitbucket-pipelines.yml
This configuration contains the pipeline definition for all branches with a single step that executes./gradlew assembleDebug
script command.After you push the new bitbucket-pipelines.yml file you can view your Pipeline status, get detailed log information from its run, and a variety of other useful data.
From the Pipeline build tab, you can see that./gradlew assembleDebug
script command took 1m 16s to execute with a total build time of 1m 21s.Add caching to speed up build time
Bitbucket Pipelines is able to cache external build dependencies and directories, such as Gradle libraries, between builds providing faster builds. To enable Gradle cache, simply add caches command.
image: androidsdk/android-30
pipelines:
default:
- step:
name: Android Debug Application
caches:
- gradle
script:
- ./gradlew assembleDebug
bitbucket-pipelines.yml
After you you make the changes./gradlew assembleDebug
script command will take 21s to execute, reducing the total build time from 1m 21s to 35s.Note: when caching is enabled, the first Pipeline execution will take more time, because the cache has to be uploaded.
Store Artifacts
Artifacts are files that are produced by a step. The assembleDebug script command produces the Android .apk file in the app/build/outputs/ folder. To store artifacts, simply add artifacts command.
image: androidsdk/android-30
pipelines:
default:
- step:
name: Android Debug Application
caches:
- gradle
script:
- ./gradlew assembleDebug
artifacts:
- app/build/outputs/**
bitbucket-pipelines.yml
You can download artifacts generated by a step by selecting the Artifact tab of the pipeline result view as shown in the above screenshot.
To learn more about Pipelines build configurations check out this this article.
Running Static Code Analysis Tools
To keep repository code healthy most of the Android projects nowadays use static code analysis tools like lint, detekt, ktlint. In this guide, we are going to use lint.
Simply add./gradlew lint script command after the
./gradlew assembleDebug
script command. Lint produces reports in the app/build/reports/ folder as an .xml and .html files. To store these files as artifacts, add another artifacts command as shown below.image: androidsdk/android-30
pipelines:
default:
- step:
name: Android Debug Application
caches:
- gradle
script:
- ./gradlew assembleDebug
- ./gradlew lint
artifacts:
- app/build/outputs/**
- app/build/reports/**
bitbucket-pipelines.yml
Linting adds 16s to the build time.
Running Unit Tests
Running tests on CI is another important aspect to assert that the new code is behaving as expected.
To run android unit tests add./gradlew testDebugUnitTest
script command. Test reporting is automatically enabled in Pipelines, so we don’t need to artifacts command.
image: androidsdk/android-30
pipelines:
default:
- step:
name: Android Debug Application
caches:
- gradle
script:
- ./gradlew assembleDebug
- ./gradlew lint
- ./gradlew testDebugUnitTest
artifacts:
- app/build/outputs/**
- app/build/reports/**
bitbucket-pipelines.yml
The number of tests that have been executed is displayed on the right of the Pipeline step as shown in the bottom left of the above screenshot.
20 tests passed
Build and Test Faster
Parallel Steps
Adding more scripts to a single Pipeline step greatly increase total project build time. Fortunately, Bitbucket Pipelines provides a way to run steps in parallel.
To run steps in parallel, instead of running all scripts in one step, you can distribute scripts to multiple steps.
image: androidsdk/android-30
pipelines:
default:
- parallel:
- step:
name: Android Debug Application
caches:
- gradle
script:
- ./gradlew assembleDebug
artifacts:
- app/build/outputs/**
- step:
name: Lint
caches:
- gradle
script:
- ./gradlew lint
artifacts:
- app/build/reports/**
- step:
name: Debug Unit Test
caches:
- gradle
script:
- ./gradlew testDebugUnitTestimage: androidsdk/android-30
bitbucket-pipelines.yml
Total build time decreased from 1m 59s to 1m 39s.
Scale CI as your project grows
When your project grows you will notice that some steps are going to take significantly more time than others.
In the case of Android projects, steps which execute tests take the most time. While Gradle can execute tasks in parallel by enablingorg.gradle.parallel
flag, you will still be limited to CI machine configuration (Memory, CPU cores).Splitting the Android project into multiple modules can greatly increase project build speed. Let’s add another Android module called feature and move 10 of our tests from the app module into feature module.
Now we can split the Debug Unit Test step into two and run tests independently:
- App Unit Test
- Feature Unit Test
image: androidsdk/android-30
pipelines:
default:
- parallel:
- step:
name: Android Debug Application
caches:
- gradle
script:
- ./gradlew assembleDebug
artifacts:
- app/build/outputs/**
- step:
name: Lint
caches:
- gradle
script:
- ./gradlew lint
artifacts:
- app/build/reports/**
- step:
name: App Unit Test
caches:
- gradle
script:
- ./gradlew :app:testDebugUnitTest
- step:
name: Feature Unit Test
caches:
- gradle
script:
- ./gradlew :feature:testDebugUnitTest
bitbucket-pipelines.yml
Total build time decreased from 1m 39s to 1m 09s.
Bitbucket Pipelines at Atlassian
Here is an example of how one of our Android teams benefits from using Bitbucket Pipelines. The Android project has more than:
- 100 modules
- 4000 Unit tests
- 800 UI tests
With Bitbucket Pipelines running steps in parallel, the build time for this project is about 20 minutes.
Splitting the Android project into multiple modules can easily build and test your Android project at scale.
Get started with the Android template.