by Chris B. Head of Mobile
Ssh, don’t tell anyone, but I’m going to reveal how we build and distribute Android apps here at Waracle.
It’s not really a secret though. All these tools are out there and there’s a fair amount of discussion about them, but putting them together for your team can seem quite daunting.
At Waracle, we aspire to a continuous delivery strategy along with transparency for our customers. As such, we have chosen a set of tools and processes that allow our developers to focus on building apps with quality and confidence, and without having to worry about the overhead of producing release builds or reports.
- git as a source control management tool, backed by GitLab allowing us to host our own source repositories and Continuous Integration (CI). We chose GitLab over other alternatives for its lightweight footprint and tight integration with git. It also requires you to store your build configuration in your project, meaning your CI jobs are automatically version controlled.
- Gitflow workflow – a branching strategy for git that helps us to manage features and releases.
- Gradle – the industry standard build tool for Android
- JFrog Artifactory – industry strength dependency and file repository
- Home-grown Gradle plugins, that react to the CI and upload artifacts to Artifactory automatically.
The build process
The Agile Manifesto states that you should favour individuals and interactions over processes, but that doesn’t mean you can’t have processes. With 100 or more years of shared development experience we were able to adopt, adapt and build a process that is unobtrusive to developers, while being useful to the whole team and our customers.
When we push certain branches to our remote repository our CI, which is part of the GitLab app, it builds, tests and deploys all the variants found in our Android applications.
Pushing to “develop” the CI automatically generates a “dev” build and deploys it to Artifactory. This allows us to do system testing throughout the sprint as we’ll generally only push to develop once a feature is complete.
When we’ve completed all the features for a sprint, we create a release branch which the CI automatically uses to generate a “release-qa” build and deploys it to Artifactory. Our QA team uses this to do final system testing of the app. Given we are going to be testing throughout the sprint as features are completed this is usually quite straight-forward since most problems have been detected earlier in the process. However, if problems are found at this stage, committing only to the release branch maintains the integrity of the source code and allows developers to continue development on other features.
Once system testing is complete we push code to “master” the CI automatically generates the released artifact which is what our customers test and deploy. Once this is done if anyone tries to push code that has the released version number, the build fails, so there is no possibility of re-releasing builds accidentally.
For Android libraries we use a subset of GitFlow; we don’t use release branches.
When we push to “develop” CI automatically generates a “SNAPSHOT” build of the library artifacts. SNAPSHOTS are intended to change frequently, so the app will reference the SNAPSHOT builds during development to ensure the app is working against the latest library code.
When we push to master it creates a “release” build of the library artifacts. If someone accidently pushes to develop without incrementing the version number of the library, the build will fail.
When we are ready to release an app we “release” any of the Android libraries it uses and remove the dependency on the SNAPSHOTS so that we have a consistent and stable app build.
You git it now?
At first glance, that might seem quite convoluted, but as far as most of our developers are concerned they are able to focus on building features using our TDD processes. Our customers are able to see builds throughout the whole development sprint and are able to get access to release builds the moment they are available.
There’s always room for improvement though. Our QA team is currently working on enhancing the process with automated UI testing to capture any regression defects. With a wide base of unit tests, and comprehensive suite of integration tests, it means our UI tests can be lightweight and quick.