/IosContinuousIntegration

Demo project which can be used to test continuous integration for iOS 9 applications.

Primary LanguageSwift

Continuous Integration with Fastlane and Jenkins

This is the demo project linked to the blog article available on the Zühlke Blog.

Follow the steps outlined in this document to set up a minimal continuous integration workflow with Fastlane and Jenkins.

Environment and Tools installed

  • Mac OS 10.11 El Capitan
  • Xcode 7.1
  • iOS 9 project with cocoapods setup for Alamofire 3.1.1
  • RubyGems 2.4.8
  • Fastlane 1.37.0
  • Jenkins 1.634
  • Cocoapods 0.39.0

Install and configure fastlane for your project

Before installing the CI server, the lane needs to run on your machine. Make sure the following works before starting to [configure Jenkins](## Install and configure Jenkins).

Install Fastlane

See the official documentation: https://github.com/fastlane/fastlane#installation

At the time of the writing:

  • sudo gem install fastlane --verbose
  • xcode-select --install
  • If you experience slow launch times, try gem cleanup
  • The lane we will be using also requires Cocoapods to be installed: sudo gem install cocoapods

Init Fastlane for your project

Initialize Fastlane with fastlane init, in the root of your Xcode project. Enter an App Identifier, your apple ID and the scheme name of the App. If you want to start simple, do not setup deliver, snapshot and sigh. They can be initialized later on, for example with deliver init. Check the full console output of my installtion for more details.

Create your testing lane

For an easier access to Fastlane files, drag the fastlane folder inside your Xcode project. Drag fastlane folder into Xcode

Open fastlane/Fastfile and create a simple testing lane. These are the key elements:

  • Build the app with: gym(scheme: "IosContinuousIntegration", workspace: "IosContinuousIntegration.xcworkspace", use_legacy_build_api: true)

    • workspace allows to build a project where cocoapoads are installed.
    • if a workspace is specified, the scheme is mandatory. There are indeed 3 schemes in this demo app: IosContinuousIntegration, Alamofire and Pods.
    • use_legacy_build_api fixes an issue of the Apple build tool
  • Run the tests with: scan(device: "iPhone 6s")

    • device defines which simulator will run the tests
    • scan can be configured through a Scanfile. In this example, it is used to set the scheme of the application.

The lane called test uses the action increment_build_number which requires a Build number set in Xcode. Set it by clicking on the target / Build Settings tab and search for CURRENT_PROJECT_VERSION

Current project version in build settings Set the current project version in Xcode. Make sure "All" is selected in the header, and not "Basic".

Make sure the lane is working by running fastlane ios test. Thanks to gym, an archive will be added in the Xcode organizer. The Unit and UI tests will also be executed in the simulator. Fastlane console result Result output for the command fastlane ios test. 1 Unit Test and 1 UI Test have been executed.

Install and configure Jenkins

Now that you have a lane running the tests, you need a CI server executing it automatically for every commit.

Note: to be able to run tests for an iOS project, you need a Mac with Xcode and Fastlane installed. In a real-life setup, Jenkins runs on a centralized server, where every developer can check the current state of the project.

Install jenkins

  • Install Jenkins: brew update && brew install jenkins
  • Start Jenkins: jenkins
  • Browse Jenkins on http://localhost:8080
  • Install Jenkins plugins:
    • On http://localhost:8080, go to Manage Jenkins / Manage plugins / Available
    • Search for the following plugins and click "Download and install after restart":
      • AnsiColor: show colored output of Fastlane log files
      • GIT: allow the use of Git as a build SCM
      • Slack Notification Plugin: can publish build status to Slack channels.
    • Restart Jenkins by checking "Restart Jenkins when installation is complete and no jobs are running". Restart Jenkins What can be seen while installing a plugin.
    • The installed plugins are visible in Manage Jenkins / Manage plugins / Installed.

Create a build job

The build job is what will start the lane for every new commit pushed to the repository.

  • New Item / Freestyle project, enter a build job name and click ok Create a build job

  • Configure Source Code Management by choosing GIT and entering the SSH URL of the repository. Configure SCM

  • If you get a Permission denied error, make sure the user running Jenkins has an SSH key set in his Github profile.

  • Configure Build Triggers to periodically check whether there is a new commit in the repo. We use here the polling approach from Jenkins to the repository. Push notifications from the repository to Jenkins is another alternative. Configure Build Triggers

  • Configure AnsiColor to get the right colors in the console output of Jenkins. Configure AnsiColor

  • Configure Slack Notification Plugin so that every information about the build gets posted in a channel. Configure Slack Notifier

  • Add a build step which will run the lane: Add build step

  • Configure the build step by writing the same command we ran locally: Add build step

  • Add a post-build action to enable Slack notifications Slack Post build

  • Click save to persist the changes.

Configure Slack Integration

Don't forget to activate a Jenkins Integration in your Slack channel.

Configure Slack Integration for Jenkins A Slack channel right after creation, with the link to add a service integration

Posting all the build info into a Slack channel allows the team to get informed about build failures. They can discuss about it and get notified when everything is back to normal. Slack works on every OS and push notifications can be enable on the Slack's mobile app.

Why using Slack? Example of what can be achieved when using Slack notifications for every build

Test the build job

  • On Jenkins Webapp, click Build Now to make sure the build step is working.

  • If everything worked as expected, you should see a blue bubble in the left of your build history in Jenkins. Build history Example of a build history on Jenkins containing only 1 successful build

  • Click on the build number to get more information like the full console output.

  • Notifications should also have been sent to the configured slack channel. Slack Build Notifications What you should see in your Slack channel after this manual test build

  • As a final test, find a way to make your tests fail, and then commit and push the change. After max 1 minute, the build job should automatically start. After about a minute or two, the build history should contain a red bubble, identifying a failed build.

  • Fix the test, commit and push again and make sure the Jenkins returns to blue. Build history with failed build Example of a build history on Jenkins, with 2 sussessful builds (#1 and #3) and 1 failed build (#2)

References