Your Swift project deserves an automatic sky: building CI/CD from scratch
\n\nYou'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\nSound 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\nSpoiler: 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\nSwift 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
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\nStep 1: Choose your tool — GitHub Actions
\n\nWe'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
If you use GitLab, Bitbucket, or Jenkins — the principles are the same, but the YAML syntax will differ.
\n\nStep 2: Basic structure of a CI/CD pipeline for Swift
\n\nAny pipeline consists of three stages:
\n\n- \n
- Build — compile the project (SPM or Xcode) \n
- Test — run Unit tests \n
- Lint — check code style (optional, but highly recommended) \n
Optionally, you can add deployment (e.g., to a server or TestFlight).
\n\nCreate the file .github/workflows/swift-ci.yml
\n\nIn the root of your repository, create a folder .github/workflows/ and inside it a file swift-ci.yml. Here is a minimal working pipeline:
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\nThis 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\nStep 3: Add macOS and Xcode to the build matrix
\n\nSwift developers often work on macOS, while the server side runs on Linux. To be sure the project builds everywhere, use a matrix strategy:
\n\njobs:\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