diff --git a/.github/scripts/checkstyle-pr.sh b/.github/scripts/checkstyle-pr.sh new file mode 100644 index 00000000..25135bb3 --- /dev/null +++ b/.github/scripts/checkstyle-pr.sh @@ -0,0 +1,102 @@ +#!/bin/bash +# ============================================================ +# checkstyle-pr.sh - 增量检查(扫描整个变更文件,不过滤行号) +# 功能:对本次提交中变更的 Java 文件执行完整的 Checkstyle 检查 +# 不阻断构建,生成完整报告 +# ============================================================ + +set -e + +echo "========================================" +echo " Checkstyle 增量检查" +echo " 扫描范围:本次变更的 Java 文件(完整文件)" +echo "========================================" + +# 1. 确定目标分支 +if [ -n "$GITHUB_BASE_REF" ]; then + BASE_BRANCH="origin/$GITHUB_BASE_REF" +elif [ -n "$GITHUB_REF" ] && [ "$GITHUB_EVENT_NAME" == "push" ]; then + BASE_BRANCH="HEAD^" +else + if git rev-parse --verify origin/main >/dev/null 2>&1; then + BASE_BRANCH="origin/main" + elif git rev-parse --verify origin/develop >/dev/null 2>&1; then + BASE_BRANCH="origin/develop" + else + echo "❌ 无法确定目标分支,请设置 BASE_BRANCH 环境变量。" + exit 1 + fi + echo "🔍 本地运行模式,对比分支: $BASE_BRANCH" +fi + +# 2. 获取变更的 Java 文件 +CHANGED_FILES=$(git diff --name-only "$BASE_BRANCH" HEAD 2>/dev/null | grep '\.java$' || true) + +if [ -z "$CHANGED_FILES" ]; then + echo "✅ 没有 Java 文件变更,跳过检查。" + exit 0 +fi + +echo "📝 变更的 Java 文件:" +echo "$CHANGED_FILES" +echo "----------------------------------------" + +# 3. 将文件列表转为逗号分隔 +FILES_LIST=$(echo "$CHANGED_FILES" | tr '\n' ',' | sed 's/,$//') + +# 4. 执行 Checkstyle 扫描(生成完整报告) +echo "🚀 执行 Checkstyle 扫描(完整文件)..." +echo "FILES_LIST: $FILES_LIST" +set +e +mvn checkstyle:check \ + -Dcheckstyle.includes="$FILES_LIST" \ + -Dcheckstyle.violationSeverity=warning +MVN_EXIT=$? +set -e + +# 5. 确定报告路径(根据项目结构调整) +REPORT_FILE="base/target/checkstyle-result.xml" +if [ ! -f "$REPORT_FILE" ]; then + echo "❌ 未生成 Checkstyle 报告,请检查 Maven 配置。" + exit 0 +fi + +# 6. 统计违规数 +VIOLATIONS=$(grep -c '//' | \ + sed 's/line="/行号: /; s/column="/列: /; s/severity="/严重性: /; s=message="=信息: =; s=source="//' | \ + while read -r line; do + echo " $line" + done +fi + +# 7. 输出到 GitHub Step Summary +if [ -n "$GITHUB_STEP_SUMMARY" ]; then + { + echo "## 📋 Checkstyle 报告" + echo "" + echo "| 指标 | 结果 |" + echo "|------|------|" + if [ $VIOLATIONS -eq 0 ]; then + echo "| 违规数 | ✅ **0** |" + else + echo "| 违规数 | ⚠️ **$VIOLATIONS** |" + fi + echo "| 扫描文件 | **$(echo "$CHANGED_FILES" | wc -l)** 个变更 Java 文件 |" + echo "| 检查方式 | 对变更文件进行完整扫描 |" + echo "" + echo "📥 完整报告已作为 Artifact 上传,请在工作流运行页面下载。" + } >> "$GITHUB_STEP_SUMMARY" + echo "✅ Step Summary 已更新" +fi + +# 8. 始终以成功状态退出 +exit 0 \ No newline at end of file diff --git a/.github/workflows/checkstyle.yml b/.github/workflows/checkstyle.yml index 74529b84..162c2b21 100644 --- a/.github/workflows/checkstyle.yml +++ b/.github/workflows/checkstyle.yml @@ -3,35 +3,59 @@ name: Checkstyle Code Quality on: push: branches: - - develop # 或者你想要检查的分支 + - develop pull_request: branches: - - develop # 你可以在 PR 时检查代码 + - develop jobs: - check: + checkstyle: runs-on: ubuntu-24.04 + env: + FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true steps: - # 检出代码 - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v6 + with: + fetch-depth: 0 # 必须拉取完整历史,才能比较分支差异 - # 设置 JDK(如果是 Java 项目) - - name: Set up JDK 17.* - uses: actions/setup-java@v4 + - name: Set up JDK 17 + uses: actions/setup-java@v5 with: - java-version: '17.*' + java-version: '17' distribution: 'temurin' - # 安装依赖并运行 Checkstyle(如果是 Maven 项目) - - name: Install dependencies and run Checkstyle + # 缓存 Maven 依赖,加速构建 + - name: Cache Maven dependencies + uses: actions/cache@v5 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- + + # 直接运行 Checkstyle 检查(不执行完整的 package) + - name: Run Checkstyle + run: bash .github/scripts/checkstyle-pr.sh + env: + GITHUB_BASE_REF: ${{ github.base_ref }} + + - name: Debug - list all checkstyle reports run: | - mvn clean package + echo "当前工作目录: $(pwd)" + echo "=== 列出所有 target 目录 ===" + find . -type d -name "target" -exec echo "目录: {}" \; -exec ls -la {}/ \; + echo "=== 查找 checkstyle 文件 ===" + find . -name "checkstyle*.xml" -o -name "checkstyle*.html" | while read f; do echo "找到: $f"; done - # 查看 Checkstyle 检查报告 + # 如果检查失败,仍然上传报告供查看 - name: Upload Checkstyle report - uses: actions/upload-artifact@v4 + if: always() # 即使失败也上传报告 + uses: actions/upload-artifact@v7 with: name: checkstyle-report - path: target/checkstyle-result.xml # 这个路径应该是 Maven 生成的检查报告路径 + path: | + **/target/checkstyle-result.xml + **/target/site/checkstyle.html + if-no-files-found: warn diff --git a/base/src/main/java/com/tinyengine/it/common/utils/testCheckstyle.java b/base/src/main/java/com/tinyengine/it/common/utils/testCheckstyle.java new file mode 100644 index 00000000..38ef8956 --- /dev/null +++ b/base/src/main/java/com/tinyengine/it/common/utils/testCheckstyle.java @@ -0,0 +1,111 @@ +package com.tinyengine.it.common.utils; +import java.lang.reflect.Field; + +/** + * 类名错误:应使用 UpperCamelCase(首字母大写) + * 这里故意写成了小写开头的 testCheckstyle + */ +public class testCheckstyle { + + // 常量命名错误:应全部大写并用下划线分隔 + public static final String myConstant = "Hello"; + + // 成员变量命名错误:不应以下划线开头 + private String _name; + + // 成员变量命名错误:不应使用单个字符 + private int a; + + /** + * 构造方法:可以接受参数,但未提供 Javadoc + */ + public testCheckstyle(String name) { + this._name = name; + } + + public void test() { + long value = 1l; // 错误:使用了小写 l + System.out.println(value); + } + public void longMethod() { + // 填充到超过 300 行,例如添加 301 个空行或打印语句 + for (int i = 0; i < 301; i++) { + System.out.println("line " + i); + } + } + + public void test1() { + if (true) { + if (true) { + if (true) { + if (true) { // 第4层嵌套,超过最大值3 + System.out.println("deep"); + } + } + } + } + } + + public void test2() { + String s = "hello"; + if (s == "hello") { // 错误:应使用 equals() + System.out.println("equal"); + } + } + + /** + * 方法名错误:不应包含大写字母,应使用 lowerCamelCase + */ + public void SayHello() { + // 行长度超限(超过120字符),故意写长 + System.out.println("This line is intentionally made extremely long to exceed the maximum line length limit which is usually set to 120 characters in Huawei coding standard. It definitely exceeds 120 chars."); + + // 缩进可能使用Tab(如果你的编辑器未转换,此处会触发) + // 未使用的局部变量 + String unused = "I am not used anywhere"; + } + + /** + * 公共方法缺少 Javadoc 注释 + */ + public void doSomething() { + // 方法体为空或简单,但缺少注释 + } + + /** + * 方法名包含下划线,违反 lowerCamelCase + */ + public void do_this() { + // 空方法体 + } + + /** + * 参数和返回值缺少 Javadoc 说明(如果有要求) + */ + public int add(int a, int b) { + return a + b; + } + + /** + * 重载方法,但缺少 Javadoc + */ + public int add(int a, int b, int c) { + return a + b + c; + } + + // 缺少访问修饰符的方法(默认包级别,可能不符合规范) + void packagePrivateMethod() { + System.out.println("This method has no access modifier."); + } + + // 静态方法命名错误 + public static void StaticMethod() { + // 方法名首字母大写,违反 lowerCamelCase + } + + // 常量应放在静态代码块或声明时赋值,但此处未遵循顺序 + public static final String ANOTHER_CONST; + static { + ANOTHER_CONST = "Init"; + } +} diff --git a/base/src/test/java/com/tinyengine/it/common/utils/JsonUtilsTest.java b/base/src/test/java/com/tinyengine/it/common/utils/JsonUtilsTest.java index 80562311..37cdcc38 100644 --- a/base/src/test/java/com/tinyengine/it/common/utils/JsonUtilsTest.java +++ b/base/src/test/java/com/tinyengine/it/common/utils/JsonUtilsTest.java @@ -270,7 +270,7 @@ void testEncodePrettily_ComplexObject() { void testDecode_ByteArray() { // Arrange String json = "{\"key\":\"value\",\"number\":123}"; - byte[] jsonBytes = json.getBytes(StandardCharsets.UTF_8); + byte[] jsonBytes = json.getBytes(); // Act Map result = JsonUtils.decode(jsonBytes, Map.class); diff --git a/checkstyle/huawei-checkstyle.xml b/checkstyle/huawei-checkstyle.xml new file mode 100644 index 00000000..a926d82b --- /dev/null +++ b/checkstyle/huawei-checkstyle.xml @@ -0,0 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index c651a73c..74015246 100644 --- a/pom.xml +++ b/pom.xml @@ -235,6 +235,30 @@ 17 + + + org.apache.maven.plugins + maven-checkstyle-plugin + 3.6.0 + + + ./checkstyle/huawei-checkstyle.xml + + false + warning + + xml + + + + checkstyle-check + validate + + check + + + +