CI/CD for Swift Projects: GitHub Actions from A to Z

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: Why CI/CD is Critical for Swift Development

In modern iOS/macOS development, manual building and testing is a path to errors and wasted time. Every commit can break the build, and testing on real devices requires physical access. CI/CD (Continuous Integration / Continuous Deployment) solves these problems by automating the build, testing, and deployment of applications.

GitHub Actions is a built-in CI/CD tool, ideally suited for Swift projects hosted on GitHub. It allows you to free (up to 2000 minutes per month for public repositories) run workflows in the cloud. In this article, we will cover the full cycle: from basic configuration to deployment to the App Store.

Who is this article for? For iOS/macOS developers who want to automate routine tasks and speed up the release cycle. Even if you are a beginner in DevOps, step-by-step instructions and code examples will help you understand.



1. GitHub Actions Basics for Swift

1.1. Workflow Structure

GitHub Actions uses YAML files stored in .github/workflows/. Each file is a separate workflow (process) triggered by an event (push, pull request, schedule).

A basic workflow for a Swift project looks like this:

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: Build run: xcodebuild build -project MyApp.xcodeproj -scheme MyApp -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 15,OS=17.2' - name: Test run: xcodebuild test -project MyApp.xcodeproj -scheme MyApp -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 15,OS=17.2'

Key points:

  • macos-latest — runner with macOS, required for Xcode and Swift.
  • actions/checkout@v4 — clones the repository.
  • xcodebuild — command for building and testing.
  • The destination parameter specifies the simulator (replace with your iOS version).


1.2. Dependency Caching

Swift Package Manager (SPM) is the standard dependency manager. To avoid downloading packages on every commit, use caching:

steps:  - uses: actions/cache@v3    with:      path: ~/Library/Developer/Xcode/DerivedData      key: ${{ runner.os }}-spm-${{ hashFiles('**/Package.resolved') }}      restore-keys: |        ${{ runner.os }}-spm-  - run: swift build

This reduces build time by 40–60%.



2. Setting up Testing and Linting

2.1. Unit Tests and UI Tests

For iOS/macOS projects, it is critical to run tests in a simulator. Make sure tests are enabled in the Xcode scheme. Example for macOS:

jobs:  test_macos:    runs-on: macos-latest    steps:      - uses: actions/checkout@v4      - name: Run macOS tests        run: xcodebuild test -project MyApp.xcodeproj -scheme MyApp -sdk macosx -destination 'platform=macOS,arch=x86_64'

For iOS, add -destination 'platform=iOS Simulator,name=iPhone 15'. Important: simulator names change with Xcode versions — use xcrun simctl list to check available ones.



2.2. Static Analysis (SwiftLint)

Maintain code quality with SwiftLint. Add a step to the workflow:

- name: SwiftLint  run: |    brew install swiftlint    swiftlint --strict

The --strict flag turns warnings into errors — the workflow will fail if the code does not comply with the rules. Configure .swiftlint.yml in the project root.



3. Building and Signing for Deployment

3.1. Managing Certificates and Profiles

<

Blogs

Book Recommendations