diff --git a/.github/workflows/swift.yml b/.github/workflows/swift.yml index 81867f32..2a6c1804 100644 --- a/.github/workflows/swift.yml +++ b/.github/workflows/swift.yml @@ -37,10 +37,21 @@ jobs: - name: Resolve SPM dependencies run: xcodebuild -resolvePackageDependencies -scheme STBaseProject-Package - - name: Build (iOS Simulator) + - name: Build (iOS Simulator) with compile log run: | + # 完整编译日志供 swiftlint analyze 使用(analyzer_rules 依赖 type-checked AST)。 + # 不使用增量构建缓存,确保日志完整。 + rm -rf ~/Library/Developer/Xcode/DerivedData xcodebuild \ -scheme STBaseProject-Package \ -destination 'generic/platform=iOS Simulator' \ - build + clean build | tee xcodebuild.log + + - name: SwiftLint Analyze (unused_import / unused_declaration) + run: | + # analyzer_rules 仅在 `swiftlint analyze` 下执行;普通 `swiftlint lint` 不会跑。 + # 需完整编译日志(上方 Build 步骤产出 xcodebuild.log)。 + swiftlint analyze \ + --compiler-log-path xcodebuild.log \ + --reporter github-actions-logging diff --git a/.swiftlint.yml b/.swiftlint.yml index d54ba491..0aec900f 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -1,6 +1,6 @@ # SwiftLint 配置 —— STBaseProject # 与 .github/check_try_question_mark.sh 互补:try? 政策由专门脚本兜底,本文件聚焦 -# 其他反模式:强解包、as!、过长文件、Bool 旗参痕迹、`@objc` 滥用等。 +# 其他反模式:强解包、as!、过长文件、含糊 Bool 参数、`@objc` 滥用等。 # # 渐进式落地策略: # - 严重项标 error(as!、Markdown 外 try! 在源码区) @@ -22,8 +22,11 @@ disabled_rules: - type_name # 同上 - trailing_whitespace # 历史空白多,独立 PR 清理 - opening_brace # 与历史风格不一致 - - line_length # 由下方自定义长度覆盖 + # 注意:line_length 是默认开启规则,不在 disabled_rules 中关闭, + # 直接在下方 line_length: 配置块生效(置于 disabled_rules 会导致同名配置块被忽略) - force_try # 由 st_no_force_try_outside_markdown 精准限制,允许 STMarkdown 静态正则 + - blanket_disable_command # 基础库大量历史 disable 注释,不卡"禁用过多/需 re-enable"风格 + - superfluous_disable_command # 同上:保留历史 disable 豁免,不因区域内未触发而告警 opt_in_rules: - empty_count @@ -41,7 +44,8 @@ opt_in_rules: - contains_over_filter_count - contains_over_first_not_nil - convenience_type - - discouraged_optional_boolean # ★ 标记 Optional,常是 Bool 旗参的延伸坏味 + - discouraged_optional_boolean # ★ 标记 Optional;若确需三态语义,局部说明并豁免 + - redundant_objc_attribute # ★ 检查不必要的 @objc,与顶部注释“@objc 滥用”策略一致 - fallthrough - fatal_error_message - flatmap_over_map_reduce @@ -55,6 +59,14 @@ opt_in_rules: - redundant_string_enum_value - sorted_imports - toggle_bool + - missing_docs # ★ 公开 API 缺文档报警(先 warning 观察存量,后续可收紧) + # === 公共基础库 Bug Prevention(第一批,低风险高价值)=== + - weak_delegate # ★ delegate 必须为 weak,否则循环引用 + - discarded_notification_center_observer # ★ block observer token 应被持有,便于按生命周期移除 + - private_subject # ★ Combine Subject 不应作为公开属性暴露 + - unhandled_throwing_task # ★ 显式处理 throwing Task 的错误或结果 + # 注:SwiftLint 无“公开类强制 final”规则(final_class 不存在);如需约束可改用 + # 架构评审/PR 模板,或 static_over_final_class(语义不同,未启用)。 force_cast: error # as! 直接 error @@ -62,6 +74,12 @@ analyzer_rules: - unused_import - unused_declaration +# 公开 API 文档缺失检查:先 warning 观察存量,待清零后可改为 error 收紧。 +# 仅检查 public 级别(open/internal/private 豁免),避免内部实现噪音。 +# CI 不使用 --strict,因此当前 warning 不阻断;使用 --strict 时会提升为 error。 +missing_docs: + warning: public + # === 规则参数化 === line_length: warning: 220 @@ -88,7 +106,10 @@ cyclomatic_complexity: error: 30 nesting: - type_level: 3 + type_level: + warning: 3 + function_level: + warning: 2 # === 自定义规则 === custom_rules: @@ -104,17 +125,21 @@ custom_rules: st_no_print: name: "Use STLog instead of print" - regex: '(?