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' | xcprettyThis 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: --strictNow, 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