Skip to content

Commit ee6c1ad

Browse files
Pin SwiftLint & SwiftFormat via Mintfile
Mirrors the setup in checkout-sheet-kit-swift: the `Mintfile` pins exact SwiftLint / SwiftFormat versions so local dev and CI always run the same linter binaries (no more "works on my machine" drift between whatever brew happens to install and whatever CI has cached). - Add `Mintfile` pinning `realm/SwiftLint@0.63.2` and `nicklockwood/SwiftFormat@0.61.0` (same pins as checkout-sheet-kit-swift for consistency across the two kits). - dev.yml: replace the bare `swiftlint` package with `mint` and `xcbeautify`, and add a `mint bootstrap` step so running `dev up` installs (or updates) the pinned toolchain into `.mint/`. This also fixes the "WARN: SwiftFormat not installed" warning developers were hitting — swiftformat wasn't being provisioned at all. - scripts/lint_swift: invoke `mint run swiftlint` / `mint run swiftformat` instead of relying on whatever binary is on PATH. Adds the `--verbose` flag that the update-linters workflow uses and keeps the same check/fix modes the existing script had. - .gitignore: ignore `.mint/` (Mint's local-install cache). - CONTRIBUTING.md: document the Mint-based flow and point at the update-linters workflow. Workflow changes (`.github/workflows/ci.yml` lint job + `.github/workflows/update-linters.yml`) are included as a patch in the PR description because the GitHub App pushing this branch doesn't have the `workflows` permission on this repo. Requested by Kieran Osgood <kieran.osgood@shopify.com>
1 parent 46c8b4f commit ee6c1ad

8 files changed

Lines changed: 272 additions & 49 deletions

File tree

.github/workflows/ci.yml

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ jobs:
4343
steps:
4444
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
4545

