Menu

Migrating Your iOS Project From 1.0 to 2.0

This document will give you the guidelines for migrating your iOS project from CircleCI 1.0 to 2.0.

Overview

With the release of CircleCI 2.0 for macOS, your iOS projects can now benefit from the improvements in the CircleCI 2.0 platform, including:

  • Workflows: Orchestrate jobs and steps with great flexibility using a simple set of new keys in your configuration. Increase the development speed through faster feedback, shorter reruns, and more efficient use of resources.

  • Advanced caching: Speed up builds by caching files from run to run using keys that are easy to control with granular caching options for cache save and restore points throughout your jobs. Cache any files from run to run using keys you can control.

Example 2.0 iOS Project Configuration

This sample configuration file should work for most iOS projects on CircleCI 2.0:

# .circleci/config.yml

# Specify the config version - version 2 is latest.
version: 2

# Define the jobs for the current project.
jobs:
  build-and-test:

    # Specify the Xcode version to use.
    macos:
      xcode: "8.3.3"

    # Define the steps required to build the project.
    steps:

      # Get the code from the VCS provider.
      - checkout

      # Download CocoaPods specs via HTTPS (faster than Git)
      # and install CocoaPods.
      - run:
          name: Install CocoaPods
          command: |
            curl https://cocoapods-specs.circleci.com/fetch-cocoapods-repo-from-s3.sh | bash -s cf
            pod install

      # Run tests.
      - run:
          name: Run tests
          command: fastlane scan
          environment:
            SCAN_DEVICE: iPhone 6
            SCAN_SCHEME: WebTests

      # Collect XML test results data to show in the UI,
      # and save the same XML files under test-results folder
      # in the Artifacts tab.
      - store_test_results:
          path: test_output/report.xml
      - store_artifacts:
          path: /tmp/test-results
          destination: scan-test-results
      - store_artifacts:
          path: ~/Library/Logs/scan
          destination: scan-logs

  deploy:
    macos:
      xcode: "8.3.3"

    steps:
      - checkout

      # Set up code signing via Fastlane Match.
      - run:
          name: Set up code signing
          command: fastlane match development --readonly

      # Build the release version of the app.
      - run:
          name: Build IPA
          command: fastlane gym

      # Store the IPA file in the build artifacts
      - store_artifacts:
          path: ./MyApp.ipa
          destination: ipa

      # Deploy!
      - run:
          name: Deploy to App Store
          command: fastlane spaceship

workflows:
  version: 2
  build-and-deploy:
    jobs:
      - build-and-test
      - deploy:
          requires:
            - build-and-test
          filters:
            branches:
              only: master

Best Practices

To ensure a consistent build experience, it is best practice to add a Gemfile and set up code signing with the help of Fastlane Match before you push a 2.0 .circleci/config.yml file to your CircleCI iOS project.

Gemfile

We suggest that you add a Gemfile to your iOS project if you don’t have one already. Checking in a Gemfile and using Bundler to install and run gems ensures that recent versions of Fastlane and CocoaPods are available in your build.

Following is a sample Gemfile:

# Gemfile

source 'https://rubygems.org'
gem 'fastlane'
gem 'cocoapods'

Setting up Code Signing With Fastlane Match

Check out our code signing guide for the exact steps for setting up code signing for your iOS project on CircleCI 2.0.

Creating the 2.0 Configuration File

The following sections provide examples of 2.0 configuration syntax for an iOS project.

Job Name and Xcode Version

In the 2.0 .circleci/config.yml file the first few lines specify the name of the job and the Xcode version to use:

version: 2
jobs:
  build-and-test:
    macos:
      xcode: "8.3.3"
...
  deploy:
    macos:
      xcode: "8.3.3"
...

Build Steps Key

The top-level steps key contains all the build steps that will be run for a particular job:

jobs:
  build-and-test:
    steps:
      - ...
      - ...

You can see all the available step types in this doc. Note: Docker support is not available in the macOS builds.

Checking out the Project Code

One of the first items under steps will be the code checkout step:

jobs:
  build-and-test:
    steps:
      - checkout

Caching Ruby Gems Installed With Bundler

In CircleCI 2.0, cache save and cache restore are based on a cache key. Here is how you can cache the Ruby gems based on the content of Gemfile.lock:

