|
13775
|
9712
|
6
|
5
|
6794a93c73e1f0426557604cd3ba8f93a10e82f1
|
0
|
Kafka 事件一致性审计
|
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:
kafka-event-audit:
name: Kafka 事件一致性审计
runs-on: ubuntu-latest
if: github.event.inputs.run_security_audit != 'false'
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: 恢复依赖缓存
uses: actions/cache/restore@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
- name: 生成 Prisma Client
run: pnpm --filter juhi-api run db:generate
- name: 运行 Kafka 事件审计(阻塞性)
run: cd backend && npx tsx scripts/audit-kafka-events.ts --ci
- if: always()
name: 上传审计报告
uses: actions/upload-artifact@v4
with:
name: kafka-audit-report
path: backend/kafka-audit-report.json
retention-days: "30"
...
|
kafka-event-audit
|
["backend-lint"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774871766
|
1774870954
|
1774871766
|
|
0
|
|
0
|
Edit
Delete
|
|
13818
|
9718
|
6
|
5
|
8a7978e163a401654f636377fc9ca790391d8779
|
0
|
Kafka 事件一致性审计
|
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:
kafka-event-audit:
name: Kafka 事件一致性审计
runs-on: ubuntu-latest
if: github.event.inputs.run_security_audit != 'false'
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: 恢复依赖缓存
uses: actions/cache/restore@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
- name: 生成 Prisma Client
run: pnpm --filter juhi-api run db:generate
- name: 运行 Kafka 事件审计(阻塞性)
run: cd backend && npx tsx scripts/audit-kafka-events.ts --ci
- if: always()
name: 上传审计报告
uses: actions/upload-artifact@v4
with:
name: kafka-audit-report
path: backend/kafka-audit-report.json
retention-days: "30"
...
|
kafka-event-audit
|
["backend-lint"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774875573
|
1774871769
|
1774875573
|
|
0
|
|
0
|
Edit
Delete
|
|
13896
|
9738
|
6
|
5
|
1ce3f3ee5a8099af3c2b00d92ab83aa31d4d803a
|
0
|
Kafka 事件一致性审计
|
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:
kafka-event-audit:
name: Kafka 事件一致性审计
runs-on: ubuntu-latest
if: github.event.inputs.run_security_audit != 'false'
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: 恢复依赖缓存
uses: actions/cache/restore@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
- name: 生成 Prisma Client
run: pnpm --filter juhi-api run db:generate
- name: 运行 Kafka 事件审计(阻塞性)
run: cd backend && npx tsx scripts/audit-kafka-events.ts --ci
- if: always()
name: 上传审计报告
uses: actions/upload-artifact@v4
with:
name: kafka-audit-report
path: backend/kafka-audit-report.json
retention-days: "30"
...
|
kafka-event-audit
|
["backend-lint"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774876259
|
1774875576
|
1774876259
|
|
0
|
|
0
|
Edit
Delete
|
|
13939
|
9744
|
6
|
5
|
fb960500246fc412cf02a20cc0b316e9100eeb7f
|
0
|
Kafka 事件一致性审计
|
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:
kafka-event-audit:
name: Kafka 事件一致性审计
runs-on: ubuntu-latest
if: github.event.inputs.run_security_audit != 'false'
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: 恢复依赖缓存
uses: actions/cache/restore@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
- name: 生成 Prisma Client
run: pnpm --filter juhi-api run db:generate
- name: 运行 Kafka 事件审计(阻塞性)
run: cd backend && npx tsx scripts/audit-kafka-events.ts --ci
- if: always()
name: 上传审计报告
uses: actions/upload-artifact@v4
with:
name: kafka-audit-report
path: backend/kafka-audit-report.json
retention-days: "30"
...
|
kafka-event-audit
|
["backend-lint"]
|
["ubuntu-latest"]
|
11492
|
4
|
1774879326
|
1774879326
|
1774876262
|
1774879326
|
|
1
|
|
0
|
Edit
Delete
|
|
14192
|
9914
|
6
|
5
|
9901c454467cf62d4e127620f218a97bcca01629
|
0
|
Kafka 事件一致性审计
|
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:
kafka-event-audit:
name: Kafka 事件一致性审计
runs-on: ubuntu-latest
if: github.event.inputs.run_security_audit != 'false'
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: 恢复依赖缓存
uses: actions/cache/restore@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
- name: 生成 Prisma Client
run: pnpm --filter juhi-api run db:generate
- name: 运行 Kafka 事件审计(阻塞性)
run: cd backend && npx tsx scripts/audit-kafka-events.ts --ci
- if: always()
name: 上传审计报告
uses: actions/upload-artifact@v4
with:
name: kafka-audit-report
path: backend/kafka-audit-report.json
retention-days: "30"
...
|
kafka-event-audit
|
["backend-lint"]
|
["ubuntu-latest"]
|
11700
|
4
|
1774927322
|
1774927322
|
1774923480
|
1774927323
|
|
1
|
|
0
|
Edit
Delete
|
|
14296
|
9957
|
6
|
5
|
dffb3332733fb56fd51632938c4379422125381c
|
0
|
Kafka 事件一致性审计
|
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:
kafka-event-audit:
name: Kafka 事件一致性审计
runs-on: ubuntu-latest
if: github.event.inputs.run_security_audit != 'false'
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: 恢复依赖缓存
uses: actions/cache/restore@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
- name: 生成 Prisma Client
run: pnpm --filter juhi-api run db:generate
- name: 运行 Kafka 事件审计(阻塞性)
run: cd backend && npx tsx scripts/audit-kafka-events.ts --ci
- if: always()
name: 上传审计报告
uses: actions/upload-artifact@v4
with:
name: kafka-audit-report
path: backend/kafka-audit-report.json
retention-days: "30"
...
|
kafka-event-audit
|
["backend-lint"]
|
["ubuntu-latest"]
|
11775
|
4
|
1774936073
|
1774936074
|
1774934356
|
1774936074
|
|
1
|
|
0
|
Edit
Delete
|
|
14429
|
10019
|
6
|
5
|
8c225d73253fe95a23618816b2f7e6a03010cae4
|
0
|
Kafka 事件一致性审计
|
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:
kafka-event-audit:
name: Kafka 事件一致性审计
runs-on: ubuntu-latest
if: github.event.inputs.run_security_audit != 'false'
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: 恢复依赖缓存
uses: actions/cache/restore@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
- name: 生成 Prisma Client
run: pnpm --filter juhi-api run db:generate
- name: 运行 Kafka 事件审计(阻塞性)
run: cd backend && npx tsx scripts/audit-kafka-events.ts --ci
- if: always()
name: 上传审计报告
uses: actions/upload-artifact@v4
with:
name: kafka-audit-report
path: backend/kafka-audit-report.json
retention-days: "30"
...
|
kafka-event-audit
|
["backend-lint"]
|
["ubuntu-latest"]
|
11876
|
4
|
1774952034
|
1774952034
|
1774950060
|
1774952034
|
|
1
|
|
0
|
Edit
Delete
|
|
14491
|
10047
|
6
|
5
|
46635b50050ba09e31518824f56b1e2176e7b0b7
|
0
|
Kafka 事件一致性审计
|
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:
kafka-event-audit:
name: Kafka 事件一致性审计
runs-on: ubuntu-latest
if: github.event.inputs.run_security_audit != 'false'
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: 恢复依赖缓存
uses: actions/cache/restore@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
- name: 生成 Prisma Client
run: pnpm --filter juhi-api run db:generate
- name: 运行 Kafka 事件审计(阻塞性)
run: cd backend && npx tsx scripts/audit-kafka-events.ts --ci
- if: always()
name: 上传审计报告
uses: actions/upload-artifact@v4
with:
name: kafka-audit-report
path: backend/kafka-audit-report.json
retention-days: "30"
...
|
kafka-event-audit
|
["backend-lint"]
|
["ubuntu-latest"]
|
11931
|
4
|
1774960559
|
1774960559
|
1774957473
|
1774960560
|
|
1
|
|
0
|
Edit
Delete
|
|
14932
|
10420
|
6
|
5
|
7212eb23c82b2ecae9ea1f22fa928fc6382f842d
|
0
|
Kafka 事件一致性审计
|
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:
kafka-event-audit:
name: Kafka 事件一致性审计
runs-on: ubuntu-latest
if: github.event.inputs.run_security_audit != 'false'
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: 恢复依赖缓存
uses: actions/cache/restore@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
- name: 生成 Prisma Client
run: pnpm --filter juhi-api run db:generate
- name: 运行 Kafka 事件审计(阻塞性)
run: cd backend && npx tsx scripts/audit-kafka-events.ts --ci
- if: always()
name: 上传审计报告
uses: actions/upload-artifact@v4
with:
name: kafka-audit-report
path: backend/kafka-audit-report.json
retention-days: "30"
...
|
kafka-event-audit
|
["backend-lint"]
|
["ubuntu-latest"]
|
12337
|
4
|
1775067238
|
1775067238
|
1775066751
|
1775067238
|
|
1
|
|
0
|
Edit
Delete
|
|
15109
|
10529
|
6
|
5
|
624893ef324e57874ecb721dfd5539eb58d49b8e
|
0
|
Kafka 事件一致性审计
|
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:
kafka-event-audit:
name: Kafka 事件一致性审计
runs-on: ubuntu-latest
if: github.event.inputs.run_security_audit != 'false'
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: 恢复依赖缓存
uses: actions/cache/restore@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
- name: 生成 Prisma Client
run: pnpm --filter juhi-api run db:generate
- name: 运行 Kafka 事件审计(阻塞性)
run: cd backend && npx tsx scripts/audit-kafka-events.ts --ci
- if: always()
name: 上传审计报告
uses: actions/upload-artifact@v4
with:
name: kafka-audit-report
path: backend/kafka-audit-report.json
retention-days: "30"
...
|
kafka-event-audit
|
["backend-lint"]
|
["ubuntu-latest"]
|
12492
|
4
|
1775098539
|
1775098539
|
1775097115
|
1775098539
|
|
1
|
|
0
|
Edit
Delete
|
|
15462
|
10814
|
6
|
5
|
40dae5944f158653af8288a3f38b6c97e8ce9f06
|
0
|
Kafka 事件一致性审计
|
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:
kafka-event-audit:
name: Kafka 事件一致性审计
runs-on: ubuntu-latest
if: github.event.inputs.run_security_audit != 'false'
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: 恢复依赖缓存
uses: actions/cache/restore@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
- name: 生成 Prisma Client
run: pnpm --filter juhi-api run db:generate
- name: 运行 Kafka 事件审计(阻塞性)
run: cd backend && npx tsx scripts/audit-kafka-events.ts --ci
- if: always()
name: 上传审计报告
uses: actions/upload-artifact@v4
with:
name: kafka-audit-report
path: backend/kafka-audit-report.json
retention-days: "30"
...
|
kafka-event-audit
|
["backend-lint"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1775180539
|
1775180412
|
1775180539
|
|
0
|
|
0
|
Edit
Delete
|
|
15502
|
10817
|
6
|
5
|
9d69e1960ec649a49c0c6f307c0fc197f47ee4c4
|
0
|
Kafka 事件一致性审计
|
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:
kafka-event-audit:
name: Kafka 事件一致性审计
runs-on: ubuntu-latest
if: github.event.inputs.run_security_audit != 'false'
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: 恢复依赖缓存
uses: actions/cache/restore@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
- name: 生成 Prisma Client
run: pnpm --filter juhi-api run db:generate
- name: 运行 Kafka 事件审计(阻塞性)
run: cd backend && npx tsx scripts/audit-kafka-events.ts --ci
- if: always()
name: 上传审计报告
uses: actions/upload-artifact@v4
with:
name: kafka-audit-report
path: backend/kafka-audit-report.json
retention-days: "30"
...
|
kafka-event-audit
|
["backend-lint"]
|
["ubuntu-latest"]
|
12850
|
4
|
1775186055
|
1775186055
|
1775180541
|
1775186055
|
|
1
|
|
0
|
Edit
Delete
|
|
18411
|
13577
|
6
|
5
|
2e3188c85a6cfc38ac7d3643b1cbbfc2e3e850d0
|
0
|
Kafka 事件一致性审计
|
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:
kafka-event-audit:
name: Kafka 事件一致性审计
runs-on: ubuntu-latest
if: github.event.inputs.run_security_audit != 'false'
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: 恢复依赖缓存
uses: actions/cache/restore@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
- name: 生成 Prisma Client
run: pnpm --filter juhi-api run db:generate
- name: 运行 Kafka 事件审计(阻塞性)
run: cd backend && npx tsx scripts/audit-kafka-events.ts --ci
- if: always()
name: 上传审计报告
uses: actions/upload-artifact@v4
with:
name: kafka-audit-report
path: backend/kafka-audit-report.json
retention-days: "30"
...
|
kafka-event-audit
|
["backend-lint"]
|
["ubuntu-latest"]
|
15722
|
4
|
1776007307
|
1776007308
|
1776001252
|
1776007308
|
|
1
|
|
0
|
Edit
Delete
|
|
18515
|
13617
|
6
|
5
|
98cc8da660b8d4dba9887432490471d976c03f5f
|
0
|
Kafka 事件一致性审计
|
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:
kafka-event-audit:
name: Kafka 事件一致性审计
runs-on: ubuntu-latest
if: github.event.inputs.run_security_audit != 'false'
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: 恢复依赖缓存
uses: actions/cache/restore@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
- name: 生成 Prisma Client
run: pnpm --filter juhi-api run db:generate
- name: 运行 Kafka 事件审计(阻塞性)
run: cd backend && npx tsx scripts/audit-kafka-events.ts --ci
- if: always()
name: 上传审计报告
uses: actions/upload-artifact@v4
with:
name: kafka-audit-report
path: backend/kafka-audit-report.json
retention-days: "30"
...
|
kafka-event-audit
|
["backend-lint"]
|
["ubuntu-latest"]
|
15781
|
4
|
1776011860
|
1776011860
|
1776011087
|
1776011860
|
|
1
|
|
0
|
Edit
Delete
|
|
18789
|
13814
|
6
|
5
|
d2c68b13960de626f7a8d496bf1977d263eb7931
|
0
|
Kafka 事件一致性审计
|
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:
kafka-event-audit:
name: Kafka 事件一致性审计
runs-on: ubuntu-latest
if: github.event.inputs.run_security_audit != 'false'
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: 恢复依赖缓存
uses: actions/cache/restore@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
- name: 生成 Prisma Client
run: pnpm --filter juhi-api run db:generate
- name: 运行 Kafka 事件审计(阻塞性)
run: cd backend && npx tsx scripts/audit-kafka-events.ts --ci
- if: always()
name: 上传审计报告
uses: actions/upload-artifact@v4
with:
name: kafka-audit-report
path: backend/kafka-audit-report.json
retention-days: "30"
...
|
kafka-event-audit
|
["backend-lint"]
|
["ubuntu-latest"]
|
16027
|
4
|
1776066804
|
1776066804
|
1776066085
|
1776066804
|
|
1
|
|
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
|