Codementor Events

Github Actions CI for Swift Projects

Published Aug 31, 2019Last updated Feb 26, 2020
Github Actions CI for Swift Projects

Github introduced CI and CD based on actions. It allows you to automate how you analyse, build, test and deploy your projects on any platform, including Linux, macOS and Windows.

I was excited over this news and can’t wait to try it out. My idea was to automate building and unit testing of Swift projects.

There are two types of actions and we should know the difference before starting.

Docker container vs JS

Originally all actions were based on Docker and used HCL syntax for workflows. Actions based on Docker run only in Linux virtual environment. With CI/CD announcement Github released JavaScript based actions and new YAML syntax for workflows.

For iOS projects you can use only JS actions because they should be run on macOS. Moreover using a JavaScript action simplifies the action code and executes faster than a Docker container action.

Lights! Camera! Github Action!

As an example I will use Texstyle. It’s a framework for formatting attributed strings. Let’s start with a complete configuration and inspect it step by step:

on: pull_request
name: Test
jobs:
  test:
    name: Test
    runs-on: macOS-latest
    strategy:
        matrix:
          destination: ['platform=iOS Simulator,OS=12.2,name=iPhone X', 'platform=tvOS Simulator,OS=12.2,name=Apple TV 4K']
    steps:
      - name: Checkout
        uses: actions/checkout@master
      - name: Build and test
        run: |
          cd Texstyle
          xcodebuild clean test -project Texstyle.xcodeproj -scheme Texstyle -destination "${destination}" CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO ONLY_ACTIVE_ARCH=NO
          bash <(curl -s https://codecov.io/bash)
        env: 
         destination: ${{ matrix.destination }}

At first you should select an event to trigger the workflow. My workflow is triggered on any pull request in the repository. Optionally you can label the workflow with name.

Workflows must contain at least one job. My workflow contains only one job for testing. It is possible to run up to 20 jobs concurrently per repository across all workflows.

Jobs run on virtual host machines that are specified with runs-on. In my case it’s macOS-latest, because I want to use xcodebuild. It’s a standard Apple developer tool and works on macOS only.

Texstyle supports both iOS and tvOS, so I want to run xcodebuild with two destinations. To specify different variations, I used strategy.matrix. I added two simulators with actual OS versions.

And the last step is to adding steps 🙃. I used checkout action to access the contents of the repository. You can specify the version of actions after @ sign with a release version, branch or specific commit.

Everything is ready for testing. I added run with bash commands to change current directory, run xcodebuild and send code coverage data to Codecov. To use matrix variables, I added env with the required variable name.

To read more about workflow syntax, check the documentation.

Comparing to Travis CI, my configuration looked like:

language: swift
osx_image: xcode10.2

env:
  matrix:
   - DESTINATION="platform=iOS Simulator,OS=12.2,name=iPhone X"
   - DESTINATION="platform=tvOS Simulator,OS=12.2,name=Apple TV 4K"

before_script: cd Texstyle

script:
   - xcodebuild clean test -project Texstyle.xcodeproj -scheme Texstyle -destination "$DESTINATION" CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO ONLY_ACTIVE_ARCH=NO
   
after_success:
  - bash <(curl -s https://codecov.io/bash)

That’s it! Here is an example of live logs:
1*vtXE2WRpFjZpPwMx3EIVJg.png

But that’s not the end, it’s just the beginning! Suppose that we want to reject pull requests if there are any linting warnings or errors. The most popular lint tool for Swift is Swiftlint. For now it’s possible to run it and see warnings in logs that is not enough. It would be great to see annotations from SwiftLint Violations via GitHub Checks API, or even have suggested changes. And actions allow to use this API easily.

Conclusion

As for me Github Actions CI is a game changer. It is deeply integrated into the service. And community-driven actions allow to reuse common scenarios.

Let’s summarise my experience with pros and cons.

Pros:

  • Various triggers for workflows. Pull requests, staring repos, project card statuses, scheduled events etc.
  • Speed. According to logs for Texstyle, last builds were 2 min 12 sec on Travis CI and 1 min 8 sec on Github CI.
  • Preinstalled software. macOS images have fastlane, swiftlint, Cocoapods, Carthage etc.
  • Marketplace. There are plenty of actions developed by community. You can reuse any of them.
  • Pricing. Of course, it’s free for open source. The time limits look pretty good — 2000 minutes for free plan and 3000 minutes with a Pro plan including private repositories 😏.

Cons:

  • Still in beta. First actions were written in HCL syntax. Support for it will be removed on September 30. And maybe it’s not the end, YAML syntax may be updated as well. So be ready to migrate your actions before public release.
  • Debugging. It’s hard to debug workflows as any CI service. You must trigger related event and wait for all steps. It’s not possible to test it locally, even validate workflow syntax.
  • Documentation. On of the goals of this article is to clarify Actions benefit for myself and give it a try on real project. I had many unobvious errors, official documentation and StackOverflow won’t help. For instance, a multiline run command won’t work without a name label. I believe open source workflows will help to avoid dump errors and handle edge cases in the future.

Thanks for reading! If you have any questions or ideas of workflows, feel free to leave comments or ping me on Twitter @iosartem.

References

Automating your workflow with GitHub Actions
Github Actions
Awesome Actions

Discover and read more posts from Artem Novichkov
get started