@@ -20,5 +20,144 @@ jobs:
2020 - name : Install SwiftLint
2121 run : brew install swiftlint
2222
23- - name : Run SwiftLint
24- run : swiftlint --strict --reporter github-actions-logging
23+ - name : Run SwiftLint and capture results
24+ id : swiftlint
25+ continue-on-error : true
26+ run : |
27+ # Run SwiftLint and save output
28+ swiftlint lint --strict --reporter markdown > swiftlint-report.md 2>&1 || echo "LINT_FAILED=true" >> $GITHUB_ENV
29+
30+ # Also run with JSON reporter for stats
31+ swiftlint lint --reporter json > swiftlint-results.json 2>&1 || true
32+
33+ # Count violations
34+ ERROR_COUNT=$(cat swiftlint-results.json | grep -o '"severity" : "error"' | wc -l | xargs)
35+ WARNING_COUNT=$(cat swiftlint-results.json | grep -o '"severity" : "warning"' | wc -l | xargs)
36+
37+ echo "ERROR_COUNT=$ERROR_COUNT" >> $GITHUB_ENV
38+ echo "WARNING_COUNT=$WARNING_COUNT" >> $GITHUB_ENV
39+
40+ # Show report in console
41+ echo "## SwiftLint Results"
42+ echo "Errors: $ERROR_COUNT"
43+ echo "Warnings: $WARNING_COUNT"
44+
45+ cat swiftlint-report.md
46+
47+ - name : Generate Accessibility Report
48+ if : always()
49+ run : |
50+ echo "# 🔍 Accessibility Check Report" >> $GITHUB_STEP_SUMMARY
51+ echo "" >> $GITHUB_STEP_SUMMARY
52+
53+ if [ "${{ env.LINT_FAILED }}" == "true" ]; then
54+ echo "## ❌ SwiftLint Check Failed" >> $GITHUB_STEP_SUMMARY
55+ else
56+ echo "## ✅ SwiftLint Check Passed" >> $GITHUB_STEP_SUMMARY
57+ fi
58+
59+ echo "" >> $GITHUB_STEP_SUMMARY
60+ echo "### 📊 Violation Summary" >> $GITHUB_STEP_SUMMARY
61+ echo "- **Errors:** ${{ env.ERROR_COUNT }}" >> $GITHUB_STEP_SUMMARY
62+ echo "- **Warnings:** ${{ env.WARNING_COUNT }}" >> $GITHUB_STEP_SUMMARY
63+ echo "" >> $GITHUB_STEP_SUMMARY
64+
65+ echo "### 🎯 Accessibility Rules Checked" >> $GITHUB_STEP_SUMMARY
66+ echo "- ✅ \`accessibility_label_for_image\` - Images must have labels" >> $GITHUB_STEP_SUMMARY
67+ echo "- ✅ \`accessibility_trait_for_button\` - Buttons must have proper traits" >> $GITHUB_STEP_SUMMARY
68+ echo "" >> $GITHUB_STEP_SUMMARY
69+
70+ if [ -f swiftlint-report.md ]; then
71+ echo "### 📝 Detailed Results" >> $GITHUB_STEP_SUMMARY
72+ echo "" >> $GITHUB_STEP_SUMMARY
73+ cat swiftlint-report.md >> $GITHUB_STEP_SUMMARY
74+ fi
75+
76+ echo "" >> $GITHUB_STEP_SUMMARY
77+ echo "### 📚 Resources" >> $GITHUB_STEP_SUMMARY
78+ echo "- [Apple Accessibility Guidelines](https://developer.apple.com/accessibility/)" >> $GITHUB_STEP_SUMMARY
79+ echo "- [SwiftUI Accessibility](https://developer.apple.com/documentation/swiftui/view-accessibility)" >> $GITHUB_STEP_SUMMARY
80+ echo "- [WCAG 2.1 Guidelines](https://www.w3.org/WAI/WCAG21/quickref/)" >> $GITHUB_STEP_SUMMARY
81+ echo "" >> $GITHUB_STEP_SUMMARY
82+
83+ if [ "${{ env.ERROR_COUNT }}" != "0" ]; then
84+ echo "### 🔧 Common Fixes" >> $GITHUB_STEP_SUMMARY
85+ echo "\`\`\`swift" >> $GITHUB_STEP_SUMMARY
86+ echo "// ❌ Bad: Image without label" >> $GITHUB_STEP_SUMMARY
87+ echo "Image(systemName: \"star\")" >> $GITHUB_STEP_SUMMARY
88+ echo "" >> $GITHUB_STEP_SUMMARY
89+ echo "// ✅ Good: Image with descriptive label" >> $GITHUB_STEP_SUMMARY
90+ echo "Image(systemName: \"star\")" >> $GITHUB_STEP_SUMMARY
91+ echo " .accessibilityLabel(\"Favorite\")" >> $GITHUB_STEP_SUMMARY
92+ echo "" >> $GITHUB_STEP_SUMMARY
93+ echo "// ✅ Good: Decorative image hidden" >> $GITHUB_STEP_SUMMARY
94+ echo "Image(systemName: \"sparkles\")" >> $GITHUB_STEP_SUMMARY
95+ echo " .accessibilityHidden(true)" >> $GITHUB_STEP_SUMMARY
96+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
97+ fi
98+
99+ - name : Upload SwiftLint Report
100+ if : always()
101+ uses : actions/upload-artifact@v4
102+ with :
103+ name : swiftlint-report
104+ path : |
105+ swiftlint-report.md
106+ swiftlint-results.json
107+ retention-days : 30
108+
109+ - name : Comment on PR
110+ if : github.event_name == 'pull_request' && env.LINT_FAILED == 'true'
111+ uses : actions/github-script@v7
112+ with :
113+ script : |
114+ const fs = require('fs');
115+ const errorCount = process.env.ERROR_COUNT || '0';
116+ const warningCount = process.env.WARNING_COUNT || '0';
117+
118+ let report = '## 🔍 Accessibility Check Results\n\n';
119+
120+ if (errorCount !== '0' || warningCount !== '0') {
121+ report += '### ❌ Issues Found\n\n';
122+ report += `- **Errors:** ${errorCount}\n`;
123+ report += `- **Warnings:** ${warningCount}\n\n`;
124+
125+ // Read the markdown report if it exists
126+ try {
127+ const markdownReport = fs.readFileSync('swiftlint-report.md', 'utf8');
128+ report += '### 📝 Details\n\n';
129+ report += '<details>\n<summary>Click to expand violations</summary>\n\n';
130+ report += markdownReport;
131+ report += '\n</details>\n\n';
132+ } catch (error) {
133+ console.log('Could not read markdown report');
134+ }
135+
136+ report += '### 🔧 Quick Fixes\n\n';
137+ report += '```swift\n';
138+ report += '// Add accessibility labels to images\n';
139+ report += 'Image(systemName: "star")\n';
140+ report += ' .accessibilityLabel("Favorite")\n\n';
141+ report += '// Hide decorative images\n';
142+ report += 'Image(systemName: "sparkles")\n';
143+ report += ' .accessibilityHidden(true)\n';
144+ report += '```\n\n';
145+ report += '### 📚 Resources\n';
146+ report += '- [Apple Accessibility Guidelines](https://developer.apple.com/accessibility/)\n';
147+ report += '- [SwiftUI Accessibility](https://developer.apple.com/documentation/swiftui/view-accessibility)\n';
148+ } else {
149+ report += '### ✅ All checks passed!\n';
150+ }
151+
152+ github.rest.issues.createComment({
153+ issue_number: context.issue.number,
154+ owner: context.repo.owner,
155+ repo: context.repo.repo,
156+ body: report
157+ });
158+
159+ - name : Fail if violations found
160+ if : env.LINT_FAILED == 'true'
161+ run : |
162+ echo "::error::SwiftLint found accessibility violations"
163+ exit 1
0 commit comments