Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 0 additions & 42 deletions .github/workflows/ci-core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,6 @@ on:
description: GitHub-generated merge commit to test
required: true
type: string
publish_status:
description: Publish CI / required from the trusted main refresh path
required: false
type: boolean
default: false

concurrency:
group: ci-pr-${{ inputs.pr_number }}
Expand Down Expand Up @@ -463,7 +458,6 @@ jobs:
timeout-minutes: 5
permissions:
contents: read
statuses: write
steps:
- name: 汇总所有必要任务
id: summary
Expand Down Expand Up @@ -519,42 +513,6 @@ jobs:
require_job nginx "$NGINX_RESULT" "$NGINX_REQUIRED"
require_job dependency_review "$DEPENDENCY_RESULT" "$DEPENDENCY_REQUIRED"

- name: 发布 main 更新重检状态
if: always() && inputs.publish_status
env:
GH_TOKEN: ${{ github.token }}
MERGE_SHA: ${{ inputs.merge_sha }}
SUMMARY_OUTCOME: ${{ steps.summary.outcome }}
shell: bash
run: |
set -euo pipefail
state=failure
description="UniSpeaking 必要 CI 检查未通过"
if [[ "$SUMMARY_OUTCOME" == success ]]; then
state=success
description="UniSpeaking 必要 CI 检查已通过"
fi

jq -n \
--arg state "$state" \
--arg context "CI / required" \
--arg description "$description" \
--arg target_url "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID" \
'{
state: $state,
context: $context,
description: $description,
target_url: $target_url
}' > "$RUNNER_TEMP/status.json"

curl --fail-with-body --silent --show-error \
--request POST \
--header "Authorization: Bearer $GH_TOKEN" \
--header "Accept: application/vnd.github+json" \
--header "X-GitHub-Api-Version: 2022-11-28" \
--data-binary "@$RUNNER_TEMP/status.json" \
"$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/$MERGE_SHA"

- name: 执行最终门禁
if: always() && steps.summary.outcome != 'success'
run: exit 1
48 changes: 47 additions & 1 deletion .github/workflows/ci-refresh-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,50 @@ jobs:
base_sha: ${{ needs.resolve.outputs.base_sha }}
head_sha: ${{ needs.resolve.outputs.head_sha }}
merge_sha: ${{ needs.resolve.outputs.merge_sha }}
publish_status: true

publish:
name: 发布重检状态
needs:
- resolve
- core
if: always() && needs.resolve.outputs.runnable == 'true'
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
contents: read
statuses: write
steps:
- name: 发布 CI / required
env:
GH_TOKEN: ${{ github.token }}
MERGE_SHA: ${{ needs.resolve.outputs.merge_sha }}
CORE_RESULT: ${{ needs.core.result }}
shell: bash
run: |
set -euo pipefail
state=failure
description="UniSpeaking 必要 CI 检查未通过"
if [[ "$CORE_RESULT" == success ]]; then
state=success
description="UniSpeaking 必要 CI 检查已通过"
fi

jq -n \
--arg state "$state" \
--arg context "CI / required" \
--arg description "$description" \
--arg target_url "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID" \
'{
state: $state,
context: $context,
description: $description,
target_url: $target_url
}' > "$RUNNER_TEMP/status.json"

curl --fail-with-body --silent --show-error \
--request POST \
--header "Authorization: Bearer $GH_TOKEN" \
--header "Accept: application/vnd.github+json" \
--header "X-GitHub-Api-Version: 2022-11-28" \
--data-binary "@$RUNNER_TEMP/status.json" \
"$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/$MERGE_SHA"
69 changes: 69 additions & 0 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: Coverage

