Use a Swift command-line tool in a GitHub workflow

I am a Software Engineer working on open source and enterprise mobile SDKs for iOS and MacOS developers written in Swift. From 🇩🇪 and happily living in 🇺🇸
Search for a command to run...

I am a Software Engineer working on open source and enterprise mobile SDKs for iOS and MacOS developers written in Swift. From 🇩🇪 and happily living in 🇺🇸
No comments yet. Be the first to comment.
WWDC26 kicked off on June 8, 2026. The information in this article reflects the information published by Apple on that date. There are 14 new frameworks. Name Description AccessoryAccess Manage

WWDC25 kicked off on June 9, 2025. The information in this article reflects the information published by Apple on that date. New Frameworks NameDescription AlarmKitSchedule prominent alarms and countdowns to help people manage their time. AVR...

WWDC25 is almost here, and I couldn’t be more excited! Whether you're attending the official events, community meetups, or just soaking in the energy around Cupertino, there’s no better time to connect, share ideas, and celebrate everything we love a...

In this blog post, I’ll share an observation and advice regarding the caching behavior of network responses by Apple’s APIs. If you are unfamiliar with caching of network responses then I recommend Apple’s article Accessing cached data that introduce...
WWDC24 kicked off on June 10, 2024. The information in this article reflects the information published by Apple on that date. New Frameworks NameDescription AccessorySetupKitUse AccessorySetupKit to discover accessories with Bluetooth or Wi-Fi...

This blog post is for you if
My example: I'll want to use Swiftformat, a command-line tool to reformat Swift code in my current GitHub repository.
name: Execute a Swift package command-line tool
on:
push:
branches: [ main ]
jobs:
swiftformat:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
- run: |
brew install mint
mint run nicklockwood/SwiftFormat@0.49.1 --verbose .
This workflow will
The simplicity of this workflow has several drawbacks:
I will explain how to improve the workflow above step-by-step. You can copy the complete and improved workflow at the end of this blog post.
First, create a Mintfile in the root of your repository.
nicklockwood/SwiftFormat@0.49.1
A Mintfile can specify a list of versioned packages. It makes installing and running these packages easy, as the specific repos and versions are centralized.
Then modify your workflow to leverage GitHub action cache to cache Swift Packages installed and built by Mint.
- name: Cache/Restore Mint packages
id: mint-cache
uses: actions/cache@v2
with:
path: ${{ github.workspace }}/mint
key: ${{ runner.os }}-mint-${{ hashFiles('**/Mintfile') }}
restore-keys: ${{ runner.os }}-mint-
Let's separate the installation of Mint for better readability. If Mint is already installed let's upgrade.
- name: Install package manager "Mint" to install and run Swift command line tool packages
run: |
brew upgrade mint || brew install mint || true
Now comes the important part: only install and build the Swift Package if there is no cached version.
- name: Install command line tool (if not yet cached)
if: steps.mint-cache.outputs.cache-hit != 'true'
run: mint bootstrap
With mint bootstrap the package manager will find the version declared in the Mintfile and install that version.
As the final step, let's run the command-line tool.
- name: Run command line tool
run: mint run swiftformat --verbose .
Mint will search for the newest tag in the installed packages and run that version when ditching the version.
The whole improved workflow:
name: Execute Swift package command-line tool
on:
push:
branches: [ main ]
jobs:
swiftformat:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
- name: Cache/Restore Mint packages
id: mint-cache
uses: actions/cache@v2
with:
path: ${{ github.workspace }}/mint
key: ${{ runner.os }}-mint-${{ hashFiles('**/Mintfile') }}
restore-keys: ${{ runner.os }}-mint-
- name: Install package manager "Mint" to install and run Swift command line tool packages
run: |
brew upgrade mint || brew install mint || true
- name: Install command line tool (if not yet cached)
if: steps.mint-cache.outputs.cache-hit != 'true'
run: mint bootstrap
- name: Run command line tool
run: mint run swiftformat --verbose .
Step "Install command line tool (if not yet cached)" will only be executed for the very first workflow run. Subsequent workflow runs will skip that step as the previous step "Cache/Restore Mint packages" will restore the cache from the first workflow run.