Advanced CI/CD for Android projects using Bitrise


This post was written by Bitbucket user Javier Marsicano.


People might think that mobile app development is not as complex as other software systems such as backend or web development. But that's simply a myth.

While mobile apps are likely to have less features or require less effort in terms of data processing or UI rendering, they are actually very complex. Therefore the codebase, as well as the development team, are often large enough to require strict tools to aid or even automate the development process. With more than two developers working in the same codebase, it isn’t as straightforward as integrating their work. As more developers involved, the complexity grows higher and higher. 

Configuration Management is defined as the discipline to coordinate, approve and implement changes to build and maintain software systems, establishing and maintaining the integrity of work products. As defined by the Software Engineering Institute, it involves the following tasks:

  • Revision of the status and history of each configuration item as necessary.
  • Systematic control and monitoring of baselines and releases of work products built from the configuration management system
  • Automatic alerting of relevant stakeholders when items are changed, or of decisions made regarding change requests.
Moderated_formal_review.png
A diagram depicting a basic configuration management setup.

To achieve Configuration Management in our software development workflow, the first tool we need is a powerful version control repository hosting service like Bitbucket.

With Bitbucket, we have a history of changes, change request control for the mainline (for instance main branch or development branch) and other features that distributed revision control systems Git or Mercurial capture. Moreover, with Bitbucket, we have a web-based code review UI that allows teammates to easily review our work with the additional benefits of being able to request changes before merging and learn from each other’s pull requests. Here is a good example of a code review workflow:

But using Bitbucket is just the beginning. W have to thoroughly monitor the codebase's integrity.

In agile environments, software development processes need to support frequent change, frequent builds (typically daily), multiple baselines, and multiple teams. A popular saying amongst technologists is "If you need to repeat a set of steps, you can automate it” which leads us to Continuous Delivery development practice.

When developing Android apps we have to detect bugs and issues as soon as possible immediately after integrating separate work developed by several teammates, like most software systems. Furthermore, it should be easy for QA testers to get in their mobile devices the latest build for UAT, smoke testing, etc. 

Setting up a continuous delivery pipeline for mobile projects

Bitbucket collaborates with CI/CD tools via webhooks to get instant feedback about any integration as well as triggering a build to deliver right away to stakeholders.

Let's look at a simple example using Bitrise. To setup a mobile project, follow the steps described here. Now, below I'm going to describe some insights we have to consider.

A CI/CD pipeline executes a set of reusable and configurable steps or jobs. In Bitrise, this is referred to as a workflow. Whichever branch flow your team uses – namely Git flow, promiscuous integration, etc – there should be at least a stable branch and many other secondary branches. So we should have at least one workflow that, when kicked off, compiles the codebase and executes unit tests, adding unit tests step. It’s represented by this icon: 

For more specific build system execution you should consider a Gradle step that allows you to execute with custom arguments, for example ./gradlew testDebugUnitTest. This step is represented by this icon: 

Also we should have early delivery workflows that build apk files of the desired flavors and distributes them so that QA and product team can install in different testing devices.

When creating a pull request to the stable branch Bitbucket should trigger the verification workflow that will execute a fast test suite.

Example workflow

On the other hand, when pushing changes to your stable branch (directly or merging a secondary branch), a Bitbucket webhook should trigger a thorough longer test suite, which may include functional tests. You can also use git tags to trigger some specific workflow with Bitbucket webhooks.

Example workflow

This way when one or more workflow steps fail, Bitbucket will notice authors and reviewers about the failing CI pipeline execution, warning them right away to let the team fix it before the issues are integrated into stable branch.

You can also configure your Bitbucket repository to automatically prevent a merge with unresolved merge checks

Static code scanning tools

There are also tools that help to maintain and even improve code's quality in our repository doing static code analysis, often called linters. We should seriously consider adding a lint task to our CI pipeline, so that whenever someone creates a pull request the linter's reports may warn that the code to be integrated might have code smells, performance issues, bad practices, etc. Likewise this tool helps to reduce technical debt as well as to ease code reviewers work.

There are many static analyzers for mobile projects that can be easily integrated into your Configuration Management workflow: Android lint, SonarQube, Spotless, Klint, Code Inspector, among others. Some of the issues that can be detected prior merging a branch are duplicated code, wrong threading management, memory leaks, high cyclomatic complexity, and many others.

Conclusion

Mobile developers should seriously consider integrating a thorough Configuration Management workflow to their projects through practices like code reviews and CI/CD pipelines. In my experience, Bitbucket allows to easily set up all the necessary tools and webhooks to automate as much of this process as possible.


Author bio:  Javier Marsicano has experience working at private and academic level as well in object-oriented applications based on Java technologies, nowadays working Senior Android Engineer.

Javier started working in 2012 on projects for CS research institutes, which involved several areas such as mobile applications, wireless networks, algorithms, among others. He has also taught on topics such as Algorithms, Programming Fundamentals 101 and Systems Architecture Introduction as an assistant professor.