on:
push:
branches:
- main
paths:
- backend/**
- .github/workflows/coverage.yml
workflow_dispatch:

permissions:
contents: read

concurrency:
group: coverage-main
cancel-in-progress: true

jobs:
backend:
name: 生成并发布后端覆盖率
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: read
id-token: write
defaults:
run:
working-directory: backend/unispeaking-server
steps:
- name: 检出 main
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4

- name: 配置 Java 21
uses: actions/setup-java@c1e323688fd81a25caa38c78aa6df2d33d3e20d9 # v4
with:
distribution: temurin
java-version: "21"
cache: maven
cache-dependency-path: backend/unispeaking-server/pom.xml

- name: 运行测试并生成 JaCoCo 聚合报告
shell: bash
run: >-
./mvnw
--batch-mode
--no-transfer-progress
-Pci-integration,coverage-aggregate
clean
verify

- name: 上传 JaCoCo XML 到 Codecov
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v6.0.2
with:
use_oidc: true
files: backend/unispeaking-server/target/site/jacoco-aggregate/jacoco.xml
disable_search: true
fail_ci_if_error: true
flags: backend
name: backend-aggregate

- name: 保存 JaCoCo 聚合报告
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: backend-main-coverage
path: backend/unispeaking-server/target/site/jacoco-aggregate
if-no-files-found: error
retention-days: 30
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# UniSpeaking

[![后端测试](https://github.com/1024XEngineer/UniSpeaking/actions/workflows/coverage.yml/badge.svg?branch=main)](https://github.com/1024XEngineer/UniSpeaking/actions/workflows/coverage.yml)
[![后端覆盖率](https://codecov.io/gh/1024XEngineer/UniSpeaking/branch/main/graph/badge.svg?flag=backend)](https://codecov.io/gh/1024XEngineer/UniSpeaking)

覆盖率目前统计后端 Java 代码,合并单元测试及 PostgreSQL、Redis 集成测试结果;
前端尚未接入自动化测试覆盖率。

UniSpeaking 是一个面向英语口语学习的 AI 实时陪练系统。当前仓库包含 React 前端、
Spring Boot 后端、PostgreSQL 数据模型以及 Nginx/Docker 部署配置。

Expand Down
13 changes: 13 additions & 0 deletions docs/ci.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Redis 引入生产运行时。
| `ci-refresh.yml` | `main` 更新后查找全部开放 PR,并行发起重检 |
| `ci-refresh-pr.yml` | 等待包含最新 `main` 的 merge SHA,跳过冲突或已变化的 PR |
| `ci-status.yml` | 在可信上下文校验当前 base、head、merge SHA 后发布 `CI / required` |
| `coverage.yml` | `main` 后端变更后生成 JaCoCo 聚合报告并通过 OIDC 上传到 Codecov |

同一 PR 的核心检查使用 `ci-pr-<PR 编号>` 并发组。出现新提交或 `main` 更新时,旧检查
会自动取消;不同 PR 可以并行执行。PR 工作流只使用只读权限,不接收仓库 Secrets。
Expand Down Expand Up @@ -74,6 +75,18 @@ GitHub Actions 在对应运行的 Artifacts 中保留以下内容 30 天:
PR 不上传后端 JAR、前端 `dist` 或 Docker 镜像。用于在任务间合并覆盖率和校验 merge SHA
的临时数据只保留 1 天。

根目录 README 显示 `main` 分支的后端测试状态和 Codecov 覆盖率。覆盖率合并单元测试
及 PostgreSQL、Redis 集成测试所执行的后端 Java 代码;它不是数据库表或 SQL 语句的
覆盖率。前端尚未建立自动化测试覆盖率,因此 README 暂不显示前端覆盖率。
`coverage.yml` 上传的是 JaCoCo 聚合报告
`backend/unispeaking-server/target/site/jacoco-aggregate/jacoco.xml`,同时使用
`backend` flag 标记报告。上传通过 GitHub OIDC 鉴权,不需要配置 `CODECOV_TOKEN`。

首次启用前,仓库管理员需要在 Codecov 中安装 GitHub App 并激活
`1024XEngineer/UniSpeaking`。工作流合入 `main` 后会自动进行首次上传;也可以在
Actions 的 Coverage 工作流中手动运行。首次上传成功前,README 徽章可能显示
`unknown`。

## 首次启用与分支保护

新增工作流的首个 PR 合并前,默认分支尚不存在可供 Ruleset 选择的
Expand Down
Loading