Multi-platform Swift Package releases with GitHub Actions
Helm Pro yearly subscribers now get a 30% discount on RocketSim thanks to contingent pricing on the App Store.
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: