CI/CD pipeline for Swift: setup from scratch on macOS and Linux

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

Your Swift project deserves an automatic sky: building CI/CD from scratch

\n\n

You've written a cool Swift package or application. The code flies, tests pass locally, you feel like a rock star. But as soon as you push — the nightmare begins: "Will it build on Linux?", "Will the tests pass on macOS?", "What if I forgot to run SwiftLint?".

\n\n

Sound familiar? If so, you need a CI/CD pipeline for Swift. It's like autopilot for your code: it builds, tests, checks style, and even deploys automatically. In this article, we'll set up a CI/CD pipeline Swift from scratch using GitHub Actions. You'll get ready-to-use working code that you can copy and use today.

\n\n
Spoiler: after setup, you'll get green checkmarks on every commit instead of stressing over the console.
\n\n

Why CI/CD for Swift is not a luxury but a necessity

\n\n

Swift lives in two worlds: macOS (Xcode, CocoaPods, Carthage) and Linux (Vapor, SwiftNIO, server-side projects). Without CI/CD, you risk:

\n\n
    \n
  • Missing a compilation error on another platform
  • \n
  • Forgetting to run the linter (and then the code looks like a disaster zone)
  • \n
  • Spending hours on manual deployment
  • \n
  • Wasting time hunting for regressions
  • \n
\n\n

A properly configured Swift CI/CD pipeline solves all these problems. It works 24/7, doesn't drink coffee, and never says "it works on my machine". Let's go!

\n\n

Step 1: Choose your tool — GitHub Actions

\n\n

We'll use GitHub Actions — it's built-in CI/CD in GitHub, and it's perfect for Swift. Reasons:

\n\n
    \n
  • Free for public repositories (2000 minutes per month)
  • \n
  • macOS runners — you can build with Xcode
  • \n
  • Linux runners — for server-side Swift projects
  • \n
  • Ready-made actions for SwiftLint, tests, deployment
  • \n
\n\n

If you use GitLab, Bitbucket, or Jenkins — the principles are the same, but the YAML syntax will differ.

\n\n

Step 2: Basic structure of a CI/CD pipeline for Swift

\n\n

Any pipeline consists of three stages:

\n\n
    \n
  1. Build — compile the project (SPM or Xcode)
  2. \n
  3. Test — run Unit tests
  4. \n
  5. Lint — check code style (optional, but highly recommended)
  6. \n
\n\n

Optionally, you can add deployment (e.g., to a server or TestFlight).

\n\n

Create the file .github/workflows/swift-ci.yml

\n\n

In the root of your repository, create a folder .github/workflows/ and inside it a file swift-ci.yml. Here is a minimal working pipeline:

\n\n
name: Swift CI/CD Pipeline\n\non:\n  push:\n    branches: [ main, develop ]\n  pull_request:\n    branches: [ main ]\n\njobs:\n  build-and-test:\n    runs-on: ubuntu-latest\n\n    steps:\n    - name: Checkout code\n      uses: actions/checkout@v3\n\n    - name: Setup Swift\n      uses: swift-actions/setup-swift@v1\n      with:\n        swift-version: "5.9"\n\n    - name: Build\n      run: swift build\n\n    - name: Run tests\n      run: swift test
\n\n

This CI/CD pipeline for Swift runs on every push or pull request to main/develop. It builds the project and runs tests on Ubuntu. Simple? Yes. But let's add some magic.

\n\n

Step 3: Add macOS and Xcode to the build matrix

\n\n

Swift developers often work on macOS, while the server side runs on Linux. To be sure the project builds everywhere, use a matrix strategy:

\n\n
jobs:\n  build-and-test:\n    strategy:\n      matrix:\n        os: [ubuntu-latest, macos-latest]\n        swift-version: ["5.8", "5.9"]\n\n    runs-on: ${{ matrix.os }}\n\n    steps:\n    - uses: actions/checkout@v3\n\n    - name: Setup Swift\n      uses: swift-actions/setup-swift@v1\n                

Blogs

Book Recommendations