Demystifying the Android CI pipeline

Building software at scale requires a team of developers that are continuously modifying the codebase in parallel. These modifications can range from feature development, bug fixes or optimizations. When building at scale, it is essential to have a continuous integration (CI) pipeline that automates the flow of validating new changes to ensure that no errors or undesired side-effects are introduced. With the combination of automated CI pipeline and code review, we get a workflow that allows teams to be agile and flexible in the development of a software product.

Setting the stage: Most development teams follow a Gitflow workflow, a process that standardizes the branching model around the release process. All new development changes are branched off as features branches from the develop branch and gets merged only once if it has passed the CI pipeline and code review. This is also the main entry-point where new changes are being introduced so it is essential to catch issues with the codebase earlier in the process. Branches such as main, hotfix and release are used when dealing with releases.

Building for Android: The development cycle for Android is not any different. If teams are following the Gitflow workflow, they will require a CI pipeline that will automatically validate the changes through the Gradle build system. These validation can range from analyzing the correctness of the source code written in Java or Kotlin as well as the resource and dependency management within the Android framework. In the following sections, we will explore how we can build a CI pipeline that can help us validate new changes specifically for Android.

CI Pipeline

At minimum, the CI pipeline for Android requires a 3-step validation that will help validate the stability and correction of the application. The pipeline is split into stages to provide early feedback whenever an issue is discovered.

Compile and Build

The first step of validation is to ensure that the project can compile and build on the CI pipeline when new code is introduced. Without a CI pipeline, it would be pretty annoying to track down a change that broke the project for the entire team. While the project is compiling and building, Gradle is also being synced to ensure the build configurations are correct and able to download the required project dependencies. The build system will also package and generate the build artifact (APK or AAB). All of these operations are signs of validation that no errors are being introduced into the codebase.

What issues are we trying to catch?

  • Syntax errors or invalid build configurations
  • Incorrect management of project dependencies
  • Errors that prevent the creation of the build artifact

Lint

After validating that the project can be compiled and built, the second step of validation is to ensure that the codebase does not have any structural issues. Issues within the Kotlin codebase can lead to performance or reliability issues. A static code analysis tool can catch issues with formatting, complexity, exception handling, multithreading and much more. With the introduction of this tool, projects will adhere to a code quality standard throughout the development flow. Some static code analysis tools for Android projects are:

What issues are we trying to catch?

  • Catching any static code analysis issues in our Kotlin codebase
  • Catching any issues in our implementation within the Android framework regarding accessibility, usability and performance

Tests

Despite validating that the project can be built and does not contain any static code analysis issues, it is not enough to ensure that the actual implementation is correct. The third step of validation is ensuring that implementation behaves as it should when the application is being used by the user. In this stage, we will require tests that validate the correctness of our business logic as well as the UI layout. The testing for Android projects can be broken down to unit tests that validate pure Kotlin code and instrumented tests running on an Android device that validate the UI or any logic that requires the Android SDK. The validation requires the execution of the entire test suite.

What issues are we trying to catch?

  • New logic behaves as it should
  • New changes did not introduce any errors or undesired side-effect in other parts of the codebase

Conclusion

The CI process helps us validate new changes through an automated and repetitive process granting us the confidence that nothing will break. If errors are found in this process, developers can quickly resolve without impacting the customer experience. Validating an Android project requires the analysis and testing of various areas of focus independently. Only when we merge all of these validation stages into a single pipeline, the decision regarding the stability of the application can be made. In the efforts to remain agile and flexible, the CI pipeline needs to be growing side-by-side with development such that it can perform fast and reliable analysis and validation for future development work.