Mobile applications CI on the Cloud

The process of packaging and shipping your mobile app is one of the most critical ones, as much it is one of the most delicate and complex ones. Let’s break it down to its atomic components:

  1. Developing features
  2. Writing tests
  3. Building the application
  4. Running tests
  5. Deploying the application

But is it really all there is to it? Let’s refactor:

  1. Developing features
    • Creating a feature branch in order to allow different developers to focus on different features.
    • Integrating features into the master branch by merge.
  2. Writing tests:
    • Developing tests using automation and unit testing frameworks
  3. Building the application
    • Build machine
      • Required dependencies
      • Build on one’s own machine
  4. Running tests
    • A suite of devices of various makes, OS and OS version

As you can see, the process is composed of subprocesses that are composed of tasks and subtasks. Setting up, managing and monitoring all of the above can and will ultimately turn into an overhead nightmare. On top of overhead, you have to be cautious about introducing bugs into your project. Have a Look at requirement 1.b. Can you foresee an integration that introduces bugs? Can you afford the time and effort entailed by procurement and maintenance of so many devices? Remember the overhead, you want to minimize maintenance as much as possible so you can focus your effort and resources on development and QA.

What you want to do is setup, configure and automate the process such that there is little to no manual intervention. As the title of this post suggests, a good option would be to setup a CI pipeline in the cloud. Let’s go through the various required components and methodologies that will help you reach your goal of setting your framework of “Mobile Applications CI on the Cloud”.

The Cloud

An amorphous concept in and of its own but a solid one nevertheless. To simplify things, the cloud is just a remote service that frees you from the need to setup services and environments locally. With high uptime and stability, as well as consistent development and testing environment, the cloud offers your developers a stable and consistent environment.

CI in the Cloud

CI stands for “Continuous Integration” and spells out the need to be able to integrate code without breaking the build or introducing bugs. A successful build and minimum amount of bugs (because let’s be honest, no bugs is utopia and we are not about utopia in this post), constitute “Continuous Integration” because it allows you to continually push code if and only if the code meets the two most important conditions:

  1. Successful build
  2. Tests pass

Any failure to meet any of these two conditions will prevent the code from being integrated, saving you hours of debugging and tracing down the faulty code. If the code doesn’t fit, it’s not going to be admitted.

CI Services

With cloud in mind, you should aim to use cloud based CI services. The list includes Jenkins, Travis, circleci, TeamCity and more. With these services you define your CI pipeline. The CI pipeline is a set of instructions that make up the CI process. They include spinning up an environment with required dependencies, building the app or compiling the code, running tests, publishing results and eventually integrating the code into the current branch. Remember that the integration is only allowed if the build succeeds and if the tests pass.

Devices in The Cloud

Defining and setting up the CI template is starting point of the CI process. Once you have the CI pipeline figured out, you need to obtain a set of devices on top of which your tests will run. Given the the time and effort involved in obtaining these devices, connecting them to your local machines, and maintaining them (keeping them updated, clean and fully charged at all times), it is much better to have these devices hosted and maintained elsewhere.

Putting Everything Together

If you take all three elements discussed above, CI in the cloud, CI services, devices in the cloud, and consider them carefully it should start getting clear what we are aiming at here. Think of as a flow chart (we will review one in abit). First, identify the cloud services you want to use. Then, plan your CI route. Finally, execute. It is that simple.

Let’s look at a simple diagram that demonstrates the concept.

A diagram breakdown is as follows:

  1. Developer pushes code
  2. The repository notifies the CI service
  3. The CI service pulls the latest changes to the branch and starts building the app
  4. If the build is successful, the CI service installs the app on cloud devices (that’s where we come in). If the build failed, the whole process stops and the developer is notified.
  5. The CI service then continues on to run pre-defined tests on the newly installed application.
  6. If the tests pass, great. The code is integrated by way of merge or push. If tests failed, the process stops and then developer is notified.

As simple as that. Once you get the whole pipeline setup, it is a matter of just tweaking the pipeline script.

Real-World Example

It’s all nice in theory but what about putting it into practice? Clouds, CI services, devices, apps, where do they come into play and how do we intertwine them together in the pipeline? Let’s look at a real world example.

Setting up the scenario and requirements

In the middle of running the sprint, Dave and I are developing new features for our mobile application. We have already branched off master to a feature branch and I now branch off the feature branch to my own branch in order to work on the features for which I am responsible. My goal in branching off to my own branch is to prevent any disruption to Dave’s work in the form of failing builds.

With much effort and a lot of coffee, I finally finished introducing the new features. Now I want to test them. What I want to do next is the following:

  1. Develop my tests by combining an automated testing framework with a unit testing framework. I use Appium, Java and Junit.
  2. Set up my CI job (I’m using Jenkins):
    • Create a pipeline CI job
    • Parameterize the test (parameters are added as environment variables):
      • Add the cloud access key
      • Add the git repository username and password
  3. Configure the pipeline with a Jenkinsfile (written in Groovy)
    • Pull the repo at the feature branch
    • Build the app
    • Upload the app to the cloud
    • Run the tests
      • Install the application on the selected devices
      • Run the tests
      • Return test results
  4. Based on results (see step 3):
    • Merge my branch with the feature branch
    • Fail the job and send a notification with test results

CI Example Using Jenkins

We have a webinar on the topic coming soon, stay tuned!