Continuous Integration (CI) is a part of the DevOps process that aims at integrating code written by a team of developers. This involves building the code along with dependencies, testing it against a prepared set of unit and integration test suites, and creating reports listing the resulting artifacts.
By performing regular tests on the code in its entirety, spotting regressions early on, and producing stable artifacts to base future versions of the code on, CI helps avoid wasting time dealing with conflicts in the code that teams are collaborating on. This is why many consider it to be the cornerstone of agile software development.
CI is closely related to the idea of Continuous Delivery, in which the successful builds that result from the continuous integration process are deployed to staging or even production environments at regular intervals. CI has become one of the mainstays of modern software engineering, and all serious development teams have set up one of the many available CI solutions to accelerate their common efforts.
Since building code and running tests are usually resource-intensive processes, teams were quick to eliminate on premise CI servers in favor of cloud-based SaaS products. Over the last few years, local building and testing of code has made way for API-driven continuous integration. As DevOps technologies have evolved of late, the software companies behind each of the major CI tools have all had to adapt to them as well.
Let’s delve into what some of them have been doing, and then examine modern trends in continuous integration.
Although CruiseControl was the first formal continuous integration tool, Jenkins was the first to gain widespread adoption. It was built in Java and open sourced in 2004 by a developer at Sun Microsystems named Kohsuke Kawaguchi (Jenkins is the largest fork of the Hudson project).
Using Jenkins, developers can set up a workflow to pull their code from a version control repository like Subversion, Git, or Mercurial, and trigger code builds, test runs, and deployments every time the repository’s mainline has been updated.
Jenkins remains one of the most popular continuous integration tools on the market. While it was initially only meant to support Java, legions of developers have contributed plugins for many other languages.
For a modern development team, the main selling point in favor of Jenkins, beyond the option of an on-premise build server, is its flexibility. While its learning curve is somewhat longer than with hosted CI products, Jenkins can be customized to fit any DevOps workflow.
Initially Jenkins was only available as on-premise, but several cloud players have created SaaS solutions based on Jenkins. In particular, CloudBees, a company that previously offered PaaS hosting for Java and Scala applications, has recently hired Kawaguchi and pivoted to focus on their cloud-based Jenkins offering.
Jenkins is often compared to TeamCity by JetBrains, another traditionally on-premise Java-based CI tool, and Atlassian’s Bamboo, which can be either on-premise or hosted on Amazon EC2 and features deep integration with other Atlassian products like JIRA, Bitbucket, and HipChat.
Test suites within continuous integration workflows have evolved over time. Initially only unit tests were included, testing individual objects and software components in isolation. While this was already much better than nothing, only running unit tests could leave out problems in the communication between components. Automated integration testing was then born to mitigate these risks, but it still wasn’t enough to cover all bases. Indeed, even integration testing didn’t cover the problems that could be encountered by the end user navigating a GUI or web page.
Functional testing, previously the exclusive domain of manual testers, has become fair game for automation. Teams started using tools like HTTPUnit and Selenium to record browsing behavior and then replay the tests every time a new build was created.
Continuous integration also enables teams to link software versions with features and bugs by including issue identifiers from bug tracking tools in build metadata. In this way, project managers are able to follow progress from the output of the CI workflow.
CI in the cloud
Fast forward to 2011, and many dev teams were tired of self-hosting their own continuous integration system, as configuring it often proved costly in time and resources — time that could be better spent working on applications. SaaS solutions quickly proliferated to fill this gap in the market.
Travis CI is a hosted continuous integration service built on top of the GitHub API. It lets dev teams build any project, provided that the code is hosted on GitHub. Travis reacts to triggers within a GitHub repository such as a commit or a pull request using webhooks to start tasks such as building a code base. It uses GitHub not only to fetch the code but to authenticate users and organizations.
Teams using cloud-based solutions like GitHub and Travis CI for version control and CI no longer face the headaches of managing these tools themselves as was necessary only a few years ago. What’s more, since all actions on both Travis CI and GitHub can be triggered via their respective APIs, this workflow can be entirely API-driven.
Another advantage of hosted CI solutions is that they can provide much broader testing facilities. Browser and OS testing used to be a tedious affair — workstations and staff had to be dedicated to ensure that bugs didn’t appear within a certain environment. In contrast, a hosted solution can maintain a set of cloud-based servers with different configuration for this purpose. Travis allows testing on Linux, Windows and Mac environments. Travis CI supports a range of programming languages such as PHP, Ruby, Node.js, Scala, Go, C and Clojure. It now supports both public and private repositories, but it was traditionally associated with open source software — Travis CI’s free version is itself an open source project hosted on GitHub.
Similar tools out there include:
- TestCafe is a specialist service that lets teams record functional tests and runs them in a variety of browsers.
- CircleCI is a popular hosted continuous integration service. One of its differentiating features is its focus on performance. It makes heavy use of parallel computation and splits test suites to run tests in parallel. CircleCI supports many startup-friendly programming languages and it supports testing against many modern SQL and NoSQL databases like PostgreSQL, MongoDB and Riak.
- Codeship is similar to Travis and CircleCI but supports both GitHub and BitBucket for both code and credentials. It does continuous integration and continuous delivery, supporting deployments to PaaS hosting platforms like Heroku and Google App Engine. It also integrates with internal communication tools like HipChat and Campfire. Codeship’s Parallel Test Pipelines is its answer to CircleCI’s parallel running of test suites.
The advent of smartphones has led to a cambrian explosion in mobile application development. Mobile apps have specific requirements in terms of their build, test and deployment processes. Some of the major CI vendors have a mobile CI offering — like CircleCI, who purchased Distiller to provide support for iOS apps.
We’ve also seen the emergence of mobile CI specialists, such as:
- Hosted-CI, a hosted CI solution focused on iOS apps (as well as desktop applications for OS X) built on top of Jenkins.
- GreenHouse, which supports native iOS and Android code as well as cross-platform frameworks like Cordova and Ionic.
- Bitrise is a similar solution. In addition to native Android and iOS apps, Bitrise supports apps built with Xamarin.
Indeed, mobile applications have different requirements in terms of testing and distribution, and different mechanisms for dependency management (such as Cocoapods for Swift and Objective-C apps).
Mobile testing also requires different software from web application testing. Mobile testing frameworks like Espresso for Android and Appium automate away much of the inherent difficulties, but since mobile apps — like native desktop apps — run on the client side and outside of the well-defined context of a browser, that still leaves a large grey area that developers don’t like to leave unattended.
Crashlytics, now part of Twitter Fabric, has mobile crash reporting capabilities in addition to its built-in CI support. These alerts help dev teams analyze and react to difficulties encountered by users on their mobile devices. HockeyApp also reports crashes for mobile and desktop apps and enables you to test against simulated mobile environments.
Since there are wide varieties of mobile clients, especially in the Android world, it is impractical to have all testing performed in a centralized manner. Instead, beta testing has been embraced in the mobile development community, with tools like TestFairy and
TestFlight to distribute tentative new versions of apps to beta testers.
Distribution of mobile apps is a fundamentally different problem when compared with web applications. Instead of simply pushing all the code, including client-side components to a server environment like Heroku or Amazon Web Services, a mobile app must go through the cumbersome approval process of the relevant app stores. This slows down the continuous delivery process and unfortunately introduces manual steps in an otherwise fully automated process.
Fastlane, also now part of Twitter Fabric, aims to streamline the delivery of apps by automating most elements of the app approval workflow, like taking screenshots of the new app and dealing with certificates. Fastlane is sometimes used in combination with a CI tool like Jenkins.
Future of CI
Continuous integration and continuous delivery are here to stay. Most development teams wouldn’t consider tackling a significant software project without setting up a CI workflow.
But it’s far from a static discipline — there are constant innovations in the area of CI, and new fields of application. We’ve explained how CI is relevant to web and mobile development, but the coming years will show us how it will be integrated into development processes in smart watches, smart cars, and more generally throughout the internet of things. What will CI look like for virtual reality and biotech software?
APIs are increasingly becoming the bedrock of internet communications, and stability is paramount to a well-functioning API, so CI will increasingly matter in API development.
An ongoing problem in CI is the difficulty of automating tests in development environments that are not always similar to production. A recent evolution in DevOps is the growing popularity of Docker, a container technology that allows you to isolate applications and their dependencies from the underlying systems they run inside. Docker’s portability has led several CI vendors to embrace Docker. CircleCI supports container-based applications and CodeShip recently introduced Jet, its solution to test and deploy Docker applications.
Docker simplifies modern CI; a throwaway build or test server is suddenly only an API call away. Docker also reduces the need for OS testing as it standardizes application runtime environments.
From its beginnings as an additional chore for developer teams and a somewhat reluctant concession to code quality, Continuous Integration has become one of the mainstays of modern software development. CI has has moved to the cloud and is gradually growing in scope; the next avenue for CI is perhaps the Internet of Things, an implication we are excited to explore soon. Also in an upcoming article we’ll track another important aspect of DevOps, namely Configuration Management, so stick around.