46-
- name: Run SwiftLint
46+
- name: Run SwiftLint (annotations)
4747
uses: norio-nomura/action-swiftlint@9f4dcd7fd46b4e75d7935cf2f4df406d5cae3684 # 3.2.1
4848
with:
4949
args: --strict
@@ -56,6 +56,37 @@ jobs:
5656
pnpm module lint
5757
pnpm sample lint
5858
59+
swift-lint:
60+
name: SwiftFormat & SwiftLint
61+
runs-on: ${{ vars.MACOS_RUNNER }}
62+
timeout-minutes: 15
63+
env:
64+
MINT_PATH: ${{ github.workspace }}/.mint/lib
65+
MINT_LINK_PATH: ${{ github.workspace }}/.mint/bin
66+
steps:
67+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
68+
69+
- name: Cache Mint packages
70+
id: mint-cache
71+
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
72+
with:
73+
path: .mint
74+
key: ${{ runner.os }}-mint-${{ hashFiles('Mintfile') }}
75+
restore-keys: |
76+
${{ runner.os }}-mint-
77+
78+
- name: Install Mint
79+
run: brew install mint
80+
81+
- name: Bootstrap Mint packages
82+
if: steps.mint-cache.outputs.cache-hit != 'true'
83+
run: mint bootstrap --link
84+
85+
- name: Add Mint to PATH
86+
run: echo "${{ github.workspace }}/.mint/bin" >> "$GITHUB_PATH"
87+
88+
- run: ./scripts/lint_swift check --verbose
89+
5990
test:
6091
name: Run jest tests
6192
runs-on: ubuntu-latest
@@ -116,7 +147,7 @@ jobs:
116147
117148
test-ios:
118149
name: Run Swift Tests
119-
runs-on: macos-26-xlarge
150+
runs-on: ${{ vars.MACOS_RUNNER }}
120151
timeout-minutes: 20
121152
needs: [lint, test]
122153
steps:
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
name: Update Linter Versions
2+
3+
on:
4+
schedule:
5+
- cron: '0 10 * * 1' # Monday 10:00 UTC
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: write
10+
pull-requests: write
11+
12+
jobs:
13+
check-updates:
14+
runs-on: ${{ vars.MACOS_RUNNER }}
15+
env:
16+
MINT_PATH: ${{ github.workspace }}/.mint/lib
17+
MINT_LINK_PATH: ${{ github.workspace }}/.mint/bin
18+
steps:
19+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
20+
21+
- name: Read current versions from Mintfile
22+
id: current
23+
run: |
24+
SWIFTLINT=$(grep 'realm/SwiftLint@' Mintfile | sed 's/.*@//')
25+
SWIFTFORMAT=$(grep 'nicklockwood/SwiftFormat@' Mintfile | sed 's/.*@//')
26+
echo "swiftlint=$SWIFTLINT" >> "$GITHUB_OUTPUT"
27+
echo "swiftformat=$SWIFTFORMAT" >> "$GITHUB_OUTPUT"
28+
29+
- name: Check latest versions
30+
id: latest
31+
env:
32+
GH_TOKEN: ${{ github.token }}
33+
run: |
34+
SWIFTLINT=$(gh api repos/realm/SwiftLint/releases/latest --jq '.tag_name')
35+
SWIFTFORMAT=$(gh api repos/nicklockwood/SwiftFormat/releases/latest --jq '.tag_name')
36+
echo "swiftlint=$SWIFTLINT" >> "$GITHUB_OUTPUT"
37+
echo "swiftformat=$SWIFTFORMAT" >> "$GITHUB_OUTPUT"
38+
39+
- name: Determine updates needed
40+
id: check
41+
run: |
42+
HAS_UPDATES=false
43+
if [ "${{ steps.current.outputs.swiftlint }}" != "${{ steps.latest.outputs.swiftlint }}" ]; then
44+
echo "swiftlint_updated=true" >> "$GITHUB_OUTPUT"
45+
HAS_UPDATES=true
46+
fi
47+
if [ "${{ steps.current.outputs.swiftformat }}" != "${{ steps.latest.outputs.swiftformat }}" ]; then
48+
echo "swiftformat_updated=true" >> "$GITHUB_OUTPUT"
49+
HAS_UPDATES=true
50+
fi
51+
echo "has_updates=$HAS_UPDATES" >> "$GITHUB_OUTPUT"
52+
53+
- name: Check for existing PR
54+
if: steps.check.outputs.has_updates == 'true'
55+
id: existing_pr
56+
env:
57+
GH_TOKEN: ${{ github.token }}
58+
run: |
59+
EXISTING=$(gh pr list --head "auto/update-linters" --state open --json number --jq '.[0].number // empty')
60+
echo "exists=$( [ -n "$EXISTING" ] && echo true || echo false )" >> "$GITHUB_OUTPUT"
61+
62+
- name: Create branch and update Mintfile
63+
if: steps.check.outputs.has_updates == 'true' && steps.existing_pr.outputs.exists != 'true'
64+
run: |
65+
git checkout -b auto/update-linters
66+
printf '%s\n' \
67+
"realm/SwiftLint@${{ steps.latest.outputs.swiftlint }}" \
68+
"nicklockwood/SwiftFormat@${{ steps.latest.outputs.swiftformat }}" \
69+
> Mintfile
70+
71+
- name: Install Mint and bootstrap new versions
72+
if: steps.check.outputs.has_updates == 'true' && steps.existing_pr.outputs.exists != 'true'
73+
run: |
74+
brew install mint
75+
echo "${{ github.workspace }}/.mint/bin" >> "$GITHUB_PATH"
76+
mint bootstrap --link
77+
78+
- name: Run lint fix
79+
if: steps.check.outputs.has_updates == 'true' && steps.existing_pr.outputs.exists != 'true'
80+
run: ./scripts/lint_swift fix --verbose
81+
82+
- name: Commit and push
83+
if: steps.check.outputs.has_updates == 'true' && steps.existing_pr.outputs.exists != 'true'
84+
run: |
85+
git config user.name "github-actions[bot]"
86+
git config user.email "github-actions[bot]@users.noreply.github.com"
87+
git add -A
88+
git commit -m "chore: update linter versions" \
89+
-m "SwiftLint: ${{ steps.current.outputs.swiftlint }} -> ${{ steps.latest.outputs.swiftlint }}" \
90+
-m "SwiftFormat: ${{ steps.current.outputs.swiftformat }} -> ${{ steps.latest.outputs.swiftformat }}"
91+
git push origin auto/update-linters
92+
93+
- name: Create Pull Request
94+
if: steps.check.outputs.has_updates == 'true' && steps.existing_pr.outputs.exists != 'true'
95+
env:
96+
GH_TOKEN: ${{ github.token }}
97+
run: |
98+
BODY="## Linter Version Updates\n\n"
99+
if [ "${{ steps.check.outputs.swiftlint_updated }}" == "true" ]; then
100+
BODY+="- **SwiftLint**: \`${{ steps.current.outputs.swiftlint }}\` → \`${{ steps.latest.outputs.swiftlint }}\`\n"
101+
BODY+=" [Release notes](https://github.com/realm/SwiftLint/releases/tag/${{ steps.latest.outputs.swiftlint }})\n"
102+
fi
103+
if [ "${{ steps.check.outputs.swiftformat_updated }}" == "true" ]; then
104+
BODY+="- **SwiftFormat**: \`${{ steps.current.outputs.swiftformat }}\` → \`${{ steps.latest.outputs.swiftformat }}\`\n"
105+
BODY+=" [Release notes](https://github.com/nicklockwood/SwiftFormat/releases/tag/${{ steps.latest.outputs.swiftformat }})\n"
106+
fi
107+
BODY+="\n---\n\n"
108+
BODY+="\`./scripts/lint_swift fix\` has been run to apply formatting changes.\n\n"
109+
BODY+="### ⚠️ CI checks need to be triggered manually\n\n"
110+
BODY+="This PR was created by GitHub Actions using \`GITHUB_TOKEN\`, which "
111+
BODY+="[does not trigger other workflows](https://docs.github.com/en/actions/security-for-github-actions/security-guides/automatic-token-authentication#using-the-github_token-in-a-workflow). "
112+
BODY+="To run CI checks, either:\n\n"
113+
BODY+="1. **Close and reopen this PR** — this fires a new \`pull_request\` event from your user, which triggers all checks.\n"
114+
BODY+="2. **Trigger workflows via CLI:**\n"
115+
BODY+="\`\`\`bash\n"
116+
BODY+="gh workflow run ci.yml --ref auto/update-linters\n"
117+
BODY+="\`\`\`\n"
118+
119+
gh pr create \
120+
--title "chore: bump linter versions" \
121+
--body "$(echo -e "$BODY")" \
122+
--label "dependencies" \
123+
--head "auto/update-linters" \
124+
--base "main"

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ modules/@shopify/checkout-sheet-kit/android/gradlew.bat
9797
# Local gems
9898
sample/vendor
9999