jobs:
  build-and-deploy:
    steps:
      ...
      - restore_cache:
          keys:
          - v1-gems-{{ checksum "Gemfile.lock" }}
          # Fall back to using the latest cache if no exact match is found.
          - v1-gems-
      # Install gems.
      - run:
          name: Bundle install
          command: bundle check || bundle install
          environment:
            BUNDLE_JOBS: 4
            BUNDLE_RETRY: 3
            # This is the path where all the gems will be installed, and
            # which CircleCI will later cache.
            BUNDLE_PATH: vendor/bundle
      - save_cache:
          key: v1-gems-{{ checksum "Gemfile.lock" }}
          paths:
            - vendor/bundle

Every time your Gemfile.lock changes, a new cache will be created. Please check out this doc for more information about cache keys and other available key options beyond checksum.

Installing CocoaPods

If you are already checking your CocoaPods into your repository, there is no need to do anything in this step—your dependencies will be picked up correctly. However, if you are not including the CocoaPods into the repository, you will need to install CocoaPods in your .circleci/config.yml.

Installing CocoaPods with pod install will fetch the whole CocoaPods specs repo, and that can take some of the valuable build time. To make pod install faster on CircleCI and reduce your build time, CircleCI provides a cache of CocoaPods specs via HTTPS instead of Git.

Following is an example config snippet that will fetch CocoaPods specs using HTTPS and then run pod install:

jobs:
  build-and-deploy:
    steps:
      ...
      - run:
          name: Install CocoaPods
          command: |
            curl https://cocoapods-specs.circleci.com/fetch-cocoapods-repo-from-s3.sh | bash -s cf
            pod install

See [this CocoaPods guide] (https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control) for more details on checking your pods into the repo instead of installing them in your config.

Running Tests

It is possible to use Fastlane Scan to run your tests as follows:

jobs:
  build-and-deploy:
    steps:
      ...
      - run:
          name: Run tests
          command: bundle exec fastlane scan
          environment:
            SCAN_DEVICE: iPhone 6
            SCAN_SCHEME: WebTests

You can replace the bundle exec fastlane scan command with your custom test command, and change the environment variables passed into it. If your test command spans multiple lines, you can include multiple commands in a single step:

jobs:
  build-and-deploy:
    steps:
      ...
      - run:
          name: Run tests
          command: |
            make build
            make test

Storing Artifacts, Test Results, and Diagnostic Files

CircleCI 2.0 does not automatically collect artifacts in your builds, so if your build is generating files that you would like to access with the CircleCI application later on, you must explicitly collect those files with the store_artifacts step.

To view XML test results in the CircleCI application, add a store_test_results step in your .circleci/config.yml file.

To save logs as artifacts, use the store_artifacts step as shown in the following example:

jobs:
  build-and-deploy:
    steps:
      ...
      - store_test_results:
          path: test_output/report.junit
      - store_artifacts:
          path: /tmp/test-results
          # Destination is the name of the item in the Artifacts tab
          # that will contain the paths specified in this step.
          destination: scan-test-results
      - store_artifacts:
          path: ~/Library/Logs/scan
          destination: scan-logs

Find more details about these steps in the Artifacts doc and the Test Metadata doc.

Deployment Using Workflows

With the availability of Workflows in 2.0, it is best practice to extract all the commands related to the deployment of the app into its own job:

jobs:
  ...
  deploy:
    macos:
      xcode: 8.3.3

    steps:
      - checkout

      # Set up code signing via Fastlane Match.
      - run:
          name: Set up code signing
          command: fastlane match development --readonly

      # Build the release version of the app.
      - run:
          name: Build IPA
          command: bundle exec fastlane gym

      # Store the IPA file in the build artifacts
      - store_artifacts:
          path: ./MyApp.ipa
          destination: ipa

      # Deploy!
      - run:
          name: Deploy to App Store
          command: bundle exec fastlane spaceship

The previous example deployment job specifies an Xcode version, adds command to produce the release version, stores it as an artifact, and submits it to the App Store.

The following snippet adds a Workflows section to the .circleci/config.yml file to specify the conditions that run the deployment job:

version: 2
jobs:
...
workflows:
  version: 2
  build-and-deploy:
    jobs:
      - build-and-test
      - deploy:
          requires:
            - build-and-test
          filters:
            branches:
              only: master

In the previous example, CircleCI runs the build-and-test job on every push to the repository, and the deploy job will only run on the master branch after the build-and-test job has finished and is successful.

Refer to the Orchestrating Workflows doc for more examples of using Workflows.

Example Application on GitHub

See the circleci-demo-ios GitHub repository for a full example of how to build, test, sign and deploy an iOS project using Fastlane on CircleCI 2.0.