In order to support running from both the repository root and from
within Xcode project, and to keep things generally organized, our
primary .swiftlint.yml configuration file lives under macos/.
This change introduces a root-level .swiftlint.yml which limits the file
scope to macos/ and then includes macos/.swiftlint.yml for the rest of
the directives.
This unlocks a few benefits:
- We no longer need to pass an explicit `macos` path argument in any of
our invocations. SwiftLint will do the right thing when run either
from the repository root or from within the macos/ directory.
- It lets us easily exclude the macos/build/ directory (and re-enable
the 'deployment_target' rule). In the previous setup, this was more
challenging than you'd expect due to SwiftLint's path resolution rules
and required passing even more arguments like `--working-directory`.
The only downside is adding a new file to the repository root, but that
feels like the right trade-off given the benefits and conveniences.
SwiftLint <https://realm.github.io/SwiftLint/> is both a linter and
formatting. It's a popular way to spot issues and enforce a consistent
style.
Our SwiftLint configuration lives in `macos/.swiftlint.yml`, where is is
automatically discovered. It's very configurable, and I made an initial
pass as some basic, weakly-opinionated rules. The "TODO" section lists
rules that currently have violations but can be easily (auto)fixed in
follow-up commits.
Our integration is CLI-based. Similar to our other support tools, we
expect developers to install `swiftlint` via nix or e.g. Homebrew. This
is documented in HACKING.md.
We also have an optional Xcode integration, for in-editor feedback. When
`swiftlint` is available, it's run as a script-based Build Phase.
SwiftLint supports an auto-fix mode (`--fix`). Agents are aware of this
via AGENTS.md.
The rules are enforced using a (nix-based) CI job.
This saves us some work on the majority of our commits. I think we'd
only miss commits to .github/ and the nix environment with this filter,
but we can expand the filter's scope as needed.
SwiftLint <https://realm.github.io/SwiftLint/> is both a linter and
formatting. It's a popular way to spot issues and enforce a consistent
style.
Our SwiftLint configuration lives in macos/.swiftlint.yml, where is is
automatically discovered. It's very configurable, and I made an initial
pass as some basic, weakly-opinionated rules. The "TODO" section lists
rules that currently have violations but can be easily (auto)fixed in
follow-up commits.
Our integration is CLI-based. Similar to our other support tools, we
expect developers to install `swiftlint` via nix or e.g. Homebrew.
This is documented in HACKING.md.
We also have an optional Xcode integration, for in-editor feedback. When
`swiftlint` is available, it's run as a script-based Build Phase.
SwiftLint supports an auto-fix mode (--fix). Agents are aware of this
via AGENTS.md.
The rules are enforced using a (nix-based) CI job.
As mentioned in
https://github.com/ghostty-org/ghostty/pull/10332#issuecomment-3800353166,
the Harfbuzz shaping tests that depend on specific fonts (that are on
macOS, but not whatever linux distro we use for CI) aren't being checked
in CI. The `build-macos-freetype` CI check is primarily to make sure
Freetype can build on Mac, but if we switch to the `coretext_freetype`
backend, we still use Freetype for rendering, but then we get Coretext
for font discovery which then enables these tests to run.
Bumps
[hustcer/milestone-action](https://github.com/hustcer/milestone-action)
from 3.0 to 3.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/hustcer/milestone-action/releases">hustcer/milestone-action's
releases</a>.</em></p>
<blockquote>
<h2>v3.1</h2>
<h2>[3.1] - 2026-01-23</h2>
<h3>Documentation</h3>
<ul>
<li>Update milestone-action version in README (<a
href="https://redirect.github.com/hustcer/milestone-action/issues/162">#162</a>)</li>
</ul>
<h3>Features</h3>
<ul>
<li>Break before sleep when milestone found</li>
</ul>
<h3>Miscellaneous Tasks</h3>
<ul>
<li>Update README.md (<a
href="https://redirect.github.com/hustcer/milestone-action/issues/166">#166</a>)</li>
</ul>
<h3>Deps</h3>
<ul>
<li>Update Nu to 0.109.1</li>
<li>Update Nushell to 0.110.0 (<a
href="https://redirect.github.com/hustcer/milestone-action/issues/167">#167</a>)</li>
<li>Upgrade hustcer/setup-nu to v3.22</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/hustcer/milestone-action/blob/main/CHANGELOG.md">hustcer/milestone-action's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<p>All notable changes to this project will be documented in this
file.</p>
<h2>[3.1] - 2026-01-23</h2>
<h3>Documentation</h3>
<ul>
<li>Update milestone-action version in README (<a
href="https://redirect.github.com/hustcer/milestone-action/issues/162">#162</a>)</li>
</ul>
<h3>Features</h3>
<ul>
<li>Break before sleep when milestone found</li>
</ul>
<h3>Miscellaneous Tasks</h3>
<ul>
<li>Update README.md (<a
href="https://redirect.github.com/hustcer/milestone-action/issues/166">#166</a>)</li>
</ul>
<h3>Deps</h3>
<ul>
<li>Update Nu to 0.109.1</li>
<li>Update Nushell to 0.110.0 (<a
href="https://redirect.github.com/hustcer/milestone-action/issues/167">#167</a>)</li>
<li>Upgrade hustcer/setup-nu to v3.22</li>
</ul>
<h1>Changelog</h1>
<p>All notable changes to this project will be documented in this
file.</p>
<h2>[3.0] - 2025-10-26</h2>
<p>This release introduces changes that may impact some users. If the
action fails due to insufficient permissions, please add the
<code>issues: write</code> and <code>pull-requests: write</code>
permissions to your workflow. Additionally, the API for binding
milestones has been modified. Due to these changes, the major version
has been incremented to 3.</p>
<h3>Bug Fixes</h3>
<ul>
<li>Try to fix GitHub Projects (classic) deprecation warning by using
REST API instead of GraphQL (<a
href="https://redirect.github.com/hustcer/milestone-action/issues/157">#157</a>)</li>
<li>Fix "Resource not accessible by integration" error for
issue milestone binding by adding <code>issues: write</code>
permission</li>
</ul>
<h3>Documentation</h3>
<ul>
<li>Update README with required permissions configuration</li>
<li>Remove unnecessary <code>contents: write</code> permission
requirement</li>
</ul>
<h2>[2.12] - 2025-10-25</h2>
<h3>Bug Fixes</h3>
<ul>
<li>Fix some typos</li>
</ul>
<h3>Miscellaneous Tasks</h3>
<ul>
<li>Sort milestones by due date, then creation time (<a
href="https://redirect.github.com/hustcer/milestone-action/issues/153">#153</a>)</li>
<li>Update output table width for logs</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="ebed8d5daa"><code>ebed8d5</code></a>
Bump to v3.1</li>
<li><a
href="e2f911c127"><code>e2f911c</code></a>
chore: Update Nushell to 0.110.0 (<a
href="https://redirect.github.com/hustcer/milestone-action/issues/167">#167</a>)</li>
<li><a
href="800adcbc5e"><code>800adcb</code></a>
deps: Upgrade hustcer/setup-nu to v3.22</li>
<li><a
href="91ff3608b5"><code>91ff360</code></a>
deps: Update Nu to 0.109.1</li>
<li><a
href="906178b9f5"><code>906178b</code></a>
chore: Update README.md (<a
href="https://redirect.github.com/hustcer/milestone-action/issues/166">#166</a>)</li>
<li><a
href="90f06528b6"><code>90f0652</code></a>
feat: Break before sleep when milestone found</li>
<li><a
href="93d96c3f77"><code>93d96c3</code></a>
Update CHANGELOG.md</li>
<li><a
href="7ee8118a50"><code>7ee8118</code></a>
docs: Update milestone-action version in README (<a
href="https://redirect.github.com/hustcer/milestone-action/issues/162">#162</a>)</li>
<li><a
href="8d333973bd"><code>8d33397</code></a>
Try to remove permission section</li>
<li>See full diff in <a
href="dcd6c3742a...ebed8d5daa">compare
view</a></li>
</ul>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
This simplifies our CI command line and makes it easier to document
expected usage (in HACKING.md).
There unfortunately isn't a way to set --checked-sourced or our default
warning level in .shellcheckrc, and our `find` command is still a bit
unwieldy, but this is still a net improvement.
Does not entail any actual changes in the version, merely in the comment
indicating the used version.
Detected by CI (GitHub Action Pins) after nixpkgs update.