100+
# Mint (pinned Swift CLI tools — SwiftLint / SwiftFormat)
101+
.mint/
102+
100103
# Sample app
101104
sample/**/AndroidManifest.xml
102105

CONTRIBUTING.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ pnpm sample clean
9999
pnpm module clean
100100
```
101101

102-
## Linting the code
102+
## Linting the code
103103

104104
Linting the codespaces will (1) compile the code with TypeScript and (2) run
105105
eslint over the source code.
@@ -112,6 +112,29 @@ pnpm module lint
112112
pnpm sample lint
113113
```
114114

115+
Swift files in the Native Module are linted with SwiftLint and SwiftFormat,
116+
pinned via the [Mintfile](./Mintfile). Run `dev up` (or `brew install mint &&
117+
mint bootstrap`) to install the pinned versions.
118+
119+
```sh
120+
# Check Swift lint + format
121+
./scripts/lint_swift check
122+
123+
# Or via dev
124+
dev check
125+
126+
# Auto-fix issues
127+
./scripts/lint_swift fix
128+
129+
# Or via dev
130+
dev fix
131+
```
132+
133+
Linter versions are bumped automatically by the
134+
[`update-linters`](./.github/workflows/update-linters.yml) workflow every
135+
Monday, which opens a PR if SwiftLint or SwiftFormat have newer releases on
136+
GitHub.
137+
115138
## Testing
116139

117140
There are 3 types of tests in this repo: Typescript, Swift and Java - each for

Mintfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
realm/SwiftLint@0.63.2
2+
nicklockwood/SwiftFormat@0.61.0

dev.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,13 @@ type: node
66

77
up:
88
- packages:
9-
- swiftlint
9+
- mint
1010
- sccache
11+
- xcbeautify
12+
- custom:
13+
name: Bootstrap Mint packages
14+
met?: mint which swiftlint >/dev/null 2>&1 && mint which swiftformat >/dev/null 2>&1
15+
meet: mint bootstrap
1116
- ruby
1217
- xcode:
1318
version: '26.2'

modules/@shopify/checkout-sheet-kit/ios/AcceleratedCheckoutButtons.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,8 @@ class RCTAcceleratedCheckoutButtonsView: UIView {
162162
hostingController?.view.frame = bounds
163163
}
164164

165-
// Deprecated in iOS 17 — superseded by registerForTraitChanges in setupView().
166-
// Remove this override when dropping iOS 16 support.
165+
/// Deprecated in iOS 17 — superseded by registerForTraitChanges in setupView().
166+
/// Remove this override when dropping iOS 16 support.
167167
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
168168
super.traitCollectionDidChange(previousTraitCollection)
169169
if #unavailable(iOS 17.0) {

0 commit comments

Comments
 (0)