Multi-platform Swift Package releases with GitHub Actions
Sponsored
Add paywalls to your iOS app's in one line of code! With RevenueCat Paywalls you can remotely configure and edit your entire paywall view without waiting on App Review.
I have recently been working on a new Swift Package library that supports iOS, macOS and Linux. As I wanted the development lifecycle to be fast and iterative, I decided to make the library’s release process as automated and as error-proof as possible.
I came up with a GitHub Actions workflow that runs every time a new tag is pushed to the repository and performs the following steps:
- Build the library and run the test suite for all supported platforms.
- Check all source files to prevent non-inclusive language from making it to the release cut.
- If the two previous checks were successful, create a new GitHub release with auto-generated release notes.
The release workflow
The workflow I ended up with extends and modifies the CI workflow from Matt Massicotte’s Swift Package template repository, which I always use when starting a new project.
The template already has two steps to build and test the library on Apple platforms (iOS and macOS) and Linux.
I changed the on
trigger to only be executed when a new tag matching the ‘..*’ pattern is pushed and then added a new job that checks for inclusive language using the woke GitHub action in the source files and creates a new GitHub release with auto-generated release notes if the two previous checks pass:
name: Release
on:
push:
tags:
- "*.*.*"
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: true
env:
DEVELOPER_DIR: /Applications/Xcode_15.2.app/Contents/Developer
jobs:
test_apple_platforms:
name: Test on iOS and macOS
runs-on: macOS-13
strategy:
matrix:
destination:
- "platform=macOS"
- "platform=iOS Simulator,name=iPhone 12"
steps:
- uses: actions/checkout@v4
- name: Test platform ${{ matrix.destination }}
run: set -o pipefail && xcodebuild -scheme XcodeCloudKit -destination "${{ matrix.destination }}" test | xcbeautify
test_linux:
name: Test Linux
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install swiftly
run: curl -L https://swift-server.github.io/swiftly/swiftly-install.sh | bash -s -- -y
- name: Install the latest Swift toolchain
run: swiftly install latest
- name: Test
run: swift test
release:
needs: [test_apple_platforms, test_linux]
name: Create a new GitHub release
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: woke
uses: get-woke/woke-action@v0
with:
fail-on-error: true
- name: Release
uses: softprops/action-gh-release@v2
with:
generate_release_notes: true
token: ${{ secrets.GITHUB_TOKEN }}
After pushing a new tag to the repository, the workflow runs all jobs and creates a new GitHub release: