swift-format GitHub Action

swift-format is only one of several options for Swift language formatting tools, but as it is part of the official Swift GitHub organization and is built by Apple, it stands a good chance of coming out as the primary one. As of Xcode 16, swift-format is bundled with Apple’s IDE for Swift development both as a CLI tool and a toolbar action.

Linting

That means that rather than needing a special GitHub Marketplace Action or Docker container to run swift-format, we can now run it almost directly—only needing to pass the command to xcrun to get things running. Here’s the full Workflow job which can be added on its own as a YAML file inside of a projects .github/workflows/ directory or combined with other Workflow definitions if you’ve already got some.

name: swift-format
on: [push, workflow_dispatch]
jobs:
  lint:
  runs-on: macos-15
  steps:
    - uses: actions/checkout@v4
    - name: Lint
      run: |
        xcrun swift-format lint . \
          --parallel \
          --recursive \
          --strict

That will check out your code in a macOS 15 container (required, I believe, to have access to Xcode 16 which is the first version where this will work) and run swift-format’s lint subcommand in parallel across all files, failing the step if there are any warnings.

Formatting

Xcode 16 stops short of supporting format on save with swift-format, but does provide a toolbar menu item and keyboard shortcut to format the current file manually. The toolbar item can un-intuitively be found in Editor→Structure→Format file with 'swift-format' and the keyboard shortcut is Ctrl+ Shift+I. I haven’t found any built-in tooling to format the entire project at once, but that can be done with the CLI tool:

xcrun swift-format . --parallel --recursive --in-place

Some developers also like to plug that into a pre-commit hook and limit it to changed files, and while it’s very fast so as not to slow down your commit workflow that is not a step I’ve taken yet.

One quick note–swift-format format (the default subcommand) will format the majority of things, but some warnings will still crop up in swift-format lint that it doesn’t resolve, so you may want to combine the two commands in your workflow however you use it.

Configuration

If your project has a .swift-format configuration file at its root, those settings will be respected. Otherwise, the output of xcrun swift-format dump-configuration shows the default settings and you can use it as a starting point for your customizations.

My own preferred configuration is available in my dotfiles and while swift-format doesn’t yet respect XDG_CONFIG_HOME or indeed any global configuration, there is an open Pull Request to add that capability, so for now I copy that file between projects and do my best to keep it in sync. That might remain a good idea even if the tool does end up supporting that so that the configuration is consistent between developers and the GitHub Action above.