Introduction
Continuous integration (CI) is a great software engineering practice. It requires developers to commit frequently and after each commit. With this, tests are run automatically, coverage is computed, static code analysis are performed etc, to make sure that every commit doesn’t break the building process and doesn’t introduce side effects. If a commit breaks the build, the person who made that change receives an email and needs to check and fix the build. Usually, at the end of the build, a test release is created.
In general, that’s the process, however it might vary from company to company. The benefits of such workflow are coming from the frequent integrations – you detect soon what’s wrong and have the chance to fix it quickly. The bigger the team, the more important is to have such automated integration process, because after every commit there is a risk that the codebase might be broken.
In this post, we will setup CI for an open source iOS project, by using Travis CI and Fastlane. The goal would be to run CI on every commit on the GitHub repo and display the information about build status and coverage in the Readme section.
Implementation
Travis CI
First, you need to have an open source iOS project on GitHub, with unit tests. In this post, I will be working with our soon-to-be-announced iOS framework GirdersSwift.
The first step is to connect your GitHub account to Travis CI, by clicking the “Sign in with GitHub” button. You will be asked to provide some permissions to Travis CI, in order for them to be able to access your open source repos.
Travis CI is free for open source projects, but there are some paid plans as well for commercial projects.
After you have successfully signed up for Travis CI, you should see all your projects listed in the dashboard. Find the one that you want to add CI for and enable the green switch.
That’s everything we need to do on Travis CI for now. With this small change, we have told Travis CI that it should run continuous builds for the GirdersSwift repo, but we still haven’t told it what to do. Travis CI doesn’t know whether it’s an iOS, Android, Java or other type of project. It also doesn’t know whether it should run tests, compute coverage and so fourth.
We provide this information by creating .travis.yml file at the root of our GitHub project. Let’s see what this file should contain.
osx_image: xcode9.3
language: swift
script:
– fastlane ios coverage
As you can see, we are telling Travis CI that it should run the build with Xcode 9.3 and the language is Swift. In the script section, we provide the steps that need to be executed after every build. Here, we are using Fastlane to run tests and coverage.
Fastlane
Fastlane is a great tool for automating all the tedious things connected to iOS development, from testing, building, creating releases, to deployment to the stores. It is based on the concept of lanes, defined in a Fastfile. You can define several actions in a lane and there are already developed actions for the most common things we need as iOS engineers.
We enable fastlane for our project by typing fastlane init at the root of your project. You can enter your developer account information as well, but that’s not required. This creates a fastlane directory, which contains the Fastfile. Now, let’s define our coverage lane, that will be used to execute the continuous build.
default_platform :ios
platform :ios do
before_all do
cocoapods
enddesc “Runs all the tests”
lane :test do
scan(
scheme: “GirdersSwift”,
code_coverage: true
)
enddesc “Runs coverage”
lane :coverage do
test
slather(
travis: true,
scheme: “GirdersSwift”,
coveralls: true,
proj: “GirdersSwift.xcodeproj”,
workspace: “GirdersSwift.xcworkspace”
)end
end
First, we define the before_all action, which always installs the CocoaPod dependencies for the project. If you are not using CocoaPods, you can remove this step. Next, we define the test lane, which basically calls the scan action, which runs the tests. Since we will display code coverage data, we need to enable code_coverage for this action.
Now, we can create our coverage lane. First, we run the test action and then we call slather, which generates the coverage report. Slather works well with travis – you can even configure in the action that you will be using travis. Apart from that, there is information about the scheme and the project, as well as coveralls flag, which we set to true. But what is coveralls?
Coveralls
Coveralls is a service that integrates with all the major CI products and is specialised in displaying your code coverage data. Similarly to Travis CI, is free for open source projects. To get started, go to their website and sign in with GitHub. It will ask you for the same permissions as Travis CI. After you are done with that, you can see all your GitHub projects listed in their dashboard. Again, enabling coverage information for your project is a matter of clicking a switch.
That’s all the setup we need to do. As you can see, it’s pretty simple.
Running CI
If everything is setup correctly, Travis CI will run your builds after you commit the .travis.yml file to your GitHub repo. Select the project in the Travis CI dashboard and you will see information about the current build (with a log below it), as well as information about your previous builds.
When the build finishes, go to the Coveralls dashboard, to see whether you have the coverage information there as well. You can navigate through source files and see which parts of your code are not tested enough. As you can see, there is some pretty useful information here.
Adding it on GitHub
Now, let’s show the world that we have continuous build that passes and a code coverage of 75%. That should be easily visible on our GitHub repo, so people know that we care about software engineering best practices. To do this, go to shields.io, and get your badge.
When you select the badge, you should enter the link to your GitHub account and repo and copy the Markdown to your Readme page on GitHub.
If all is setup correctly, you should see the badges for a passing build and code coverage, which will be updated every time your build runs.
Conclusion
As you can see, the process of setting up CI for your project is very simple, but the benefits are huge. You always get the chance to react soon on potential problems with your codebase.
One thing to mention is that there are other CI solutions as well, such as Jenkins. You can setup Jenkins instance on your infrastructure and run everything in-house. That requires a bit more work and maintenance costs, but also you keep all the code and access to it to your organisation.
Are you using CI for your projects? Do you think it’s useful? If yes, which products are you using? Share your thoughts in the comments section.