Your product ideas may be the greatest of all time, but without delivering well and delivering often, it may be extremely hard to keep up with the competition. In this article, we'll show you how continuous integration and delivery can help you do just that.

What you'll learn about in this article:

What is continuous integration and delivery (CI/CD)

What's the differences of mobile CI/CD and web CI/CD

How to set up a CI/CD pipeline

Why does Flutter require dedicated CI

Continuous Integration (CI)

Continuous Integration is the process of merging the code of all developers into a main source code, so that developers can find and fix the issues as soon as possible. The popular scientist Martin Fowler defined continuous integration as follows:

“Continuous Integration doesn't get rid of bugs, but it does make them dramatically easier to find and remove."

The main goal of CI is to provide faster feedback and speed up the development process. Fixing bugs early on is cheaper than putting it off till it's too late.

The term continuous integration was first coined in 1994 by Grady Booch and used in extreme programming practices later. The first ever continuous integration tool was CruiseControl. Since then, CI servers have evolved with time and many companies have started to provide CI services.

A continuous integration server performs following things:

gets access to the Source Code Control, e.g GitHub, and checks out the code on the server;

performs static analysis on the code to detect syntax related issues;

Builds and compiles the app using the source code;

Runs the different flavours of the tests;

Team fixes the issues as soon they are found by the server.

CI practices include the build automation, self-testing and faster builds.

Continuous Delivery (CD)

Continuous delivery (CD) is an extension to continuous integration where the working software can be released to the end users at any time. The process of continuous delivery adds extra steps to the above mentioned CI process, which are:

Packaging application;

Code Sign (if needed);

Deploying the application to specific environments.

With continuous delivery the software teams can achieve fully automated, low risk, and low cost releases. This process enables one click deployment where you can get the releasable build whenever needed. However, manual intervention is always required to deploy the software to production. In continuous deployment, there is no manual intervention, the committed code reaches production straightaway.

The combination of CI and CD processes forms the CI/CD pipeline.

CI/CD pipelines for mobile apps

The CI/CD pipelines for mobile apps differ from web apps due to the complexities involved in the building and packaging of the mobile apps.

The main differences of mobile CI/CD and web CI/CD are:

The deployed code for web apps runs in the browsers while the deployed code for mobile apps runs in the various versions of the devices and operating systems, e.g Android, iOS.

The web application code and infrastructure have to be maintained by the companies using data centers or a cloud, e.g AWS, Azure or Google Cloud.

The tools and technologies used for developing mobile apps are different from the ones used for web apps. Websites can be built by various web technologies like Java, Ruby, and JavaScript, while mobile apps are built using languages like Swift, Kotlin, JavaScript, or Dart.

Code signing is mandatory for the deployment of mobile apps, however most web apps don't require any code signing.

Another major difference is that web deployments are push-type, where we can push the code change to production and users have to accept all the deployed changes. Mobile deployments are pull-type, where we have to submit an app to the App Store for review and then Apple or Google will review the app before it goes to the end users. Once released, mobile apps need to be explicitly updated by the users.

With the limitation of pull-type deployment, mobile apps can not achieve continuous deployment. However, continuous delivery is still possible for mobile apps.

How to set up a CI/CD pipeline

In order to set up CI/CD pipelines, it's essential to know the underlying command line tools to automate the common tasks. In the case of mobile apps, CI/CD pipelines are a bit complex and require extra steps, like code signing and publishing to the Apple App Store or Google Play Store. Mobile CI/CD pipelines require build automation tools. A couple of widely used build automation tools are Fastlane and Gradle for iOS and Android respectively. Let's explore how to automate a CI/CD pipeline for mobile apps

Automating static analysis

Static code analysis is the process of finding syntax and coding style related issues. There are various tools available for every language to detect the syntax and coding style issues. These tools are also called linter. While developing mobile apps, we need to choose the correct linter tool to perform the coding style checks.

When building Flutter apps, we need to use the linter for the Dart programming language. The static analyzer is one that can be used for linting the Dart code. While setting up CI/CD pipelines, static code analysis should be the absolute first step in the build process, so that we can fail the build early if there are serious coding errors.

