diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..ba6f6fff7 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,90 @@ +name: CI + +# PR 门禁。只保两件事(详见 Makefile 的 ci-syntax): +# G1 生成的代码能被编译 +# G2 生成的代码没有重复项(重复方法、重复 都是 mvn compile 的编译期错误) +# 代码风格不进门禁:风格问题不影响 SDK 能否使用。 +# +# **本仓的 lint 目前是空壳**:Makefile 里 `lint` 就是 `echo "skipped"`,exit 0 但什么都没检查。 +# 之所以还留着这个 job,是为了将来填实时位置已经在、不用再动 workflow; +# 但它的绿色不代表任何东西 —— 本仓门禁的有效性完全由 ci-syntax + test 两个 job 承担。 +# 不要把「java 有 lint job」读成「java 做了 lint 把关」。 +# +# JDK 统一为 17。此前 codecov.yml 用 11、sonar.yml 用 17,同一份代码两个版本各测各的, +# 出分歧时谁是准的说不清;codecov.yml 已随本次改动删除,覆盖率上传并进 test job, +# 从此全仓只有 17 这一个门禁版本。 +# +# pom 声明的下界是 1.8,本门禁不验证它——那是「声明还成不成立」的问题, +# 与本次改动是否正确无关,不该占用每个 PR 的时间。要验的时候手工跑一次即可。 +# +# 分支保护只需把 `ci-gate` 配成 required check,其余 job 增删都不影响它。 + +on: + pull_request: + branches: [master] + push: + branches: [master] + +permissions: + contents: read + +jobs: + ci-syntax: + name: ci-syntax + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + - uses: actions/setup-java@v5 + with: + java-version: '17' + distribution: temurin + # 51 个 module 每个 job 都重下一遍依赖太慢,交给 setup-java 自带的 ~/.m2 缓存。 + cache: maven + - run: make ci-syntax + + lint: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + - uses: actions/setup-java@v5 + with: + java-version: '17' + distribution: temurin + cache: maven + # 注意:这一步当前恒绿且什么都没做,见文件头部说明。 + - run: make lint + + test: + name: test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + - uses: actions/setup-java@v5 + with: + java-version: '17' + distribution: temurin + cache: maven + - run: make test-cov + # 覆盖率上传是看板不是门禁:codecov 服务抖动不该把 PR 卡死, + # 故 step 级 continue-on-error,且 ci-gate 的 needs 里也没有它。 + - name: Upload coverage + continue-on-error: true + uses: codecov/codecov-action@v7 + with: + fail_ci_if_error: false + + ci-gate: + name: ci-gate + needs: [ci-syntax, lint, test] + if: always() + runs-on: ubuntu-latest + steps: + - name: Aggregate + run: | + if [[ "${{ contains(needs.*.result, 'failure') }}" == "true" \ + || "${{ contains(needs.*.result, 'cancelled') }}" == "true" ]]; then + echo "ci-gate: 有 job 失败或被取消" + exit 1 + fi + echo "ci-gate: 全部通过" diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml deleted file mode 100644 index d1d0b70ec..000000000 --- a/.github/workflows/codecov.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: Codecov - -on: - push: - branches: - - master - - release/* - pull_request: - types: [opened, synchronize, reopened] - -jobs: - test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Run tests - run: mvn --batch-mode --update-snapshots test - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v1 - with: - fail_ci_if_error: false diff --git a/.github/workflows/sonar.yml b/.github/workflows/sonar.yml index b47da867f..b46042a87 100644 --- a/.github/workflows/sonar.yml +++ b/.github/workflows/sonar.yml @@ -1,4 +1,23 @@ name: Sonar + +# 这个 workflow 现在是**非阻断的质量看板,不是门禁**。 +# +# 起因:SONAR_TOKEN 已失效,「Build and analyze」这一步 403 恒失败(最近 8 次全红)。 +# 只要它是红的,PR 的 mergeable_state 就恒为 unstable、永远到不了 clean, +# codegen PR 的自动合并会被这条与代码质量无关的红叉挡死。 +# 处置:给该 step 加 step 级 continue-on-error —— step 仍然会红、问题不被掩盖, +# 但 job 结论是 success,不再拖住合并。**修好 token 是另一件事,不在本次范围内。** +# +# job 的显示名 `Build` 必须保持不变:它可能已经被配进分支保护的 required check, +# 改名会让那条 required check 永远 pending、把所有 PR 卡死。 +# (job key 仍叫 `lint` 是历史遗留,与代码风格检查无关;本仓真正的 lint 见 ci.yml, +# 且那个目前是空壳。) +# +# 已从原来的 `mvn verify` 缩为只跑到 compile:verify 会把测试和打包再跑一遍, +# 而这两件事 ci.yml 已经做了,重复跑既费时又让「哪个结果算数」变得含糊。 +# sonar 分析本身只需要有编译产物即可。 +# 原来的 -Dgpg.skip 一并去掉:gpg 签名绑在 verify 阶段,跑到 compile 根本到不了那里。 + on: push: branches: @@ -6,32 +25,41 @@ on: - release/* pull_request: types: [opened, synchronize, reopened] + +permissions: + contents: read + jobs: lint: name: Build runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v7 with: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - name: Set up JDK 17 - uses: actions/setup-java@v1 + uses: actions/setup-java@v5 with: - java-version: 17 + java-version: '17' + distribution: temurin - name: Cache SonarCloud packages - uses: actions/cache@v3 + uses: actions/cache@v6 with: path: ~/.sonar/cache key: ${{ runner.os }}-sonar restore-keys: ${{ runner.os }}-sonar - name: Cache Maven packages - uses: actions/cache@v3 + uses: actions/cache@v6 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 + # continue-on-error 加在 step 上而不是 job 上: + # job 级会把整个 job 标成 success 却看不出哪里出了问题, + # step 级则是这一步红、job 绿,红叉仍留在 Actions 页面上等人去修 token。 - name: Build and analyze + continue-on-error: true env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dgpg.skip -Dsonar.projectKey=ucloud_ucloud-sdk-java + run: mvn -B -DskipTests compile org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=ucloud_ucloud-sdk-java diff --git a/Makefile b/Makefile index fe25a2580..d728e5394 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,19 @@ build: fmt: google-java-format --aosp -r ${JAVA_FILES} +# CI 语法闸。只保两件事,都由 mvn compile 一次覆盖全部产品 module: +# G1 生成的代码能被编译 —— 编译不过直接失败。 +# G2 生成的代码没有重复项 —— 重复方法、重复 都是编译期错误,天然被抓住。 +# 已知缺口(如实记录,不要以为这条闸是全的): +# 重复的 在 maven 里只有 WARNING、不会让构建失败,本 target 对它无闸。 +# 要补需引入 maven-enforcer-plugin 的 banDuplicatePomDependencyVersions, +# 经评估后决定不引入,故该缺口保留。 +.PHONY: ci-syntax +ci-syntax: + mvn -B -DskipTests compile + +# 警告:当前是空壳,exit 0 但什么都没检查,不要把它的通过当成风格已过检。 +# 填实需要先跑一次全仓 google-java-format(见 fmt),是个独立的大 diff,不在 CI 改造范围内。 .PHONY: lint lint: echo "skipped"