Add shellcheck, SwiftFormat and SwiftLint - #410
Conversation
Closes #380, #382; the CI half of #381. Formatting had drifted: 22 of 41 files failed swiftformat --lint before any of today's work, so the .swiftformat config existed without anything enforcing it. Applying it touches 21 files. HTMLTemplates.swift is excluded from both tools. It carries a DO NOT EDIT header and is almost entirely multiline string literals whose contents are the emitted HTML; the file is 2-space Allman while the config wants 4-space K&R, so reformatting would move the closing string delimiters. In Swift the closing delimiter's indentation determines how much leading whitespace is stripped from every line, which would change the bytes of every generated report. Verified the reformat is behaviour-preserving by generating a report before and after. That comparison also turned up something unrelated: the same binary produces different output on consecutive runs, because five call sites mint a fresh UUID() per run for DOM handles. Filed separately. shellcheck already passes on prepareTestResults.sh, so that job is a guard against regression rather than a cleanup. SwiftLint starts non-strict with a config that is green today: layout rules that SwiftFormat already owns are disabled so the two tools cannot disagree, and thresholds are set so the gate can be tightened deliberately rather than switched on already failing and then ignored. Two genuine violations are fixed rather than suppressed — a manual add-and-assign that should be +=, and a test helper whose leading underscore tripped the naming rule. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 2 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe PR adds ShellCheck, SwiftFormat, and SwiftLint CI coverage. It configures formatting and lint rules, updates Swift source formatting and documentation comments, strengthens result-count tests, and replaces ChangesCode quality and validation
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related issues
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/lint.yml:
- Around line 1-7: Update the workflow-level configuration in lint.yml by adding
a permissions block with contents set to read, ensuring all lint jobs use
least-privilege repository access.
- Line 13: Update both actions/checkout@v4 steps in the workflow to set
persist-credentials to false, ensuring credential persistence is disabled for
each checkout.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 60b107c3-6131-40d2-b9ac-29dd5c90c8d3
📒 Files selected for processing (26)
.github/workflows/lint.yml.gitignore.swiftformat.swiftlint.ymlSources/XCTestHTMLReport/XCTestHtmlReport.swiftSources/XCTestHTMLReportCore/Classes/Helpers/ImageHelpers.swiftSources/XCTestHTMLReportCore/Classes/Helpers/UnattachedFiles.swiftSources/XCTestHTMLReportCore/Classes/Models/Attachment.swiftSources/XCTestHTMLReportCore/Classes/Models/Iteration.swiftSources/XCTestHTMLReportCore/Classes/Models/JUnitReport.swiftSources/XCTestHTMLReportCore/Classes/Models/Run.swiftSources/XCTestHTMLReportCore/Classes/Models/Summary.swiftSources/XCTestHTMLReportCore/Classes/Models/TargetDevice.swiftSources/XCTestHTMLReportCore/Classes/Models/Test.swiftSources/XCTestHTMLReportCore/Classes/Models/TestScreenshotFlow.swiftSources/XCTestHTMLReportCore/Classes/Models/TestSummary.swiftSources/XCTestHTMLReportCore/Classes/Protocols/EmittableOutput.swiftSources/XCTestHTMLReportCore/Classes/Protocols/TestConforming.swiftTests/XCTestHTMLReportTests/CliTests.swiftTests/XCTestHTMLReportTests/CoreTests.swiftTests/XCTestHTMLReportTests/FaultReportingTests.swiftTests/XCTestHTMLReportTests/JUnitReportTests.swiftTests/XCTestHTMLReportTests/TestSupport.swiftXCTestHTMLReportSampleApp/SampleApp/AppDelegate.swiftXCTestHTMLReportSampleApp/SampleAppUITests/RetryTests.swiftXCTestHTMLReportSampleApp/SampleAppUnitTests/SampleAppUnitTests.swift
Both findings from CodeRabbit on #410, both valid. The repository default workflow permission is write, so these jobs were inheriting a write-scoped GITHUB_TOKEN they never use. Pinned to contents: read. actions/checkout also leaves the token in .git/config by default. Neither job pushes anything, and the swift job runs third-party code via brew install, so the token was sitting on disk while unrelated code executed. persist-credentials: false on both. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Both addressed in aad6ae7.
Both are scoped to That workflow-wide pass belongs with the SHA-pinning work (#384), which already has to rewrite every |
Closes #380 and #382; the CI half of #381. Second of the maintenance-automation batch.
Formatting had already drifted
22 of 41 files failed
swiftformat --lintbefore any of today's work. The.swiftformatconfig existed with nothing enforcing it. I checked whether I had caused it — the answer is one file (FaultReportingTests.swift, mine) out of 22; the other 21 predate this session.Applying the config touches 21 files: 155 insertions, 91 deletions. Mechanical and reproducible with
swiftformat ..HTMLTemplates.swiftis excluded, deliberatelyIt wanted 1,200 indent changes alone. The file is 2-space Allman while the config wants 4-space K&R, so reformatting moves the closing
"""delimiters of its multiline strings — and in Swift the closing delimiter's indentation determines how much leading whitespace is stripped from every line. That would change the bytes of every generated report.It also carries a
DO NOT EDIT! This file is autogeneratedheader, so hand-formatting it is wrong regardless. Excluded from both tools.Verified the reformat is behaviour-preserving
Generated a report before and after and compared. That comparison found something unrelated and worth knowing: the same binary produces different output on consecutive runs.
Five call sites mint a fresh
UUID()per run for DOM handles (TestSummary,TargetDevice,Test×2,Iteration). Harmless for rendering, but reports are not reproducible — which matters for diffing across runs or content-addressed caching. Filed separately; not changed here.Without that check I would have blamed the formatting for the differing output.
SwiftLint
Scoped correctly it reports 65 warnings / 24 errors; 31 of those are in the excluded
HTMLTemplates.swift. (Unscoped it reports 7,285 warnings because it lints.build/checkouts— i.e. your dependencies.)The config starts green, non-strict:
line_lengtherrors above what a formatter can fix — SwiftFormat wraps at 100 but cannot wrap string literals.todois off; TODOs are tracked as issues here, not lint failures.A gate that is switched on already failing gets ignored. This one can be tightened deliberately.
Two genuine violations are fixed rather than suppressed: a manual add-and-assign that should be
+=(UnattachedFiles.swift), and a test helper whose leading underscore tripped the naming rule (renamed_testAttachmentsExist→assertAttachmentsExist, which says "not a test" more clearly anyway).shellcheck
prepareTestResults.shalready passes. So this job guards against regression rather than fixing anything.I should correct something I said when proposing this batch: I claimed shellcheck would have caught two bugs I shipped today. It would not have. The lexicographic sort was Python inside a heredoc, and the
set -e+readinteraction isn't a standard shellcheck rule.Also
swift testwritesindex.html/report.junitinto the fixture directory. Those were untracked and produced aswift buildwarning on every subsequent build (#389). Now gitignored.Verification
swiftformat --lint .→ cleanswiftlint→ 0 errors, 26 warningsswift test→ 22 tests, 1 skipped, 0 failures🤖 Generated with Claude Code
Summary by CodeRabbit
Chores
Tests
Refactor