Automating the build process

Once the linter step is passed, we can move on to the building and compiling of the source code. Building mobile apps requires compiling the source code, resources and other app-related data. The end result of the app building process should be generating the build artifacts. In the case of iOS, it should be a app/.ipa file and in the case of Android a apk file. When setting up CI/CD pipelines, we should use relevant tools to build the mobile apps. In the case of Flutter apps, we need to use the flutter build command with various parameters, e.g for building iOS and Android versions of the Flutter apps:

$ flutter build ios –release

$ flutter build apk –release

The build step should generate the build artifacts for the mobile apps.

Automated testing/code coverage

Automated testing is an integral part of CI/CD pipelines. Without automated tests CI/CD pipelines will lack quality checks which are important in order for the app to be released. Automated tests can be written for various levels. There are some lightweight tests like unit, integration, API tests, and there are long-running tests like UI tests which are very useful but require maintenance. The code coverage part should also be considered while setting up CI/CD pipelines. This will give some insights on how much code is covered by the tests.

With Flutter apps there is great support for automated testing for all levels. We can also write Widget tests for testing widgets. We can execute the flutter tests using the following command:

$ flutter test

The testing phase in a CI/CD pipeline gives you confidence that app functionality hasn't been broken with the latest code changes.

Code signing and publishing

While setting up CI/CD pipelines for mobile apps, we need to consider code signing. The code signing process is a bit complex to understand as it requires some assets to be generated before we code sign an actual app, e.g Certificate, Profiles, etc. We have written an article covering the basics of code signing for mobile apps.

Once the app is code signed, it needs to be published in Apple App Store or Android Play Store or some third-party beta testing services. The CI/CD process should have the ability to publish the app on any platform configured by the user.

Automating notifications

Once the build is finished, it's important to send a notification to the team with the status of the build and artifacts. The developers can always check the logs but it would be convenient to send the notification in terms of email, Slack or a similar notification service. The CI/CD pipeline should trigger this notification at the end of the build.

There are some CI/CD tools available on the market for mobile apps. The CI/CD tools can be of two types.

Self-hosted

The self-hosted CI/CD solutions require owning hardware, e.g macOS machines or Linux servers. The process of setting up CI/CD pipelines can take longer and the maintenance of both hardware and software packages is always required for the in-house CI/CD tools. Some examples of the Self-hosted CI/CD tools are Jenkins, TeamCity, BuildKite, etc.

Cloud-based

Cloud-based CI/CD tools are easy to set up and all the hardware and software packages are managed in the cloud. As most of the complex tasks, like code signing and publishing, are being handled in the cloud, it requires less maintenance and developers can concentrate on building the business features. Some cloud-based CI/CD tools include Nevercode, Bitrise, Travis CI, Circle CI, etc.

Why does Flutter require dedicated CI?

Flutter is a cross-platform mobile app development framework from Google which allows us to write both iOS and Android source code with the same source code.

Smooth and automatic deployment

Flutter apps look almost like native apps because of the widgets. However, the process of deploying Flutter apps can be time consuming. Flutter documentation has a cool guide on deploying iOS and Android apps but there are many manual steps needed to be followed in order to release Flutter apps. It would be great to automate the whole Flutter app distribution process using a convenient tool with great user interface. Flutter apps could be deployed automatically if developers made deployable code changes.

Painless code signing

Flutter apps still require code signing for both Android and iOS apps. There are ways to script the code signing tasks, but usually it requires a lot of effort in writing and maintaining the scripts.

Easily downloadable build artifacts

Flutter CI/CD pipeline generates the build artifacts, however there are extra steps involved if we want to download the build artifacts generated by the CI/CD tool. It would be great if the CI/CD tool were able to provide the mechanism for easy downloading of the builds on devices.

Conclusion

The CI/CD process for mobile apps has become mandatory in order to deliver quality apps to the end user and avoid the cost of bugs in the later phases. Especially for the apps developed with cross-platform development technologies like Flutter. It's useful to have a dedicated mobile only CI/CD platform for building and publishing mobile apps.