|
29483
|
22435
|
6
|
5
|
cf8ca525a24f7e8f7f02481cf1c6e72f68c3788a
|
0
|
安装依赖
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
setup:
name: 安装依赖
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 安装 pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: pnpm install --frozen-lockfile
- name: 构建共享包
run: pnpm --filter @juhi/shared run build
- name: 缓存依赖
uses: actions/cache/save@v4
with:
key: pipeline-deps-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
path: |
node_modules
backend/node_modules
frontend/node_modules
shared/node_modules
shared/dist
e2e/node_modules
...
|
setup
|
null
|
["ubuntu-latest"]
|
25754
|
2
|
1778609487
|
1778609519
|
1778598489
|
1778609519
|
|
0
|
|
0
|
Edit
Delete
|
|
29606
|
22503
|
6
|
5
|
cf8ca525a24f7e8f7f02481cf1c6e72f68c3788a
|
0
|
安装依赖
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
setup:
name: 安装依赖
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 安装 pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: pnpm install --frozen-lockfile
- name: 构建共享包
run: pnpm --filter @juhi/shared run build
- name: 缓存依赖
uses: actions/cache/save@v4
with:
key: pipeline-deps-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
path: |
node_modules
backend/node_modules
frontend/node_modules
shared/node_modules
shared/dist
e2e/node_modules
...
|
setup
|
null
|
["ubuntu-latest"]
|
25853
|
2
|
1778624237
|
1778624327
|
1778624145
|
1778624328
|
|
0
|
|
0
|
Edit
Delete
|
|
29652
|
22505
|
6
|
5
|
75c32172af80b8afc83b0c684b9d65fba5cf9d7e
|
0
|
安装依赖
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
setup:
name: 安装依赖
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 安装 pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: pnpm install --frozen-lockfile
- name: 构建共享包
run: pnpm --filter @juhi/shared run build
- name: 缓存依赖
uses: actions/cache/save@v4
with:
key: pipeline-deps-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
path: |
node_modules
backend/node_modules
frontend/node_modules
shared/node_modules
shared/dist
e2e/node_modules
...
|
setup
|
null
|
["ubuntu-latest"]
|
25857
|
2
|
1778625918
|
1778625949
|
1778624232
|
1778625950
|
|
0
|
|
0
|
Edit
Delete
|
|
9371
|
7506
|
6
|
5
|
ff3149170c6b0deb6d8151cb962592199b95bdd8
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
8128
|
1
|
1774286325
|
1774286326
|
1774286007
|
1774286326
|
|
1
|
|
0
|
Edit
Delete
|
|
9534
|
7601
|
6
|
5
|
2ec5b7d8079ffd911c7b27a395d5aba3ceafe372
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
8264
|
1
|
1774312506
|
1774312508
|
1774312190
|
1774312508
|
|
1
|
|
0
|
Edit
Delete
|
|
9609
|
7615
|
6
|
5
|
07680473f95a02e139e159147a93ef74e61f3db2
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
8312
|
1
|
1774314834
|
1774314835
|
1774314118
|
1774314836
|
|
1
|
|
0
|
Edit
Delete
|
|
9680
|
7625
|
6
|
5
|
cfe1efeda7265f05374d3bd0036cf684a15f3cb9
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
8355
|
1
|
1774315825
|
1774315826
|
1774315057
|
1774315826
|
|
1
|
|
0
|
Edit
Delete
|
|
9763
|
7638
|
6
|
5
|
8c39619c9cdb0d888d10942bf50533c8238021df
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
8400
|
1
|
1774317031
|
1774317032
|
1774316715
|
1774317032
|
|
1
|
|
0
|
Edit
Delete
|
|
9836
|
7650
|
6
|
5
|
dbf34b08bbb60650d15b0c55262dbfe8d0a3a655
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
8449
|
2
|
1774319105
|
1774319280
|
1774318461
|
1774319280
|
|
1
|
|
0
|
Edit
Delete
|
|
9914
|
7667
|
6
|
5
|
db7f39e63151b9c065646855287b8be73e13649b
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
8499
|
2
|
1774321792
|
1774321882
|
1774321431
|
1774321882
|
|
1
|
|
0
|
Edit
Delete
|
|
9994
|
7686
|
6
|
5
|
81e883dfff9283af39b3dd2aa30e25ae2119e8f0
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
8553
|
1
|
1774325280
|
1774325281
|
1774325031
|
1774325281
|
|
1
|
|
0
|
Edit
Delete
|
|
10144
|
7766
|
6
|
5
|
9f09902dce3537d952595fd6d33175b6f0c24c7e
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
8667
|
1
|
1774346928
|
1774346929
|
1774346642
|
1774346929
|
|
1
|
|
0
|
Edit
Delete
|
|
10437
|
7982
|
6
|
5
|
adc3e0209b2ffa4d34c89b638f1f03b36ebfd24f
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
8922
|
1
|
1774408813
|
1774408813
|
1774408525
|
1774408814
|
|
1
|
|
0
|
Edit
Delete
|
|
10606
|
8090
|
6
|
5
|
1b2a0b35284edd65cdda0501ced15ca388220ddd
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
9066
|
2
|
1774439148
|
1774439238
|
1774438841
|
1774439238
|
|
1
|
|
0
|
Edit
Delete
|
|
10680
|
8103
|
6
|
5
|
6dde21cfcbb2a424db0efb8629b4351eb2a43315
|
0
|
质量门禁
|
0
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774443470
|
1774440695
|
1774443470
|
|
0
|
|
0
|
Edit
Delete
|
|
10729
|
8115
|
6
|
5
|
3b540d63f39a66a79b06f096f7b7e9041dd4bc26
|
0
|
质量门禁
|
0
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774444076
|
1774443472
|
1774444076
|
|
0
|
|
0
|
Edit
Delete
|
|
10771
|
8120
|
6
|
5
|
83de8108577a8633d0dc3193eb7e19e9e6a668c1
|
0
|
质量门禁
|
0
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774444188
|
1774444078
|
1774444188
|
|
0
|
|
0
|
Edit
Delete
|
|
10811
|
8123
|
6
|
5
|
18d5b913e02e9d72301206688cfee01e40b9d2cd
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
9190
|
2
|
1774451250
|
1774451340
|
1774444191
|
1774451340
|
|
1
|
|
0
|
Edit
Delete
|
|
11077
|
8303
|
6
|
5
|
0b85dd84d5debc36f158918b188cde8b6305035f
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
9385
|
1
|
1774494801
|
1774494802
|
1774493746
|
1774494802
|
|
1
|
|
0
|
Edit
Delete
|
|
11263
|
8428
|
6
|
5
|
6b8d13c5b29827249da650ed1bd9ace7fc68959c
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
9543
|
1
|
1774529277
|
1774529278
|
1774528964
|
1774529278
|
|
1
|
|
0
|
Edit
Delete
|
|
11572
|
8669
|
6
|
5
|
c09d9ff6160d851464fbce2a407409d4e8d2bc95
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
9835
|
1
|
1774602061
|
1774602061
|
1774598827
|
1774602062
|
|
1
|
|
0
|
Edit
Delete
|
|
11900
|
8929
|
6
|
5
|
59f46625b28f7defe4dba196efd9edd5f82ed701
|
0
|
质量门禁
|
0
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774674958
|
1774674588
|
1774674958
|
|
0
|
|
0
|
Edit
Delete
|
|
11942
|
8934
|
6
|
5
|
9953914b57055e78c3af10cbf077f41f0580f0da
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
10150
|
1
|
1774676706
|
1774676707
|
1774674960
|
1774676708
|
|
1
|
|
0
|
Edit
Delete
|
|
12044
|
8966
|
6
|
5
|
5b7447bfcd02c4ecefee1ed6a7ca386a974d8d29
|
0
|
质量门禁
|
0
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774682195
|
1774681536
|
1774682195
|
|
0
|
|
0
|
Edit
Delete
|
|
12086
|
8971
|
6
|
5
|
03181d96b7830a1e1ec141a36a19c7a59c681262
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
10229
|
1
|
1774683480
|
1774683481
|
1774682196
|
1774683481
|
|
1
|
|
0
|
Edit
Delete
|
|
12186
|
9004
|
6
|
5
|
b27f9d478a1cc664b9ca612e54c2ba37bc57b152
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
10294
|
1
|
1774690761
|
1774690762
|
1774689391
|
1774690762
|
|
1
|
|
0
|
Edit
Delete
|
|
12259
|
9016
|
6
|
5
|
f60415723c7e4450e3f307a54e65df5fbb4d38d2
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
10343
|
2
|
1774692625
|
1774692655
|
1774691011
|
1774692656
|
|
1
|
|
0
|
Edit
Delete
|
|
12337
|
9033
|
6
|
5
|
0c8f4a138b823e8d615f93850a64c3365e5aed15
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
10394
|
2
|
1774695550
|
1774695580
|
1774694075
|
1774695581
|
|
1
|
|
0
|
Edit
Delete
|
|
12609
|
9237
|
6
|
5
|
58e5152a38868b8f3832d9573c340a3eb60051c8
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
10638
|
2
|
1774754105
|
1774754135
|
1774752769
|
1774754135
|
|
1
|
|
0
|
Edit
Delete
|
|
12986
|
9540
|
6
|
5
|
54bd92949aefc1f23668a2a27f1cf7d315589eb3
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
10989
|
1
|
1774841765
|
1774841766
|
1774840767
|
1774841766
|
|
1
|
|
0
|
Edit
Delete
|
|
13060
|
9553
|
6
|
5
|
1e14b41edac86496d70ac83d1cb3292fa0513af3
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
11036
|
1
|
1774843517
|
1774843518
|
1774842575
|
1774843518
|
|
1
|
|
0
|
Edit
Delete
|
|
13134
|
9566
|
6
|
5
|
3ccdb3e3d8a8734cc11324a89259df948523a812
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
11082
|
1
|
1774845150
|
1774845152
|
1774844139
|
1774845152
|
|
1
|
|
0
|
Edit
Delete
|
|
13214
|
9585
|
6
|
5
|
4d1dd7b8c8604ad5b1f60158574ce50a60b0e82c
|
0
|
质量门禁
|
0
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774847841
|
1774847731
|
1774847841
|
|
0
|
|
0
|
Edit
Delete
|
|
13254
|
9588
|
6
|
5
|
a8f1896ed41a547563a11d929465e7a92cdec4e9
|
0
|
质量门禁
|
0
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774847978
|
1774847843
|
1774847978
|
|
0
|
|
0
|
Edit
Delete
|
|
13294
|
9591
|
6
|
5
|
f2d6f50d81972cf5e93d657140a9a89b6e6189fb
|
0
|
质量门禁
|
0
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774848151
|
1774847980
|
1774848151
|
|
0
|
|
0
|
Edit
Delete
|
|
13335
|
9595
|
6
|
5
|
d85951e777b951a8957f68cdbf1d581dc9c91479
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
11191
|
2
|
1774851726
|
1774851816
|
1774848153
|
1774851817
|
|
1
|
|
0
|
Edit
Delete
|
|
13478
|
9656
|
6
|
5
|
1b7720d8bdc8f3778e6ad14715be746db29627af
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
11272
|
1
|
1774863625
|
1774863626
|
1774862379
|
1774863627
|
|
1
|
|
0
|
Edit
Delete
|
|
13558
|
9675
|
6
|
5
|
2cf3567367105da23ab10795975e05379e764f31
|
0
|
质量门禁
|
0
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774867691
|
1774865782
|
1774867691
|
|
0
|
|
0
|
Edit
Delete
|
|
13608
|
9685
|
6
|
5
|
2aeab72a37f15a2a4572f7cf32d2c5e4f430a2e8
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
11345
|
1
|
1774868198
|
1774868199
|
1774867692
|
1774868200
|
|
1
|
|
0
|
Edit
Delete
|
|
13684
|
9697
|
6
|
5
|
a255ed13fa907f9a1c0dc03afaa0038c6c432749
|
0
|
质量门禁
|
0
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774869700
|
1774868831
|
1774869700
|
|
0
|
|
0
|
Edit
Delete
|
|
13731
|
9704
|
6
|
5
|
12913d4ccde98eafffea39e5821bd5d4c15aa868
|
0
|
质量门禁
|
0
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774870952
|
1774869701
|
1774870952
|
|
0
|
|
0
|
Edit
Delete
|
|
13779
|
9712
|
6
|
5
|
6794a93c73e1f0426557604cd3ba8f93a10e82f1
|
0
|
质量门禁
|
0
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774871767
|
1774870954
|
1774871767
|
|
0
|
|
0
|
Edit
Delete
|
|
13822
|
9718
|
6
|
5
|
8a7978e163a401654f636377fc9ca790391d8779
|
0
|
质量门禁
|
0
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774875574
|
1774871769
|
1774875574
|
|
0
|
|
0
|
Edit
Delete
|
|
13900
|
9738
|
6
|
5
|
1ce3f3ee5a8099af3c2b00d92ab83aa31d4d803a
|
0
|
质量门禁
|
0
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774876259
|
1774875576
|
1774876259
|
|
0
|
|
0
|
Edit
Delete
|
|
13943
|
9744
|
6
|
5
|
fb960500246fc412cf02a20cc0b316e9100eeb7f
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
11501
|
2
|
1774879497
|
1774880519
|
1774876262
|
1774880519
|
|
1
|
|
0
|
Edit
Delete
|
|
14196
|
9914
|
6
|
5
|
9901c454467cf62d4e127620f218a97bcca01629
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
11710
|
2
|
1774927431
|
1774927462
|
1774923480
|
1774927462
|
|
1
|
|
0
|
Edit
Delete
|
|
14300
|
9957
|
6
|
5
|
dffb3332733fb56fd51632938c4379422125381c
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
11784
|
1
|
1774936263
|
1774936265
|
1774934356
|
1774936265
|
|
1
|
|
0
|
Edit
Delete
|
|
14433
|
10019
|
6
|
5
|
8c225d73253fe95a23618816b2f7e6a03010cae4
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
11882
|
2
|
1774952222
|
1774952313
|
1774950060
|
1774952313
|
|
1
|
|
0
|
Edit
Delete
|
|
14495
|
10047
|
6
|
5
|
46635b50050ba09e31518824f56b1e2176e7b0b7
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
11941
|
1
|
1774960751
|
1774960753
|
1774957473
|
1774960753
|
|
1
|
|
0
|
Edit
Delete
|
|
14936
|
10420
|
6
|
5
|
7212eb23c82b2ecae9ea1f22fa928fc6382f842d
|
0
|
质量门禁
|
1
|
name: Test Pipeline
"on":
push:
name: Test Pipeline
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
coverage_threshold:
description: '覆盖率阈值 (%)'
required: false
default: '80'
run_ai_tests:
description: '运行 AI 模块测试'
required: false
default: 'true'
type: boolean
run_api_tests:
description: '运行 API 集成测试'
required: false
default: 'true'
type: boolean
run_security_audit:
description: '运行安全审计'
required: false
default: 'true'
type: boolean
env:
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成流水线报告
run: |
echo "## Test Pipeline 结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**分支**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**提交**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**触发者**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 静态检查 + 构建" >> $GITHUB_STEP_SUMMARY
echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端构建 | ${{ needs.backend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端构建 | ${{ needs.frontend-build.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 测试" >> $GITHUB_STEP_SUMMARY
echo "| 测试套件 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端单元测试 (4 分片) | ${{ needs.backend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 后端 API 集成测试 | ${{ needs.backend-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 前端单元测试 | ${{ needs.frontend-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 状态机测试 | ${{ needs.state-machine-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块单元测试 | ${{ needs.ai-unit-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| AI 模块 API 测试 | ${{ needs.ai-api-test.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 安全审计" >> $GITHUB_STEP_SUMMARY
echo "| 审计项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 多租户安全审计 | ${{ needs.tenant-security-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Kafka 事件审计 | ${{ needs.kafka-event-audit.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全扫描 | ${{ needs.dependency-security-scan.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 治理基线 | ${{ needs.governance-baseline.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
- name: 门禁裁决
run: |
FAILED=0
# 构建必须通过
for job in "${{ needs.backend-build.result }}" "${{ needs.frontend-build.result }}"; do
if [ "$job" == "failure" ]; then
echo "构建失败"
FAILED=1
fi
done
# 单元测试必须通过
for job in "${{ needs.backend-unit-test.result }}" "${{ needs.frontend-unit-test.result }}"; do
if [ "$job" == "failure" ]; then
echo "单元测试失败"
FAILED=1
fi
done
# 状态机测试必须通过
if [ "${{ needs.state-machine-test.result }}" == "failure" ]; then
echo "状态机测试失败"
FAILED=1
fi
# AI 模块测试失败视为阻塞
if [ "${{ needs.ai-unit-test.result }}" == "failure" ]; then
echo "AI 模块单元测试失败"
FAILED=1
fi
# 多租户安全审计(红线 1)
if [ "${{ needs.tenant-security-audit.result }}" == "failure" ]; then
echo "多租户安全审计失败 - CRITICAL 数据安全风险"
FAILED=1
fi
# Kafka 事件审计(红线 3)
if [ "${{ needs.kafka-event-audit.result }}" == "failure" ]; then
echo "Kafka 事件审计失败 - 审计链断裂风险"
FAILED=1
fi
# 依赖安全扫描
if [ "${{ needs.dependency-security-scan.result }}" == "failure" ]; then
echo "依赖安全扫描失败 - 存在 high/critical 漏洞"
FAILED=1
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "质量门禁未通过"
exit 1
fi
echo "质量门禁通过"
- if: github.event_name == 'pull_request' && always()
name: PR 评论质量报告
uses: actions/github-script@v7
with:
script: |
const results = {
backendBuild: '${{ needs.backend-build.result }}',
frontendBuild: '${{ needs.frontend-build.result }}',
backendUnit: '${{ needs.backend-unit-test.result }}',
backendApi: '${{ needs.backend-api-test.result }}',
frontendUnit: '${{ needs.frontend-unit-test.result }}',
stateMachine: '${{ needs.state-machine-test.result }}',
aiUnit: '${{ needs.ai-unit-test.result }}',
aiApi: '${{ needs.ai-api-test.result }}',
tenantAudit: '${{ needs.tenant-security-audit.result }}',
kafkaAudit: '${{ needs.kafka-event-audit.result }}',
depScan: '${{ needs.dependency-security-scan.result }}',
};
const icon = (r) => r === 'success' ? '✅' : r === 'failure' ? '❌' : '⏭️';
const allPassed = !Object.values(results).some(r => r === 'failure');
const body = [
`## ${allPassed ? '✅' : '❌'} Test Pipeline 质量门禁`,
'',
'| 检查项 | 状态 |',
'|--------|------|',
`| 后端构建 | ${icon(results.backendBuild)} |`,
`| 前端构建 | ${icon(results.frontendBuild)} |`,
`| 后端单元测试 | ${icon(results.backendUnit)} |`,
`| 后端 API 测试 | ${icon(results.backendApi)} |`,
`| 前端单元测试 | ${icon(results.frontendUnit)} |`,
`| 状态机测试 | ${icon(results.stateMachine)} |`,
`| AI 单元测试 | ${icon(results.aiUnit)} |`,
`| AI API 测试 | ${icon(results.aiApi)} |`,
`| 多租户审计 | ${icon(results.tenantAudit)} |`,
`| Kafka 审计 | ${icon(results.kafkaAudit)} |`,
`| 依赖扫描 | ${icon(results.depScan)} |`,
'',
allPassed ? '**所有门禁通过,可以合并!**' : '**门禁未通过,请修复问题后重新提交。**',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Test Pipeline 质量门禁')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
...
|
quality-gate
|
["backend-unit-test","backend-api-test ["backend-unit-test","backend-api-test","backend-build","frontend-unit-test","frontend-build","state-machine-test","ai-unit-test","ai-api-test","tenant-security-audit","kafka-event-audit","dependency-security-scan","governance-baseline"]...
|
["ubuntu-latest"]
|
12345
|
2
|
1775067283
|
1775068308
|
1775066751
|
1775068309
|
|
1
|
|
0
|
Edit
Delete
|