CI/CD for Swift Projects: Setting Up GitHub Actions

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction to CI/CD for Swift Projects

Modern development of mobile and desktop applications in Swift requires not only high-quality code but also a reliable integration and delivery process. CI/CD (Continuous Integration / Continuous Deployment) is a practice that allows you to automate building, testing, and deploying applications. For Swift projects, especially for iOS and macOS, GitHub Actions is one of the most convenient and popular tools.

In this article, we will walk through how to set up a full CI/CD pipeline for Swift projects using GitHub Actions. You will learn how to automate building, run unit tests, and even send the application to TestFlight or the Mac App Store.



Why GitHub Actions for Swift?

GitHub Actions provides built-in capabilities for working with the Apple ecosystem. Unlike third-party services, it is fully integrated with the repository and does not require additional plugin configuration. The main advantages are:

  • Free minutes for public repositories (up to 2000 minutes per month)
  • Ready-made actions for Xcode, SwiftLint, CocoaPods, and SPM
  • Support for macOS runners with pre-installed Xcode
  • Flexible configuration via YAML files


Basic CI Setup for a Swift Project

Let's start with a simple pipeline that will build the project and run tests on every push to the main branch or when a Pull Request is created.

Create a file .github/workflows/swift-ci.yml in the root of the repository:

name: Swift CI

on: push: branches: [ main ] pull_request: branches: [ main ]

jobs: build-and-test: runs-on: macos-latest steps: - uses: actions/checkout@v4 - name: Select Xcode version run: sudo xcode-select -s /Applications/Xcode_15.2.app - name: Build run: xcodebuild build -scheme MyApp -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 15,OS=17.2' | xcpretty - name: Run tests run: xcodebuild test -scheme MyApp -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 15,OS=17.2' | xcpretty

This workflow performs two main steps: building the project and running tests. Note the use of xcpretty — a utility that formats Xcodebuild output into a readable format.



Additional Code Quality Check

Let's add static analysis using SwiftLint. This will help maintain a consistent code style within the team:

jobs:  lint:    runs-on: ubuntu-latest    steps:    - uses: actions/checkout@v4    - name: SwiftLint      uses: norio-nomura/action-swiftlint@3.2.1      with:        args: --strict

Now, on every commit, the code will be checked against SwiftLint rules. If violations are found, the workflow will fail with an error.



Advanced CI/CD: Testing and Deployment

After the basic setup, you can move on to more complex scenarios. Let's consider a pipeline that includes:

  • Building for multiple simulators
  • Testing with code coverage
  • Automatic publishing to TestFlight (for iOS) or the Mac App Store


Building and Testing with Coverage

To collect test coverage data, use the flag -enableCodeCoverage YES:

jobs:  test-coverage:    runs-on: macos-latest    steps:    - uses: actions/checkout@v4        - name: Test with coverage      run: |        xcodebuild test \          -scheme MyApp \          -sdk iphonesimulator \          -destination 'platform=iOS Simulator,name=iPhone 15,OS=17.2' \          -enableCodeCoverage YES \          -derivedDataPath Build/DerivedData | xcpretty        - name: Upload coverage to Codecov      uses: codecov/cod                

Blogs

Book Recommendations