Aug 31, 2022
Senior Software Developer
If I was asked what is the main reason to not automate mobile application delivery, I would say that it’s because it is relatively easy. You just don’t need to do anything.
That is obviously one of the reasons completely automated mobile application delivery is a rare beast, but I wouldn’t accuse developers of overall laziness. There may be an understandable psychological barrier in trusting automation, and there may also be deficiencies in the testing process – in any level: unit, UI, or acceptance testing.
On the other hand, when you have built a fully functional application delivery pipeline, everything gets much easier. For one, you don’t need a person sitting in front of a Google Play console, manually pushing new versions for release. Most importantly, the pipeline acts as an indicator for the team on the status of the code, reporting whether acceptance tests have failed or passed.
Secondly, the whole environment gets much nicer for the developers, who don’t have to worry anymore about mistakes in the release process, remember every release command word for word, run continuous tests and so on.
Thirdly, of course, the automation helps end users, whose applications stay up to date and receive smaller update patches but more frequently. New features are thus available instantly, and application data security is maintained.
Not automating the process slows down the whole development team by increasing invisible manual work. The invisible work can also be considered as technical debt that needs to be paid by new team members through their input.
As our team has learned, building application delivery automation is demanding and time-consuming, but we have decided to slow things down a bit to go for it – because it allows us to speed things up considerably when we reach our goal.
The vision is to automate the whole application delivery from a commit in the version control system to a release for end users. In a little less than two years we essentially have designed all the building blocks for the delivery pipeline, but the pipeline as a whole still needs to be assembled, so to speak.
Some of the blocks are already in use, but for example we haven’t figured out how to utilise the Google-managed devices feature in a virtualized environment, so that part is still a work in progress.
Fortunately we have two things that have really been on our side during this process: the trust we have in our testing processes and the head start we got with using GitHub Actions.
At Elisa, we have been one of the pioneers using build automation tools, and we have been using GitHub Actions as long as it has been around. GHA supports our know-how of building automations by driving the steps in the automation process.
The pipeline of the delivery process is triggered by pushing a commit to a GitHub repository on our server, which is the location for version control and also where the automation tool accesses the code itself.
Every step is described as a workflow of GitHub Actions for the repo. The next step continues if the previous step succeeds, and the first steps are the compilation of debug and release variants of the application.
As Google Play requires a unique version code and a version name that is visible for end users, the version code is typically assigned manually. Version code assignment and the version name can be set by the delivery pipeline based on the code.
GHA is not a straightforward tool, and it demands delving into its intricacies, studying, and learning to use it. Fortunately there is a lot of open source software to help, and several users have created individual actions for Google Play, for example.
That has been of great use for our team, and we have of course given back to the GHA community and shared our own bug fixes and such for open use.
From the beginning of the process we knew that we have high confidence in our testing practices, so we should take advantage of that.
The testing process begins by running every non-UI unit test and then all UI unit tests. The UI unit tests are for Jetpack Compose compose functions and thus they are Android instrumented tests that require an emulator or a device to run them.
With Gradle build tool and Google-managed devices feature, the unit test step of the pipeline utilises the automatic provisioning of emulators. Downloads, installs, starts, and shutdowns are automated for running the tests on an emulator, and UI tests are run inside a container.
The behaviour of the features of the application is checked by running acceptance tests also in a container and using Google-managed devices to have an emulator for the test environment.
The source of truth for the acceptance tests is the specifications in feature files, to make it easy to access for all team members – as they perhaps don’t have access to code and GitHub. Confluence pages are then generated from the feature files as a part of the pipeline.
It is impossible to automatically see if there’s a missing acceptance test, so there is an additional check against work in progress, disabling the pipeline from delivering an unfinished feature to end users.
Finally, there’s the step to release the bundle of the application to Google Play, which is possible because of the automatic setting of the version code and version name.
In the future there could be an automated step to increase the roll-out of a canary release based on criteria, for example, event rate in Firebase Crashlytics of the released version.
Building automation demands genuine interest in the process from the developers. The most important part is understanding the role of testing in software development and trusting the testing process in a healthy manner.
As everything comes back to agile development that serves the overall Elisa business, knowing when to pull the brakes and when to speed up is of paramount importance.
If I was to give a single advice on the subject, I would suggest implementing all testing and automation on day one. The earlier they are in use, the easier it gets in the long run. There are no shortcuts in software development – and that is for the good of everyone involved.