|
8309
|
7003
|
6
|
5
|
01a8ea9191c28b210d2abb3db3cbc65db42fc801
|
0
|
前端代码检查
|
1
|
name: CI
"on":
push:
branches: name: CI
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
env:
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
frontend-lint:
name: 前端代码检查
runs-on: ubuntu-latest
if: needs.detect-changes.outputs.frontend == 'true'
steps:
- uses: actions/checkout@v4
- name: 安装 pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: 恢复依赖缓存
uses: actions/cache/restore@v4
with:
key: deps-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
path: |
node_modules
backend/node_modules
frontend/node_modules
mobile/node_modules
shared/node_modules
shared/dist
- name: ESLint 检查
run: pnpm --filter juhi-frontend run lint
- name: 数组守卫检查
run: pnpm --filter juhi-frontend run check:array-guard
- name: TypeScript 类型检查
run: pnpm --filter juhi-frontend run type-check
...
|
frontend-lint
|
["setup","detect-changes"]
|
["ubuntu-latest"]
|
7169
|
4
|
1773914182
|
1773914182
|
1773913344
|
1773914183
|
|
1
|
|
0
|
Edit
Delete
|
|
8308
|
7003
|
6
|
5
|
01a8ea9191c28b210d2abb3db3cbc65db42fc801
|
0
|
后端构建检查
|
0
|
name: CI
"on":
push:
branches: name: CI
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
env:
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
backend-build:
name: 后端构建检查
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 安装 pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: 恢复依赖缓存
uses: actions/cache/restore@v4
with:
key: deps-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
path: |
node_modules
backend/node_modules
frontend/node_modules
mobile/node_modules
shared/node_modules
shared/dist
- name: 生成 Prisma Client
run: pnpm --filter juhi-api run db:generate
- name: 构建
run: pnpm --filter juhi-api run build
- name: 验证构建产物
run: |
if [ ! -d "backend/dist" ]; then
echo "❌ 构建产物不存在"
exit 1
fi
echo "✅ 后端构建验证通过"
...
|
backend-build
|
["backend-lint"]
|
["ubuntu-latest"]
|
0
|
4
|
0
|
0
|
1773913344
|
1773914182
|
|
1
|
|
0
|
Edit
Delete
|
|
8307
|
7003
|
6
|
5
|
01a8ea9191c28b210d2abb3db3cbc65db42fc801
|
0
|
后端单元测试
|
0
|
name: CI
"on":
push:
branches: name: CI
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
env:
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
backend-test:
name: 后端单元测试
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 安装 pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: 恢复依赖缓存
uses: actions/cache/restore@v4
with:
key: deps-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
path: |
node_modules
backend/node_modules
frontend/node_modules
mobile/node_modules
shared/node_modules
shared/dist
- name: 生成 Prisma Client
run: pnpm --filter juhi-api run db:generate
- name: 运行单元测试
run: pnpm --filter juhi-api run test:ci
env:
DATABASE_URL: postgresql://test:test@localhost:5432/juhi_test
REDIS_URL: redis://localhost:6379
JWT_SECRET: test-secret-key
NODE_ENV: test
- name: 上传覆盖率报告
uses: codecov/codecov-action@v4
with:
fail_ci_if_error: "false"
files: backend/coverage/lcov.info
flags: backend
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_DB: juhi_test
POSTGRES_PASSWORD: test
POSTGRES_USER: test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
redis:
image: redis:7-alpine
ports:
- 6379:6379
options: --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5
...
|
backend-test
|
["backend-lint"]
|
["ubuntu-latest"]
|
0
|
4
|
0
|
0
|
1773913344
|
1773914182
|
|
1
|
|
0
|
Edit
Delete
|
|
8306
|
7003
|
6
|
5
|
01a8ea9191c28b210d2abb3db3cbc65db42fc801
|
0
|
后端代码检查
|
1
|
name: CI
"on":
push:
branches: name: CI
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
env:
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
backend-lint:
name: 后端代码检查
runs-on: ubuntu-latest
if: needs.detect-changes.outputs.backend == 'true'
steps:
- uses: actions/checkout@v4
- name: 安装 pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: 恢复依赖缓存
uses: actions/cache/restore@v4
with:
key: deps-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
path: |
node_modules
backend/node_modules
frontend/node_modules
mobile/node_modules
shared/node_modules
shared/dist
- name: 生成 Prisma Client
run: pnpm --filter juhi-api run db:generate
- name: ESLint 检查
run: pnpm --filter juhi-api run lint
- name: TypeScript 类型检查
run: pnpm --filter juhi-api run type-check
- name: 审计门禁基线采集(route/state/events/gate)
run: pnpm --filter juhi-api run audit:baseline:capture -- --skip-tenant --label ci-${{ github.run_id }}
- if: always()
name: "\U0001F4CA 上传审计基线快照"
uses: actions/upload-artifact@v4
with:
name: backend-audit-baseline
path: reports/audit-baseline/latest
retention-days: "30"
- if: always()
name: "\U0001F9FE 生成治理摘要"
run: |
mkdir -p reports/audit-baseline/latest
if [ -f reports/audit-baseline/latest/summary.json ]; then
pnpm --filter juhi-api run governance:summary -- \
--module workspace-baseline \
--stage CI \
--scope workspace \
--classification workspace-baseline \
--summary-json reports/audit-baseline/latest/summary.json \
--output reports/audit-baseline/latest/governance-summary.md
else
printf "### Governance 3.0 摘要\n\n- 模块: workspace-baseline\n- 阶段: CI\n- 范围: 工作区级\n- 分类: 工作区基线\n- 结论: 审计快照缺失,本次仅记录摘要生成失败,不替代原始门禁结果。\n" > reports/audit-baseline/latest/governance-summary.md
fi
- if: always()
name: "\U0001F4DD 写入审计摘要"
run: |
if [ -f reports/audit-baseline/latest/summary.md ]; then
cat reports/audit-baseline/latest/summary.md >> $GITHUB_STEP_SUMMARY
fi
if [ -f reports/audit-baseline/latest/governance-summary.md ]; then
echo "" >> $GITHUB_STEP_SUMMARY
cat reports/audit-baseline/latest/governance-summary.md >> $GITHUB_STEP_SUMMARY
fi
...
|
backend-lint
|
["setup","detect-changes"]
|
["ubuntu-latest"]
|
7168
|
4
|
1773914180
|
1773914180
|
1773913344
|
1773914180
|
|
1
|
|
0
|
Edit
Delete
|
|
8305
|
7003
|
6
|
5
|
01a8ea9191c28b210d2abb3db3cbc65db42fc801
|
0
|
共享包检查
|
1
|
name: CI
"on":
push:
branches: name: CI
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
env:
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
shared-check:
name: 共享包检查
runs-on: ubuntu-latest
if: needs.detect-changes.outputs.shared == 'true'
steps:
- uses: actions/checkout@v4
- name: 安装 pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: 恢复依赖缓存
uses: actions/cache/restore@v4
with:
key: deps-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
path: |
node_modules
backend/node_modules
frontend/node_modules
mobile/node_modules
shared/node_modules
shared/dist
- name: TypeScript 类型检查
run: pnpm --filter @juhi/shared run build
- name: 运行共享层单元测试
run: pnpm --filter @juhi/shared run test:coverage
- name: 上传共享层覆盖率报告
uses: codecov/codecov-action@v4
with:
fail_ci_if_error: "false"
files: shared/coverage/lcov.info
flags: shared
- name: 验证导出
run: |
cd shared
node -e "import('./dist/index.js').then(m => console.log('✅ 共享包导出验证通过'))"
...
|
shared-check
|
["setup","detect-changes"]
|
["ubuntu-latest"]
|
7167
|
4
|
1773914178
|
1773914178
|
1773913344
|
1773914178
|
|
1
|
|
0
|
Edit
Delete
|
|
8304
|
7003
|
6
|
5
|
01a8ea9191c28b210d2abb3db3cbc65db42fc801
|
0
|
安装依赖
|
1
|
name: CI
"on":
push:
branches: name: CI
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
env:
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
setup:
name: 安装依赖
runs-on: ubuntu-latest
steps:
- name: 检出代码
uses: actions/checkout@v4
- name: 安装 pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: pnpm install --frozen-lockfile
- name: 构建共享包
run: pnpm --filter @juhi/shared run build
- name: 缓存 node_modules
uses: actions/cache/save@v4
with:
key: deps-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
path: |
node_modules
backend/node_modules
frontend/node_modules
mobile/node_modules
shared/node_modules
shared/dist
e2e/node_modules
...
|
setup
|
null
|
["ubuntu-latest"]
|
7143
|
2
|
1773913839
|
1773913869
|
1773913344
|
1773913869
|
|
0
|
|
0
|
Edit
Delete
|
|
8303
|
7003
|
6
|
5
|
01a8ea9191c28b210d2abb3db3cbc65db42fc801
|
0
|
检测代码变更
|
1
|
name: CI
"on":
push:
branches: name: CI
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
env:
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
detect-changes:
name: 检测代码变更
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- id: filter
uses: dorny/paths-filter@v3
with:
filters: |
backend:
- 'backend/**'
- 'shared/**'
frontend:
- 'frontend/**'
- 'shared/**'
mobile:
- 'mobile/**'
- 'shared/**'
shared:
- 'shared/**'
workflows:
- '.github/workflows/**'
outputs:
backend: ${{ steps.filter.outputs.backend }}
frontend: ${{ steps.filter.outputs.frontend }}
mobile: ${{ steps.filter.outputs.mobile }}
shared: ${{ steps.filter.outputs.shared }}
workflows: ${{ steps.filter.outputs.workflows }}
...
|
detect-changes
|
null
|
["ubuntu-latest"]
|
7142
|
2
|
1773913808
|
1773913838
|
1773913344
|
1773913839
|
|
0
|
|
0
|
Edit
Delete
|
|
31480
|
23602
|
76
|
5
|
019f721377c4a8970dfc4064886129b1cbcbd089
|
0
|
Runtime and UI acceptance
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
runtime-acceptance:
name: Runtime and UI acceptance
runs-on: ubuntu-latest
env:
DATABASE_URL: postgresql://postgres:postgres@127.0.0.1:5432/digital_employee_os_ci?schema=public
REDIS_URL: redis://127.0.0.1:6379
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
fetch-depth: "0"
- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020
with:
node-version: 22.23.2
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@9.15.9 --activate
- name: Install dependencies
run: pnpm install --frozen-lockfile --ignore-scripts
- name: Rebuild approved dependency scripts
run: pnpm dependencies:rebuild-approved
- name: Generate Prisma clients
run: pnpm prisma:generate
- name: Run real DB and Redis acceptance
run: pnpm check:runtime
- name: Install Playwright browser
run: pnpm --filter web exec playwright install --with-deps chromium
- name: Run UI acceptance
run: pnpm check:ui
env:
# O1:runtime 验收的遗留 delayed job 不得漏进 UI 阶段共享的 BullMQ 队列,
# Redis 逻辑库隔离(镜像本地 /2 vs /3 约定)。
REDIS_URL: redis://127.0.0.1:6379/1
services:
postgres:
image: postgres:16-alpine@sha256:cf78e76683b9ca8c5733cbbdce6c9262b45b6767934dd0a95e671f9a0fc20685
env:
POSTGRES_DB: digital_employee_os_ci
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
ports:
- 5432:5432
options: --health-cmd "pg_isready -U postgres -d digital_employee_os_ci" --health-interval 5s --health-timeout 5s --health-retries 20
redis:
image: redis:7-alpine@sha256:ff02b58f971e7d7d156a1267e283fcbbeee91773b6aa36c49dac28ecfe28eadf
ports:
- 6379:6379
options: --health-cmd "redis-cli ping" --health-interval 5s --health-timeout 5s --health-retries 20
permissions:
contents: read
...
|
runtime-acceptance
|
["static-governance"]
|
["ubuntu-latest"]
|
27406
|
2
|
1788362647
|
1788362702
|
1788361593
|
1788362702
|
|
1
|
|
0
|
Edit
Delete
|
|
31479
|
23602
|
76
|
5
|
019f721377c4a8970dfc4064886129b1cbcbd089
|
0
|
Third-party image scan (redis:7-alpine@sha256:ff02 Third-party image scan (redis:7-alpine@sha256:ff02b58f971e7d7d156a1267e283fcbbeee91773b6aa36c49dac28ecfe28eadf)...
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
third-party-image-vulnerability-scan:
name: Third-party image scan (redis:7-alpine@sha256:ff02b58f971e7d7d156a1267e283fcbbeee91773b6aa36c49dac28ecfe28eadf)
runs-on: ubuntu-latest
steps:
- name: Reject third-party HIGH or CRITICAL vulnerabilities
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25
with:
exit-code: "1"
format: table
ignore-unfixed: "false"
image-ref: ${{ matrix.image }}
scanners: vuln
severity: CRITICAL,HIGH
trivy-version: v0.74.0
vuln-type: os,library
strategy:
fail-fast: "false"
matrix:
image:
- redis:7-alpine@sha256:ff02b58f971e7d7d156a1267e283fcbbeee91773b6aa36c49dac28ecfe28eadf
permissions:
contents: read
...
|
third-party-image-vulnerability-scan
|
["static-governance"]
|
["ubuntu-latest"]
|
27405
|
2
|
1788362601
|
1788362646
|
1788361593
|
1788362647
|
|
1
|
|
0
|
Edit
Delete
|
|
31478
|
23602
|
76
|
5
|
019f721377c4a8970dfc4064886129b1cbcbd089
|
0
|
Third-party image scan (prom/prometheus:v3.14.0@sh Third-party image scan (prom/prometheus:v3.14.0@sha256:5ce7540c3c00ef4ab0c9d2c995c6a5b9c421f44b4a115d97a2c7af3b1c21cbb0)...
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
third-party-image-vulnerability-scan:
name: Third-party image scan (prom/prometheus:v3.14.0@sha256:5ce7540c3c00ef4ab0c9d2c995c6a5b9c421f44b4a115d97a2c7af3b1c21cbb0)
runs-on: ubuntu-latest
steps:
- name: Reject third-party HIGH or CRITICAL vulnerabilities
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25
with:
exit-code: "1"
format: table
ignore-unfixed: "false"
image-ref: ${{ matrix.image }}
scanners: vuln
severity: CRITICAL,HIGH
trivy-version: v0.74.0
vuln-type: os,library
strategy:
fail-fast: "false"
matrix:
image:
- prom/prometheus:v3.14.0@sha256:5ce7540c3c00ef4ab0c9d2c995c6a5b9c421f44b4a115d97a2c7af3b1c21cbb0
permissions:
contents: read
...
|
third-party-image-vulnerability-scan
|
["static-governance"]
|
["ubuntu-latest"]
|
27404
|
2
|
1788362548
|
1788362601
|
1788361593
|
1788362601
|
|
1
|
|
0
|
Edit
Delete
|
|
31477
|
23602
|
76
|
5
|
019f721377c4a8970dfc4064886129b1cbcbd089
|
0
|
Application image scan (web)
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
application-image-vulnerability-scan:
name: Application image scan (web)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
fetch-depth: "0"
- name: Build immutable application target
run: docker build --target "${{ matrix.target }}" --tag "${{ matrix.image }}" --file deploy/production/Dockerfile .
env:
DOCKER_BUILDKIT: "1"
- if: matrix.target == 'ops-postgres'
name: Verify hardened PostgreSQL runtime
run: node scripts/check-postgres-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-alertmanager'
name: Verify reduced Alertmanager runtime
run: node scripts/check-alertmanager-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-loki'
name: Verify rebuilt Loki runtime
run: node scripts/check-loki-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-tempo'
name: Verify rebuilt Tempo runtime
run: node scripts/check-tempo-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-otel-collector'
name: Verify minimal OTel Collector runtime
run: node scripts/check-otel-collector-image.mjs "${{ matrix.image }}"
- name: Reject application HIGH or CRITICAL vulnerabilities
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25
with:
exit-code: "1"
format: table
ignore-unfixed: "false"
image-ref: ${{ matrix.image }}
scanners: vuln
severity: CRITICAL,HIGH
trivy-version: v0.74.0
vuln-type: os,library
strategy:
fail-fast: "false"
matrix:
image:
- deos-scan-web:ci
target:
- web
permissions:
contents: read
...
|
application-image-vulnerability-scan
|
["static-governance"]
|
["ubuntu-latest"]
|
27403
|
2
|
1788362531
|
1788362547
|
1788361593
|
1788362548
|
|
1
|
|
0
|
Edit
Delete
|
|
31476
|
23602
|
76
|
5
|
019f721377c4a8970dfc4064886129b1cbcbd089
|
0
|
Application image scan (ops-trace-storage)
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
application-image-vulnerability-scan:
name: Application image scan (ops-trace-storage)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
fetch-depth: "0"
- name: Build immutable application target
run: docker build --target "${{ matrix.target }}" --tag "${{ matrix.image }}" --file deploy/production/Dockerfile .
env:
DOCKER_BUILDKIT: "1"
- if: matrix.target == 'ops-postgres'
name: Verify hardened PostgreSQL runtime
run: node scripts/check-postgres-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-alertmanager'
name: Verify reduced Alertmanager runtime
run: node scripts/check-alertmanager-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-loki'
name: Verify rebuilt Loki runtime
run: node scripts/check-loki-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-tempo'
name: Verify rebuilt Tempo runtime
run: node scripts/check-tempo-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-otel-collector'
name: Verify minimal OTel Collector runtime
run: node scripts/check-otel-collector-image.mjs "${{ matrix.image }}"
- name: Reject application HIGH or CRITICAL vulnerabilities
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25
with:
exit-code: "1"
format: table
ignore-unfixed: "false"
image-ref: ${{ matrix.image }}
scanners: vuln
severity: CRITICAL,HIGH
trivy-version: v0.74.0
vuln-type: os,library
strategy:
fail-fast: "false"
matrix:
image:
- deos-scan-ops-trace-storage:ci
target:
- ops-trace-storage
permissions:
contents: read
...
|
application-image-vulnerability-scan
|
["static-governance"]
|
["ubuntu-latest"]
|
27402
|
2
|
1788362455
|
1788362531
|
1788361593
|
1788362531
|
|
1
|
|
0
|
Edit
Delete
|
|
31475
|
23602
|
76
|
5
|
019f721377c4a8970dfc4064886129b1cbcbd089
|
0
|
Application image scan (ops-tempo)
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
application-image-vulnerability-scan:
name: Application image scan (ops-tempo)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
fetch-depth: "0"
- name: Build immutable application target
run: docker build --target "${{ matrix.target }}" --tag "${{ matrix.image }}" --file deploy/production/Dockerfile .
env:
DOCKER_BUILDKIT: "1"
- if: matrix.target == 'ops-postgres'
name: Verify hardened PostgreSQL runtime
run: node scripts/check-postgres-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-alertmanager'
name: Verify reduced Alertmanager runtime
run: node scripts/check-alertmanager-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-loki'
name: Verify rebuilt Loki runtime
run: node scripts/check-loki-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-tempo'
name: Verify rebuilt Tempo runtime
run: node scripts/check-tempo-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-otel-collector'
name: Verify minimal OTel Collector runtime
run: node scripts/check-otel-collector-image.mjs "${{ matrix.image }}"
- name: Reject application HIGH or CRITICAL vulnerabilities
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25
with:
exit-code: "1"
format: table
ignore-unfixed: "false"
image-ref: ${{ matrix.image }}
scanners: vuln
severity: CRITICAL,HIGH
trivy-version: v0.74.0
vuln-type: os,library
strategy:
fail-fast: "false"
matrix:
image:
- deos-scan-ops-tempo:ci
target:
- ops-tempo
permissions:
contents: read
...
|
application-image-vulnerability-scan
|
["static-governance"]
|
["ubuntu-latest"]
|
27401
|
2
|
1788362439
|
1788362455
|
1788361593
|
1788362455
|
|
1
|
|
0
|
Edit
Delete
|
|
31474
|
23602
|
76
|
5
|
019f721377c4a8970dfc4064886129b1cbcbd089
|
0
|
Application image scan (ops-postgres)
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
application-image-vulnerability-scan:
name: Application image scan (ops-postgres)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
fetch-depth: "0"
- name: Build immutable application target
run: docker build --target "${{ matrix.target }}" --tag "${{ matrix.image }}" --file deploy/production/Dockerfile .
env:
DOCKER_BUILDKIT: "1"
- if: matrix.target == 'ops-postgres'
name: Verify hardened PostgreSQL runtime
run: node scripts/check-postgres-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-alertmanager'
name: Verify reduced Alertmanager runtime
run: node scripts/check-alertmanager-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-loki'
name: Verify rebuilt Loki runtime
run: node scripts/check-loki-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-tempo'
name: Verify rebuilt Tempo runtime
run: node scripts/check-tempo-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-otel-collector'
name: Verify minimal OTel Collector runtime
run: node scripts/check-otel-collector-image.mjs "${{ matrix.image }}"
- name: Reject application HIGH or CRITICAL vulnerabilities
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25
with:
exit-code: "1"
format: table
ignore-unfixed: "false"
image-ref: ${{ matrix.image }}
scanners: vuln
severity: CRITICAL,HIGH
trivy-version: v0.74.0
vuln-type: os,library
strategy:
fail-fast: "false"
matrix:
image:
- deos-scan-ops-postgres:ci
target:
- ops-postgres
permissions:
contents: read
...
|
application-image-vulnerability-scan
|
["static-governance"]
|
["ubuntu-latest"]
|
27400
|
2
|
1788362392
|
1788362438
|
1788361593
|
1788362439
|
|
1
|
|
0
|
Edit
Delete
|
|
31473
|
23602
|
76
|
5
|
019f721377c4a8970dfc4064886129b1cbcbd089
|
0
|
Application image scan (ops-pager)
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
application-image-vulnerability-scan:
name: Application image scan (ops-pager)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
fetch-depth: "0"
- name: Build immutable application target
run: docker build --target "${{ matrix.target }}" --tag "${{ matrix.image }}" --file deploy/production/Dockerfile .
env:
DOCKER_BUILDKIT: "1"
- if: matrix.target == 'ops-postgres'
name: Verify hardened PostgreSQL runtime
run: node scripts/check-postgres-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-alertmanager'
name: Verify reduced Alertmanager runtime
run: node scripts/check-alertmanager-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-loki'
name: Verify rebuilt Loki runtime
run: node scripts/check-loki-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-tempo'
name: Verify rebuilt Tempo runtime
run: node scripts/check-tempo-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-otel-collector'
name: Verify minimal OTel Collector runtime
run: node scripts/check-otel-collector-image.mjs "${{ matrix.image }}"
- name: Reject application HIGH or CRITICAL vulnerabilities
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25
with:
exit-code: "1"
format: table
ignore-unfixed: "false"
image-ref: ${{ matrix.image }}
scanners: vuln
severity: CRITICAL,HIGH
trivy-version: v0.74.0
vuln-type: os,library
strategy:
fail-fast: "false"
matrix:
image:
- deos-scan-ops-pager:ci
target:
- ops-pager
permissions:
contents: read
...
|
application-image-vulnerability-scan
|
["static-governance"]
|
["ubuntu-latest"]
|
27399
|
2
|
1788362312
|
1788362392
|
1788361593
|
1788362392
|
|
1
|
|
0
|
Edit
Delete
|
|
31472
|
23602
|
76
|
5
|
019f721377c4a8970dfc4064886129b1cbcbd089
|
0
|
Application image scan (ops-otel-collector)
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
application-image-vulnerability-scan:
name: Application image scan (ops-otel-collector)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
fetch-depth: "0"
- name: Build immutable application target
run: docker build --target "${{ matrix.target }}" --tag "${{ matrix.image }}" --file deploy/production/Dockerfile .
env:
DOCKER_BUILDKIT: "1"
- if: matrix.target == 'ops-postgres'
name: Verify hardened PostgreSQL runtime
run: node scripts/check-postgres-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-alertmanager'
name: Verify reduced Alertmanager runtime
run: node scripts/check-alertmanager-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-loki'
name: Verify rebuilt Loki runtime
run: node scripts/check-loki-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-tempo'
name: Verify rebuilt Tempo runtime
run: node scripts/check-tempo-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-otel-collector'
name: Verify minimal OTel Collector runtime
run: node scripts/check-otel-collector-image.mjs "${{ matrix.image }}"
- name: Reject application HIGH or CRITICAL vulnerabilities
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25
with:
exit-code: "1"
format: table
ignore-unfixed: "false"
image-ref: ${{ matrix.image }}
scanners: vuln
severity: CRITICAL,HIGH
trivy-version: v0.74.0
vuln-type: os,library
strategy:
fail-fast: "false"
matrix:
image:
- deos-scan-ops-otel-collector:ci
target:
- ops-otel-collector
permissions:
contents: read
...
|
application-image-vulnerability-scan
|
["static-governance"]
|
["ubuntu-latest"]
|
27398
|
2
|
1788362235
|
1788362312
|
1788361593
|
1788362312
|
|
1
|
|
0
|
Edit
Delete
|
|
31471
|
23602
|
76
|
5
|
019f721377c4a8970dfc4064886129b1cbcbd089
|
0
|
Application image scan (ops-loki)
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
application-image-vulnerability-scan:
name: Application image scan (ops-loki)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
fetch-depth: "0"
- name: Build immutable application target
run: docker build --target "${{ matrix.target }}" --tag "${{ matrix.image }}" --file deploy/production/Dockerfile .
env:
DOCKER_BUILDKIT: "1"
- if: matrix.target == 'ops-postgres'
name: Verify hardened PostgreSQL runtime
run: node scripts/check-postgres-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-alertmanager'
name: Verify reduced Alertmanager runtime
run: node scripts/check-alertmanager-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-loki'
name: Verify rebuilt Loki runtime
run: node scripts/check-loki-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-tempo'
name: Verify rebuilt Tempo runtime
run: node scripts/check-tempo-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-otel-collector'
name: Verify minimal OTel Collector runtime
run: node scripts/check-otel-collector-image.mjs "${{ matrix.image }}"
- name: Reject application HIGH or CRITICAL vulnerabilities
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25
with:
exit-code: "1"
format: table
ignore-unfixed: "false"
image-ref: ${{ matrix.image }}
scanners: vuln
severity: CRITICAL,HIGH
trivy-version: v0.74.0
vuln-type: os,library
strategy:
fail-fast: "false"
matrix:
image:
- deos-scan-ops-loki:ci
target:
- ops-loki
permissions:
contents: read
...
|
application-image-vulnerability-scan
|
["static-governance"]
|
["ubuntu-latest"]
|
27397
|
2
|
1788362158
|
1788362235
|
1788361593
|
1788362235
|
|
1
|
|
0
|
Edit
Delete
|
|
31470
|
23602
|
76
|
5
|
019f721377c4a8970dfc4064886129b1cbcbd089
|
0
|
Application image scan (ops-gateway)
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
application-image-vulnerability-scan:
name: Application image scan (ops-gateway)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
fetch-depth: "0"
- name: Build immutable application target
run: docker build --target "${{ matrix.target }}" --tag "${{ matrix.image }}" --file deploy/production/Dockerfile .
env:
DOCKER_BUILDKIT: "1"
- if: matrix.target == 'ops-postgres'
name: Verify hardened PostgreSQL runtime
run: node scripts/check-postgres-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-alertmanager'
name: Verify reduced Alertmanager runtime
run: node scripts/check-alertmanager-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-loki'
name: Verify rebuilt Loki runtime
run: node scripts/check-loki-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-tempo'
name: Verify rebuilt Tempo runtime
run: node scripts/check-tempo-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-otel-collector'
name: Verify minimal OTel Collector runtime
run: node scripts/check-otel-collector-image.mjs "${{ matrix.image }}"
- name: Reject application HIGH or CRITICAL vulnerabilities
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25
with:
exit-code: "1"
format: table
ignore-unfixed: "false"
image-ref: ${{ matrix.image }}
scanners: vuln
severity: CRITICAL,HIGH
trivy-version: v0.74.0
vuln-type: os,library
strategy:
fail-fast: "false"
matrix:
image:
- deos-scan-ops-gateway:ci
target:
- ops-gateway
permissions:
contents: read
...
|
application-image-vulnerability-scan
|
["static-governance"]
|
["ubuntu-latest"]
|
27396
|
2
|
1788362081
|
1788362158
|
1788361593
|
1788362158
|
|
1
|
|
0
|
Edit
Delete
|
|
31469
|
23602
|
76
|
5
|
019f721377c4a8970dfc4064886129b1cbcbd089
|
0
|
Application image scan (ops-alertmanager)
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
application-image-vulnerability-scan:
name: Application image scan (ops-alertmanager)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
fetch-depth: "0"
- name: Build immutable application target
run: docker build --target "${{ matrix.target }}" --tag "${{ matrix.image }}" --file deploy/production/Dockerfile .
env:
DOCKER_BUILDKIT: "1"
- if: matrix.target == 'ops-postgres'
name: Verify hardened PostgreSQL runtime
run: node scripts/check-postgres-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-alertmanager'
name: Verify reduced Alertmanager runtime
run: node scripts/check-alertmanager-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-loki'
name: Verify rebuilt Loki runtime
run: node scripts/check-loki-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-tempo'
name: Verify rebuilt Tempo runtime
run: node scripts/check-tempo-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-otel-collector'
name: Verify minimal OTel Collector runtime
run: node scripts/check-otel-collector-image.mjs "${{ matrix.image }}"
- name: Reject application HIGH or CRITICAL vulnerabilities
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25
with:
exit-code: "1"
format: table
ignore-unfixed: "false"
image-ref: ${{ matrix.image }}
scanners: vuln
severity: CRITICAL,HIGH
trivy-version: v0.74.0
vuln-type: os,library
strategy:
fail-fast: "false"
matrix:
image:
- deos-scan-ops-alertmanager:ci
target:
- ops-alertmanager
permissions:
contents: read
...
|
application-image-vulnerability-scan
|
["static-governance"]
|
["ubuntu-latest"]
|
27395
|
2
|
1788362004
|
1788362081
|
1788361593
|
1788362081
|
|
1
|
|
0
|
Edit
Delete
|
|
31468
|
23602
|
76
|
5
|
019f721377c4a8970dfc4064886129b1cbcbd089
|
0
|
Application image scan (api-nestjs)
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
application-image-vulnerability-scan:
name: Application image scan (api-nestjs)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
fetch-depth: "0"
- name: Build immutable application target
run: docker build --target "${{ matrix.target }}" --tag "${{ matrix.image }}" --file deploy/production/Dockerfile .
env:
DOCKER_BUILDKIT: "1"
- if: matrix.target == 'ops-postgres'
name: Verify hardened PostgreSQL runtime
run: node scripts/check-postgres-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-alertmanager'
name: Verify reduced Alertmanager runtime
run: node scripts/check-alertmanager-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-loki'
name: Verify rebuilt Loki runtime
run: node scripts/check-loki-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-tempo'
name: Verify rebuilt Tempo runtime
run: node scripts/check-tempo-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-otel-collector'
name: Verify minimal OTel Collector runtime
run: node scripts/check-otel-collector-image.mjs "${{ matrix.image }}"
- name: Reject application HIGH or CRITICAL vulnerabilities
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25
with:
exit-code: "1"
format: table
ignore-unfixed: "false"
image-ref: ${{ matrix.image }}
scanners: vuln
severity: CRITICAL,HIGH
trivy-version: v0.74.0
vuln-type: os,library
strategy:
fail-fast: "false"
matrix:
image:
- deos-scan-api-nestjs:ci
target:
- api-nestjs
permissions:
contents: read
...
|
application-image-vulnerability-scan
|
["static-governance"]
|
["ubuntu-latest"]
|
27394
|
2
|
1788361928
|
1788362004
|
1788361593
|
1788362004
|
|
1
|
|
0
|
Edit
Delete
|
|
31467
|
23602
|
76
|
5
|
019f721377c4a8970dfc4064886129b1cbcbd089
|
0
|
Application image scan (api-fastify)
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
application-image-vulnerability-scan:
name: Application image scan (api-fastify)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
fetch-depth: "0"
- name: Build immutable application target
run: docker build --target "${{ matrix.target }}" --tag "${{ matrix.image }}" --file deploy/production/Dockerfile .
env:
DOCKER_BUILDKIT: "1"
- if: matrix.target == 'ops-postgres'
name: Verify hardened PostgreSQL runtime
run: node scripts/check-postgres-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-alertmanager'
name: Verify reduced Alertmanager runtime
run: node scripts/check-alertmanager-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-loki'
name: Verify rebuilt Loki runtime
run: node scripts/check-loki-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-tempo'
name: Verify rebuilt Tempo runtime
run: node scripts/check-tempo-image.mjs "${{ matrix.image }}"
- if: matrix.target == 'ops-otel-collector'
name: Verify minimal OTel Collector runtime
run: node scripts/check-otel-collector-image.mjs "${{ matrix.image }}"
- name: Reject application HIGH or CRITICAL vulnerabilities
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25
with:
exit-code: "1"
format: table
ignore-unfixed: "false"
image-ref: ${{ matrix.image }}
scanners: vuln
severity: CRITICAL,HIGH
trivy-version: v0.74.0
vuln-type: os,library
strategy:
fail-fast: "false"
matrix:
image:
- deos-scan-api-fastify:ci
target:
- api-fastify
permissions:
contents: read
...
|
application-image-vulnerability-scan
|
["static-governance"]
|
["ubuntu-latest"]
|
27393
|
2
|
1788361842
|
1788361928
|
1788361593
|
1788361928
|
|
1
|
|
0
|
Edit
Delete
|
|
31466
|
23602
|
76
|
5
|
019f721377c4a8970dfc4064886129b1cbcbd089
|
0
|
Static governance
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
static-governance:
name: Static governance
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
fetch-depth: "0"
- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020
with:
node-version: 22.23.2
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@9.15.9 --activate
- name: Install dependencies
run: pnpm install --frozen-lockfile --ignore-scripts
- name: Rebuild approved dependency scripts
run: pnpm dependencies:rebuild-approved
- name: Audit production dependencies
run: pnpm audit --prod --audit-level high
- name: Generate Prisma clients
run: pnpm prisma:generate
- name: Run static governance gate
run: pnpm check
permissions:
contents: read
...
|
static-governance
|
null
|
["ubuntu-latest"]
|
27392
|
1
|
1788361595
|
1788361839
|
1788361593
|
1788361839
|
|
0
|
|
0
|
Edit
Delete
|
|
37449
|
25276
|
116
|
5
|
019cb5aac97b29f5eeab6d5e9560ed1cb7ed6a34
|
0
|
Release candidate verification + manifest
|
1
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
candidate:
name: Release candidate verification + manifest
runs-on: ubuntu-latest
if: always()
steps:
- uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: actions/setup-node@v4
with:
node-version: "20"
- name: Download static evidence
uses: actions/download-artifact@v3
with:
name: platform-static-${{ env.CANDIDATE_TAG }}
path: candidate/static
continue-on-error: true
- name: Download runtime evidence
uses: actions/download-artifact@v3
with:
name: platform-runtime-${{ env.CANDIDATE_TAG }}
path: candidate/runtime/runtime/reports
continue-on-error: true
- name: Download identity evidence
uses: actions/download-artifact@v3
with:
name: platform-identity-${{ env.CANDIDATE_TAG }}
path: candidate/identity/identity/reports
continue-on-error: true
- name: Download port-conformance evidence
uses: actions/download-artifact@v3
with:
name: platform-port-conformance-${{ env.CANDIDATE_TAG }}
path: candidate/port-conformance/reports
continue-on-error: true
- id: verify
name: Verify candidate (per-report sourceSha / dirty / status / digest; missing → ineligible)
run: node governance/verify-candidate.mjs --candidate candidate --sha "${{ github.sha }}" --run-id "${{ github.run_id }}" --attempt "${{ github.run_attempt }}" --out reports/release-candidate.latest.json
continue-on-error: true
- name: Download image and full SBOM evidence for the same candidate
uses: actions/download-artifact@v3
with:
name: platform-image-${{ env.CANDIDATE_TAG }}
path: reports
- name: Release Manifest (known facts, status partial until all deliverables exist)
run: node governance/release-manifest.mjs
- if: always()
name: Upload candidate evidence
uses: actions/upload-artifact@v3
with:
if-no-files-found: error
name: platform-candidate-${{ env.CANDIDATE_TAG }}
path: |
reports/release-candidate.latest.json
reports/release-manifest.latest.json
retention-days: "30"
- if: always()
name: Propagate upstream results and candidate eligibility
run: |
echo "public-static=${{ needs.public-static.result }} static=${{ needs.static.result }} runtime=${{ needs.runtime.result }} identity=${{ needs.identity.result }} verify=${{ steps.verify.outcome }}"
test "${{ needs.public-static.result }}" = "success"
test "${{ needs.static.result }}" = "success"
test "${{ needs.unit.result }}" = "success"
test "${{ needs.port-conformance.result }}" = "success"
test "${{ needs.runtime.result }}" = "success"
test "${{ needs.identity.result }}" = "success"
test "${{ needs.image.result }}" = "success"
test "${{ steps.verify.outcome }}" = "success"
timeout-minutes: "10"
permissions:
contents: read
...
|
candidate
|
["public-static","static","uni ["public-static","static","unit","port-conformance","runtime","identity","image"]...
|
["ubuntu-latest"]
|
31506
|
2
|
1791590908
|
1791590922
|
1791590790
|
1791590922
|
|
1
|
|
0
|
Edit
Delete
|
|
37448
|
25276
|
116
|
5
|
019cb5aac97b29f5eeab6d5e9560ed1cb7ed6a34
|
0
|
Runtime image build + SBOM (+ cosign when a key is Runtime image build + SBOM (+ cosign when a key is provided)...
|
1
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
image:
name: Runtime image build + SBOM (+ cosign when a key is provided)
runs-on: ubuntu-latest
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: actions/setup-node@v4
with:
node-version: "20"
- name: Private registry auth (temporary userconfig)
uses: ./.github/actions/private-npm
with:
token: ${{ secrets.GITEA_NPM_TOKEN }}
- name: Resolve npmrc for BuildKit secret (never printed)
run: |
cfg="${RUNNER_TEMP}/platform-npmrc-resolved"
umask 077
printf '@juhai:registry=https://gitea.g-hi.com/api/packages/luoanwu/npm/\n//gitea.g-hi.com/api/packages/luoanwu/npm/:_authToken=%s\n' "${GITEA_NPM_TOKEN}" > "${cfg}"
echo "PLATFORM_NPMRC=${cfg}" >> "${GITHUB_ENV}"
- name: Build runtime image from git archive HEAD:runtime (reports/image-digest.json)
run: node governance/build-image.mjs --context head --npmrc "${PLATFORM_NPMRC}"
- name: Install syft (pinned) and generate SPDX SBOM
run: |
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b "${RUNNER_TEMP}/bin" v1.20.0
PATH="${RUNNER_TEMP}/bin:${PATH}" node governance/sbom.mjs
- name: Install cosign (pinned)
uses: sigstore/cosign-installer@v3
with:
cosign-release: v2.4.1
- name: Sign image when COSIGN_PRIVATE_KEY is provided (otherwise explicit skip)
run: |
if [ -n "${COSIGN_PRIVATE_KEY}" ]; then
umask 077; printf '%s' "${COSIGN_PRIVATE_KEY}" > "${RUNNER_TEMP}/cosign.key"
COSIGN_KEY="${RUNNER_TEMP}/cosign.key" node governance/sign-image.mjs
else
node governance/sign-image.mjs
fi
env:
COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }}
COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}
- if: always()
name: Upload image evidence
uses: actions/upload-artifact@v3
with:
if-no-files-found: warn
name: platform-image-${{ env.CANDIDATE_TAG }}
path: |
reports/image-digest.json
reports/sbom.spdx.json
reports/sbom.latest.json
reports/signature.json
retention-days: "30"
timeout-minutes: "40"
permissions:
contents: read
...
|
image
|
["static"]
|
["ubuntu-latest"]
|
31503
|
4
|
1791590858
|
1791590858
|
1791590790
|
1791590859
|
|
1
|
|
0
|
Edit
Delete
|
|
37447
|
25276
|
116
|
5
|
019cb5aac97b29f5eeab6d5e9560ed1cb7ed6a34
|
0
|
M1 identity transitional workspace (IdP static → E M1 identity transitional workspace (IdP static → E2 → governance)...
|
1
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
identity:
name: M1 identity transitional workspace (IdP static → E2 → governance)
runs-on: ubuntu-latest
env:
# 库名前缀由 identity/package.json name 派生(enterprise_idp*);Redis 必须 db 0(老框架 C22)
DATABASE_URL: postgresql://postgres:postgres@127.0.0.1:5432/enterprise_idp_ci?schema=public
REDIS_URL: redis://127.0.0.1:6379/0
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: actions/setup-node@v4
with:
cache: pnpm
cache-dependency-path: identity/pnpm-lock.yaml
node-version: "20"
- name: Private registry auth (temporary userconfig; identity 目前无私包依赖,保持同一配置步骤以便后续 pin)
uses: ./.github/actions/private-npm
with:
token: ${{ secrets.GITEA_NPM_TOKEN }}
- name: Install identity workspace (frozen lockfile)
run: pnpm --dir identity install --frozen-lockfile
- name: Generate Prisma clients
run: pnpm --dir identity prisma:generate
- name: IdP static sub-checks (independent of runtime / UI reports)
run: pnpm identity:check:static
- name: IdP real DB acceptance (255 tests, serialized)
run: pnpm identity:check:runtime
- name: Install Playwright browser
run: pnpm --dir identity --filter web exec playwright install --with-deps chromium
- name: IdP UI acceptance (12 cases)
run: pnpm identity:check:ui
- name: IdP final governance aggregation (same checkout, fresh runtime / UI reports)
run: pnpm identity:check:governance
- if: always()
name: Upload identity evidence
uses: actions/upload-artifact@v3
with:
if-no-files-found: warn
name: platform-identity-${{ env.CANDIDATE_TAG }}
path: identity/reports/*.latest.json
retention-days: "30"
timeout-minutes: "50"
services:
postgres:
image: postgres:16
env:
POSTGRES_DB: enterprise_idp_ci
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
ports:
- 5432:5432
options: --health-cmd "pg_isready -U postgres -d enterprise_idp_ci" --health-interval 5s --health-timeout 5s --health-retries 20
redis:
image: redis:7
ports:
- 6379:6379
options: --health-cmd "redis-cli ping" --health-interval 5s --health-timeout 5s --health-retries 20
permissions:
contents: read
...
|
identity
|
["static"]
|
["ubuntu-latest"]
|
31502
|
4
|
1791590856
|
1791590856
|
1791590790
|
1791590857
|
|
1
|
|
0
|
Edit
Delete
|
|
37446
|
25276
|
116
|
5
|
019cb5aac97b29f5eeab6d5e9560ed1cb7ed6a34
|
0
|
Runtime and UI acceptance (real PostgreSQL + Redis Runtime and UI acceptance (real PostgreSQL + Redis)...
|
1
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
runtime:
name: Runtime and UI acceptance (real PostgreSQL + Redis)
runs-on: ubuntu-latest
env:
# 库名前缀由 runtime/package.json name 派生(G15 基座守卫:enterprise_platform*)
DATABASE_URL: postgresql://postgres:postgres@127.0.0.1:5432/enterprise_platform_ci?schema=public
REDIS_URL: redis://127.0.0.1:6379
KAFKA_BROKERS: 127.0.0.1:59092
MAINLINE_CHAOS_CONTAINER: enterprise-platform-ms23-ci-redpanda-1
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: actions/setup-node@v4
with:
cache: pnpm
cache-dependency-path: runtime/pnpm-lock.yaml
node-version: "20"
- name: Private registry auth (temporary userconfig)
uses: ./.github/actions/private-npm
with:
token: ${{ secrets.GITEA_NPM_TOKEN }}
- name: Install runtime workspace (frozen lockfile)
run: pnpm --dir runtime install --frozen-lockfile
- name: Generate Prisma clients
run: pnpm --dir runtime prisma:generate
- name: Build persistence modules and prepare isolated ordinary-role databases
run: |
pnpm runtime:build:modules
pnpm mainline:prepare
pnpm identity:prepare
- name: Policy activation concurrency and lease fencing (isolated PostgreSQL with RLS)
run: pnpm check:policy-governance
- name: Real file and notification execution slices (S3, ClamAV, durable receiver receipts)
run: pnpm check:execution-slices
env:
EXECUTION_CLAMAV_PORT: "3310"
- name: Start isolated Redpanda and provision registered topics
run: |
docker compose -p enterprise-platform-ms23-ci -f stack/compose.yaml -f stack/overlays/test.yaml up -d --wait --no-deps redpanda
bash stack/provision/redpanda-topics.sh --apply
- name: Real DB and Redis acceptance (deploy → RLS roles → differential → tests incl. 7 profile boots)
run: pnpm runtime:check:runtime
- name: Persistent mainline, audit tamper, revocation SLA and real broker failure
run: pnpm mainline:check
- name: Identity signing against isolated OpenBao Transit
run: pnpm identity:check:transit
- name: Install Playwright browser
run: pnpm --dir runtime --filter web exec playwright install --with-deps chromium
- name: Workbench browser regressions (intercepted read APIs)
run: pnpm check:workbench-ui
- name: UI acceptance (NestJS / Fastify x WS / SSE)
run: pnpm runtime:check:ui
env:
UI_MATRIX: "1"
- name: Identity module browser acceptance (login / MFA / consent / sessions)
run: pnpm identity:check:module-ui
- name: MCP controlled writes (isolated IdP, Owner receipt, retry and revocation)
run: pnpm check:mcp-writes
- if: always()
name: Upload runtime and UI evidence
uses: actions/upload-artifact@v3
with:
if-no-files-found: warn
name: platform-runtime-${{ env.CANDIDATE_TAG }}
path: |
runtime/reports/runtime-acceptance.latest.json
runtime/reports/conformance-differential.latest.json
runtime/reports/ui-acceptance.latest.json
reports/workbench-ui.latest.json
reports/identity-ui.latest.json
reports/mcp-writes.latest.json
reports/mainline-acceptance.latest.json
reports/revocation-sla.latest.json
reports/policy-governance.latest.json
reports/execution-slices.latest.json
reports/identity-transit.latest.json
reports/scope-http.latest.json
reports/scope-fact-sla.latest.json
reports/machine-revocation-sla.latest.json
reports/credential-m1-sla.latest.json
retention-days: "30"
- if: always()
name: Stop isolated acceptance broker
run: docker compose -p enterprise-platform-ms23-ci -f stack/compose.yaml -f stack/overlays/test.yaml down
timeout-minutes: "50"
services:
clamav:
image: clamav/clamav-debian@sha256:be3cb41d9833ce9ffb98f3d3e1483c35c0d87060c2bda3624d75fd28bbf0b3bd
ports:
- 3310:3310
options: --health-cmd "clamdcheck.sh" --health-start-period 120s --health-interval 10s --health-timeout 5s --health-retries 24
postgres:
image: postgres:16
env:
POSTGRES_DB: enterprise_platform_ci
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
ports:
- 5432:5432
options: --health-cmd "pg_isready -U postgres -d enterprise_platform_ci" --health-interval 5s --health-timeout 5s --health-retries 20
redis:
image: redis:7
ports:
- 6379:6379
options: --health-cmd "redis-cli ping" --health-interval 5s --health-timeout 5s --health-retries 20
permissions:
contents: read
...
|
runtime
|
["static"]
|
["ubuntu-latest"]
|
31501
|
4
|
1791590854
|
1791590854
|
1791590790
|
1791590855
|
|
1
|
|
0
|
Edit
Delete
|
|
37445
|
25276
|
116
|
5
|
019cb5aac97b29f5eeab6d5e9560ed1cb7ed6a34
|
0
|
Port conformance (kernel / modules / clients)
|
1
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
port-conformance:
name: Port conformance (kernel / modules / clients)
runs-on: ubuntu-latest
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: actions/setup-node@v4
with:
cache: pnpm
cache-dependency-path: runtime/pnpm-lock.yaml
node-version: "20"
- name: Private registry auth (temporary userconfig)
uses: ./.github/actions/private-npm
with:
token: ${{ secrets.GITEA_NPM_TOKEN }}
- name: Install runtime workspace (frozen lockfile)
run: pnpm --dir runtime install --frozen-lockfile
- name: Run port conformance with complete suite coverage
run: pnpm check:port-conformance
- if: always()
name: Upload port conformance evidence
uses: actions/upload-artifact@v3
with:
if-no-files-found: error
name: platform-port-conformance-${{ env.CANDIDATE_TAG }}
path: reports/port-conformance.latest.json
retention-days: "30"
timeout-minutes: "20"
permissions:
contents: read
...
|
port-conformance
|
["static"]
|
["ubuntu-latest"]
|
31500
|
4
|
1791590852
|
1791590852
|
1791590790
|
1791590853
|
|
1
|
|
0
|
Edit
Delete
|
|
37444
|
25276
|
116
|
5
|
019cb5aac97b29f5eeab6d5e9560ed1cb7ed6a34
|
0
|
Unit tests without DB (modules / packages / govern Unit tests without DB (modules / packages / governance)...
|
1
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
unit:
name: Unit tests without DB (modules / packages / governance)
runs-on: ubuntu-latest
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: actions/setup-node@v4
with:
cache: pnpm
cache-dependency-path: runtime/pnpm-lock.yaml
node-version: "20"
- name: Private registry auth (temporary userconfig)
uses: ./.github/actions/private-npm
with:
token: ${{ secrets.GITEA_NPM_TOKEN }}
- name: Install runtime workspace (frozen lockfile)
run: pnpm --dir runtime install --frozen-lockfile
- name: Generate clients for authority module unit imports (no database)
run: pnpm --dir runtime prisma:generate
- name: Module / package unit tests
run: pnpm --dir runtime exec turbo run test --filter='./modules/*' --filter='./packages/*' --filter='./clients/*' --force
- name: Governance package tests
run: pnpm governance:test
timeout-minutes: "20"
permissions:
contents: read
...
|
unit
|
["static"]
|
["ubuntu-latest"]
|
31499
|
4
|
1791590850
|
1791590850
|
1791590790
|
1791590851
|
|
1
|
|
0
|
Edit
Delete
|
|
37443
|
25276
|
116
|
5
|
019cb5aac97b29f5eeab6d5e9560ed1cb7ed6a34
|
0
|
Static governance (repo root, private packages)
|
1
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
static:
name: Static governance (repo root, private packages)
runs-on: ubuntu-latest
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: actions/setup-node@v4
with:
cache: pnpm
cache-dependency-path: runtime/pnpm-lock.yaml
node-version: "20"
- name: Private registry auth (temporary userconfig)
uses: ./.github/actions/private-npm
with:
token: ${{ secrets.GITEA_NPM_TOKEN }}
- name: Install runtime workspace (frozen lockfile)
run: pnpm --dir runtime install --frozen-lockfile
- name: Install contracts dependencies (public npm only, frozen lockfile; CT-1 build / validators / generated-types check)
run: pnpm --dir contracts install --frozen-lockfile
- name: Generate Prisma clients
run: pnpm --dir runtime prisma:generate
- name: Build runtime modules (fixture suites evaluate migrated rules from dist)
run: pnpm runtime:build:modules
- name: Repo-root governance gate
run: pnpm check
- name: Source tree must stay clean apart from latest reports (no tracked .npmrc mutation)
run: |
git status --porcelain | grep -vE '\.latest\.json$' && { echo "::error::静态门禁修改了报告以外的跟踪文件"; exit 1; } || echo "clean apart from latest reports"
- if: always()
name: Upload static evidence
uses: actions/upload-artifact@v3
with:
if-no-files-found: warn
name: platform-static-${{ env.CANDIDATE_TAG }}
path: |
reports/*.latest.json
runtime/reports/*.latest.json
!runtime/reports/runtime-acceptance.latest.json
!runtime/reports/conformance-differential.latest.json
!runtime/reports/ui-acceptance.latest.json
retention-days: "30"
timeout-minutes: "30"
permissions:
contents: read
...
|
static
|
null
|
["ubuntu-latest"]
|
31498
|
2
|
1791590836
|
1791590848
|
1791590790
|
1791590848
|
|
1
|
|
0
|
Edit
Delete
|
|
37442
|
25276
|
116
|
5
|
019cb5aac97b29f5eeab6d5e9560ed1cb7ed6a34
|
0
|
Public static checks (no private packages)
|
1
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
public-static:
name: Public static checks (no private packages)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: actions/setup-node@v4
with:
node-version: "20"
- name: Install contracts dependencies (public npm only, frozen lockfile; CT-1 build / validators / generated-types check)
run: pnpm --dir contracts install --frozen-lockfile
- name: Governance checks (no private packages; contracts deps from public npm)
run: |
pnpm check:module-imports
pnpm check:fact-pii
pnpm check:catalog
pnpm check:migration-decs
pnpm check:caddy
pnpm test
pnpm contracts:check:local
- name: Pack publishable packages (contracts + governance; no publish)
run: |
rm -rf dist-artifacts
pnpm --dir contracts build
pnpm --dir governance pack --pack-destination ../dist-artifacts
pnpm --dir contracts pack --pack-destination ../dist-artifacts
ls -la dist-artifacts
- if: always()
name: Upload package tarballs
uses: actions/upload-artifact@v3
with:
if-no-files-found: error
name: platform-packages-${{ env.CANDIDATE_TAG }}
path: dist-artifacts/*.tgz
retention-days: "30"
- if: always()
name: Upload public static evidence
uses: actions/upload-artifact@v3
with:
if-no-files-found: warn
name: platform-public-static-${{ env.CANDIDATE_TAG }}
path: reports/*.latest.json
retention-days: "30"
timeout-minutes: "15"
permissions:
contents: read
...
|
public-static
|
null
|
["ubuntu-latest"]
|
31497
|
2
|
1791590814
|
1791590836
|
1791590790
|
1791590836
|
|
1
|
|
0
|
Edit
Delete
|
|
40279
|
25742
|
139
|
5
|
018cc2cf5baa6db3ef3c5f8a56943fffe632ef53
|
0
|
Build (windows-latest)
|
0
|
name: Test
"on":
push:
paths-i name: Test
"on":
push:
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
build:
name: Build (windows-latest)
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node 20
uses: actions/setup-node@v4
with:
cache: npm
node-version: 20.x
- name: npm install
run: npm install
- name: Compile
run: npm run build
- name: Lint
run: npm run lint
- name: Format
run: npm run format-check
- name: Run Unit Tests
run: npm test
- name: Create artifacts
run: |
mkdir -p path/to/artifact-A
mkdir -p path/to/artifact-B
echo "Lorem ipsum dolor sit amet" > path/to/artifact-A/file-A.txt
echo "Hello world from file B" > path/to/artifact-B/file-B.txt
- name: Upload artifact A
uses: actions/upload-artifact@v4
with:
name: Artifact-A-${{ matrix.runs-on }}
path: path/to/artifact-A
- name: Upload artifact B
uses: actions/upload-artifact@v4
with:
name: Artifact-B-${{ matrix.runs-on }}
path: path/to/artifact-B
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: some/new/path
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: ~/some/path/with/a/tilde
- name: Verify successful download
run: |
$file1 = "some/new/path/file-A.txt"
$file2 = "~/some/path/with/a/tilde/file-A.txt"
if(!(Test-Path -path $file1) -or !(Test-Path -path $file2))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $file1) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $file2) -ceq "Lorem ipsum dolor sit amet"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
path: some/other/path
- name: Verify successful download
run: |
$fileA = "some/other/path/Artifact-A-${{ matrix.runs-on }}/file-A.txt"
$fileB = "some/other/path/Artifact-B-${{ matrix.runs-on }}/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
merge-multiple: "true"
path: single/directory
pattern: Artifact-*
- name: Verify successful download
run: |
$fileA = "single/directory/file-A.txt"
$fileB = "single/directory/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
strategy:
fail-fast: "false"
matrix:
runs-on:
- windows-latest
...
|
build
|
null
|
["windows-latest"]
|
0
|
3
|
0
|
1791950475
|
1791844748
|
1791950483
|
|
0
|
|
0
|
Edit
Delete
|
|
40278
|
25742
|
139
|
5
|
018cc2cf5baa6db3ef3c5f8a56943fffe632ef53
|
0
|
Build (ubuntu-latest)
|
1
|
name: Test
"on":
push:
paths-i name: Test
"on":
push:
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
build:
name: Build (ubuntu-latest)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node 20
uses: actions/setup-node@v4
with:
cache: npm
node-version: 20.x
- name: npm install
run: npm install
- name: Compile
run: npm run build
- name: Lint
run: npm run lint
- name: Format
run: npm run format-check
- name: Run Unit Tests
run: npm test
- name: Create artifacts
run: |
mkdir -p path/to/artifact-A
mkdir -p path/to/artifact-B
echo "Lorem ipsum dolor sit amet" > path/to/artifact-A/file-A.txt
echo "Hello world from file B" > path/to/artifact-B/file-B.txt
- name: Upload artifact A
uses: actions/upload-artifact@v4
with:
name: Artifact-A-${{ matrix.runs-on }}
path: path/to/artifact-A
- name: Upload artifact B
uses: actions/upload-artifact@v4
with:
name: Artifact-B-${{ matrix.runs-on }}
path: path/to/artifact-B
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: some/new/path
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: ~/some/path/with/a/tilde
- name: Verify successful download
run: |
$file1 = "some/new/path/file-A.txt"
$file2 = "~/some/path/with/a/tilde/file-A.txt"
if(!(Test-Path -path $file1) -or !(Test-Path -path $file2))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $file1) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $file2) -ceq "Lorem ipsum dolor sit amet"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
path: some/other/path
- name: Verify successful download
run: |
$fileA = "some/other/path/Artifact-A-${{ matrix.runs-on }}/file-A.txt"
$fileB = "some/other/path/Artifact-B-${{ matrix.runs-on }}/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
merge-multiple: "true"
path: single/directory
pattern: Artifact-*
- name: Verify successful download
run: |
$fileA = "single/directory/file-A.txt"
$fileB = "single/directory/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
strategy:
fail-fast: "false"
matrix:
runs-on:
- ubuntu-latest
...
|
build
|
null
|
["ubuntu-latest"]
|
33371
|
2
|
1791858441
|
1791858478
|
1791844748
|
1791858478
|
|
0
|
|
0
|
Edit
Delete
|
|
40277
|
25742
|
139
|
5
|
018cc2cf5baa6db3ef3c5f8a56943fffe632ef53
|
0
|
Build (macos-latest)
|
0
|
name: Test
"on":
push:
paths-i name: Test
"on":
push:
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
build:
name: Build (macos-latest)
runs-on: macos-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node 20
uses: actions/setup-node@v4
with:
cache: npm
node-version: 20.x
- name: npm install
run: npm install
- name: Compile
run: npm run build
- name: Lint
run: npm run lint
- name: Format
run: npm run format-check
- name: Run Unit Tests
run: npm test
- name: Create artifacts
run: |
mkdir -p path/to/artifact-A
mkdir -p path/to/artifact-B
echo "Lorem ipsum dolor sit amet" > path/to/artifact-A/file-A.txt
echo "Hello world from file B" > path/to/artifact-B/file-B.txt
- name: Upload artifact A
uses: actions/upload-artifact@v4
with:
name: Artifact-A-${{ matrix.runs-on }}
path: path/to/artifact-A
- name: Upload artifact B
uses: actions/upload-artifact@v4
with:
name: Artifact-B-${{ matrix.runs-on }}
path: path/to/artifact-B
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: some/new/path
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: ~/some/path/with/a/tilde
- name: Verify successful download
run: |
$file1 = "some/new/path/file-A.txt"
$file2 = "~/some/path/with/a/tilde/file-A.txt"
if(!(Test-Path -path $file1) -or !(Test-Path -path $file2))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $file1) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $file2) -ceq "Lorem ipsum dolor sit amet"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
path: some/other/path
- name: Verify successful download
run: |
$fileA = "some/other/path/Artifact-A-${{ matrix.runs-on }}/file-A.txt"
$fileB = "some/other/path/Artifact-B-${{ matrix.runs-on }}/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
merge-multiple: "true"
path: single/directory
pattern: Artifact-*
- name: Verify successful download
run: |
$fileA = "single/directory/file-A.txt"
$fileB = "single/directory/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
strategy:
fail-fast: "false"
matrix:
runs-on:
- macos-latest
...
|
build
|
null
|
["macos-latest"]
|
0
|
3
|
0
|
1791950475
|
1791844748
|
1791950483
|
|
0
|
|
0
|
Edit
Delete
|
|
40276
|
25741
|
139
|
5
|
018cc2cf5baa6db3ef3c5f8a56943fffe632ef53
|
0
|
Build (windows-latest)
|
0
|
name: Test
"on":
push:
paths-i name: Test
"on":
push:
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
build:
name: Build (windows-latest)
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node 20
uses: actions/setup-node@v4
with:
cache: npm
node-version: 20.x
- name: npm install
run: npm install
- name: Compile
run: npm run build
- name: Lint
run: npm run lint
- name: Format
run: npm run format-check
- name: Run Unit Tests
run: npm test
- name: Create artifacts
run: |
mkdir -p path/to/artifact-A
mkdir -p path/to/artifact-B
echo "Lorem ipsum dolor sit amet" > path/to/artifact-A/file-A.txt
echo "Hello world from file B" > path/to/artifact-B/file-B.txt
- name: Upload artifact A
uses: actions/upload-artifact@v4
with:
name: Artifact-A-${{ matrix.runs-on }}
path: path/to/artifact-A
- name: Upload artifact B
uses: actions/upload-artifact@v4
with:
name: Artifact-B-${{ matrix.runs-on }}
path: path/to/artifact-B
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: some/new/path
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: ~/some/path/with/a/tilde
- name: Verify successful download
run: |
$file1 = "some/new/path/file-A.txt"
$file2 = "~/some/path/with/a/tilde/file-A.txt"
if(!(Test-Path -path $file1) -or !(Test-Path -path $file2))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $file1) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $file2) -ceq "Lorem ipsum dolor sit amet"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
path: some/other/path
- name: Verify successful download
run: |
$fileA = "some/other/path/Artifact-A-${{ matrix.runs-on }}/file-A.txt"
$fileB = "some/other/path/Artifact-B-${{ matrix.runs-on }}/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
merge-multiple: "true"
path: single/directory
pattern: Artifact-*
- name: Verify successful download
run: |
$fileA = "single/directory/file-A.txt"
$fileB = "single/directory/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
strategy:
fail-fast: "false"
matrix:
runs-on:
- windows-latest
...
|
build
|
null
|
["windows-latest"]
|
0
|
3
|
0
|
1791950475
|
1791844747
|
1791950482
|
|
0
|
|
0
|
Edit
Delete
|
|
40275
|
25741
|
139
|
5
|
018cc2cf5baa6db3ef3c5f8a56943fffe632ef53
|
0
|
Build (ubuntu-latest)
|
1
|
name: Test
"on":
push:
paths-i name: Test
"on":
push:
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
build:
name: Build (ubuntu-latest)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node 20
uses: actions/setup-node@v4
with:
cache: npm
node-version: 20.x
- name: npm install
run: npm install
- name: Compile
run: npm run build
- name: Lint
run: npm run lint
- name: Format
run: npm run format-check
- name: Run Unit Tests
run: npm test
- name: Create artifacts
run: |
mkdir -p path/to/artifact-A
mkdir -p path/to/artifact-B
echo "Lorem ipsum dolor sit amet" > path/to/artifact-A/file-A.txt
echo "Hello world from file B" > path/to/artifact-B/file-B.txt
- name: Upload artifact A
uses: actions/upload-artifact@v4
with:
name: Artifact-A-${{ matrix.runs-on }}
path: path/to/artifact-A
- name: Upload artifact B
uses: actions/upload-artifact@v4
with:
name: Artifact-B-${{ matrix.runs-on }}
path: path/to/artifact-B
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: some/new/path
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: ~/some/path/with/a/tilde
- name: Verify successful download
run: |
$file1 = "some/new/path/file-A.txt"
$file2 = "~/some/path/with/a/tilde/file-A.txt"
if(!(Test-Path -path $file1) -or !(Test-Path -path $file2))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $file1) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $file2) -ceq "Lorem ipsum dolor sit amet"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
path: some/other/path
- name: Verify successful download
run: |
$fileA = "some/other/path/Artifact-A-${{ matrix.runs-on }}/file-A.txt"
$fileB = "some/other/path/Artifact-B-${{ matrix.runs-on }}/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
merge-multiple: "true"
path: single/directory
pattern: Artifact-*
- name: Verify successful download
run: |
$fileA = "single/directory/file-A.txt"
$fileB = "single/directory/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
strategy:
fail-fast: "false"
matrix:
runs-on:
- ubuntu-latest
...
|
build
|
null
|
["ubuntu-latest"]
|
33370
|
2
|
1791858403
|
1791858440
|
1791844747
|
1791858441
|
|
0
|
|
0
|
Edit
Delete
|
|
40274
|
25741
|
139
|
5
|
018cc2cf5baa6db3ef3c5f8a56943fffe632ef53
|
0
|
Build (macos-latest)
|
0
|
name: Test
"on":
push:
paths-i name: Test
"on":
push:
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
build:
name: Build (macos-latest)
runs-on: macos-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node 20
uses: actions/setup-node@v4
with:
cache: npm
node-version: 20.x
- name: npm install
run: npm install
- name: Compile
run: npm run build
- name: Lint
run: npm run lint
- name: Format
run: npm run format-check
- name: Run Unit Tests
run: npm test
- name: Create artifacts
run: |
mkdir -p path/to/artifact-A
mkdir -p path/to/artifact-B
echo "Lorem ipsum dolor sit amet" > path/to/artifact-A/file-A.txt
echo "Hello world from file B" > path/to/artifact-B/file-B.txt
- name: Upload artifact A
uses: actions/upload-artifact@v4
with:
name: Artifact-A-${{ matrix.runs-on }}
path: path/to/artifact-A
- name: Upload artifact B
uses: actions/upload-artifact@v4
with:
name: Artifact-B-${{ matrix.runs-on }}
path: path/to/artifact-B
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: some/new/path
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: ~/some/path/with/a/tilde
- name: Verify successful download
run: |
$file1 = "some/new/path/file-A.txt"
$file2 = "~/some/path/with/a/tilde/file-A.txt"
if(!(Test-Path -path $file1) -or !(Test-Path -path $file2))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $file1) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $file2) -ceq "Lorem ipsum dolor sit amet"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
path: some/other/path
- name: Verify successful download
run: |
$fileA = "some/other/path/Artifact-A-${{ matrix.runs-on }}/file-A.txt"
$fileB = "some/other/path/Artifact-B-${{ matrix.runs-on }}/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
merge-multiple: "true"
path: single/directory
pattern: Artifact-*
- name: Verify successful download
run: |
$fileA = "single/directory/file-A.txt"
$fileB = "single/directory/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
strategy:
fail-fast: "false"
matrix:
runs-on:
- macos-latest
...
|
build
|
null
|
["macos-latest"]
|
0
|
3
|
0
|
1791950475
|
1791844747
|
1791950482
|
|
0
|
|
0
|
Edit
Delete
|
|
38666
|
25465
|
116
|
5
|
01890ce8dc2c6393290cb03df060b772a08a4461
|
0
|
Release candidate verification + manifest
|
1
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
candidate:
name: Release candidate verification + manifest
runs-on: ubuntu-latest
if: always()
steps:
- uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: actions/setup-node@v4
with:
node-version: "20"
- name: Download static evidence
uses: actions/download-artifact@v3
with:
name: platform-static-${{ env.CANDIDATE_TAG }}
path: candidate/static
continue-on-error: true
- name: Download runtime evidence
uses: actions/download-artifact@v3
with:
name: platform-runtime-${{ env.CANDIDATE_TAG }}
path: candidate/runtime/runtime/reports
continue-on-error: true
- name: Download identity evidence
uses: actions/download-artifact@v3
with:
name: platform-identity-${{ env.CANDIDATE_TAG }}
path: candidate/identity/identity/reports
continue-on-error: true
- name: Download port-conformance evidence
uses: actions/download-artifact@v3
with:
name: platform-port-conformance-${{ env.CANDIDATE_TAG }}
path: candidate/port-conformance/reports
continue-on-error: true
- id: verify
name: Verify candidate (per-report sourceSha / dirty / status / digest; missing → ineligible)
run: node governance/verify-candidate.mjs --candidate candidate --sha "${{ github.sha }}" --run-id "${{ github.run_id }}" --attempt "${{ github.run_attempt }}" --out reports/release-candidate.latest.json
continue-on-error: true
- name: Download image and full SBOM evidence for the same candidate
uses: actions/download-artifact@v3
with:
name: platform-image-${{ env.CANDIDATE_TAG }}
path: reports
- name: Release Manifest (known facts, status partial until all deliverables exist)
run: node governance/release-manifest.mjs
- if: always()
name: Upload candidate evidence
uses: actions/upload-artifact@v3
with:
if-no-files-found: error
name: platform-candidate-${{ env.CANDIDATE_TAG }}
path: |
reports/release-candidate.latest.json
reports/release-manifest.latest.json
retention-days: "30"
- if: always()
name: Propagate upstream results and candidate eligibility
run: |
echo "public-static=${{ needs.public-static.result }} static=${{ needs.static.result }} runtime=${{ needs.runtime.result }} identity=${{ needs.identity.result }} verify=${{ steps.verify.outcome }}"
test "${{ needs.public-static.result }}" = "success"
test "${{ needs.static.result }}" = "success"
test "${{ needs.unit.result }}" = "success"
test "${{ needs.port-conformance.result }}" = "success"
test "${{ needs.runtime.result }}" = "success"
test "${{ needs.identity.result }}" = "success"
test "${{ needs.image.result }}" = "success"
test "${{ steps.verify.outcome }}" = "success"
timeout-minutes: "10"
permissions:
contents: read
...
|
candidate
|
["public-static","static","uni ["public-static","static","unit","port-conformance","runtime","identity","image"]...
|
["ubuntu-latest"]
|
32303
|
2
|
1791680251
|
1791680265
|
1791680184
|
1791680265
|
|
1
|
|
0
|
Edit
Delete
|
|
38665
|
25465
|
116
|
5
|
01890ce8dc2c6393290cb03df060b772a08a4461
|
0
|
Runtime image build + SBOM (+ cosign when a key is Runtime image build + SBOM (+ cosign when a key is provided)...
|
1
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
image:
name: Runtime image build + SBOM (+ cosign when a key is provided)
runs-on: ubuntu-latest
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: actions/setup-node@v4
with:
node-version: "20"
- name: Private registry auth (temporary userconfig)
uses: ./.github/actions/private-npm
with:
token: ${{ secrets.GITEA_NPM_TOKEN }}
- name: Resolve npmrc for BuildKit secret (never printed)
run: |
cfg="${RUNNER_TEMP}/platform-npmrc-resolved"
umask 077
printf '@juhai:registry=https://gitea.g-hi.com/api/packages/luoanwu/npm/\n//gitea.g-hi.com/api/packages/luoanwu/npm/:_authToken=%s\n' "${GITEA_NPM_TOKEN}" > "${cfg}"
echo "PLATFORM_NPMRC=${cfg}" >> "${GITHUB_ENV}"
- name: Build runtime image from git archive HEAD:runtime (reports/image-digest.json)
run: node governance/build-image.mjs --context head --npmrc "${PLATFORM_NPMRC}"
- name: Install syft (pinned) and generate SPDX SBOM
run: |
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b "${RUNNER_TEMP}/bin" v1.20.0
PATH="${RUNNER_TEMP}/bin:${PATH}" node governance/sbom.mjs
- name: Install cosign (pinned)
uses: sigstore/cosign-installer@v3
with:
cosign-release: v2.4.1
- name: Sign image when COSIGN_PRIVATE_KEY is provided (otherwise explicit skip)
run: |
if [ -n "${COSIGN_PRIVATE_KEY}" ]; then
umask 077; printf '%s' "${COSIGN_PRIVATE_KEY}" > "${RUNNER_TEMP}/cosign.key"
COSIGN_KEY="${RUNNER_TEMP}/cosign.key" node governance/sign-image.mjs
else
node governance/sign-image.mjs
fi
env:
COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }}
COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}
- if: always()
name: Upload image evidence
uses: actions/upload-artifact@v3
with:
if-no-files-found: warn
name: platform-image-${{ env.CANDIDATE_TAG }}
path: |
reports/image-digest.json
reports/sbom.spdx.json
reports/sbom.latest.json
reports/signature.json
retention-days: "30"
timeout-minutes: "40"
permissions:
contents: read
...
|
image
|
["static"]
|
["ubuntu-latest"]
|
32302
|
4
|
1791680249
|
1791680249
|
1791680184
|
1791680249
|
|
1
|
|
0
|
Edit
Delete
|
|
38664
|
25465
|
116
|
5
|
01890ce8dc2c6393290cb03df060b772a08a4461
|
0
|
M1 identity transitional workspace (IdP static → E M1 identity transitional workspace (IdP static → E2 → governance)...
|
1
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
identity:
name: M1 identity transitional workspace (IdP static → E2 → governance)
runs-on: ubuntu-latest
env:
# 库名前缀由 identity/package.json name 派生(enterprise_idp*);Redis 必须 db 0(老框架 C22)
DATABASE_URL: postgresql://postgres:postgres@127.0.0.1:5432/enterprise_idp_ci?schema=public
REDIS_URL: redis://127.0.0.1:6379/0
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: actions/setup-node@v4
with:
cache: pnpm
cache-dependency-path: identity/pnpm-lock.yaml
node-version: "20"
- name: Private registry auth (temporary userconfig; shared runtime identity fixture dependencies)
uses: ./.github/actions/private-npm
with:
token: ${{ secrets.GITEA_NPM_TOKEN }}
- name: Install identity workspace (frozen lockfile)
run: pnpm --dir identity install --frozen-lockfile
- name: Build shared identity fixture dependencies from this checkout
run: |
pnpm --dir runtime install --frozen-lockfile --filter @juhai/module-identity... --filter @juhai/client-identity
pnpm --dir runtime --filter @juhai/module-identity prisma:generate
pnpm --dir runtime exec turbo run build --filter=@juhai/module-identity... --filter=@juhai/client-identity...
pnpm --dir identity --filter api-nestjs exec node -e "require('node:assert/strict').strictEqual(require('@juhai/module-kit'), require('../../../runtime/modules/kit'))"
- name: Provision ordinary owner for the isolated identity test database
run: |
psql "${DATABASE_URL%%\?*}" -v ON_ERROR_STOP=1 <<'SQL'
CREATE ROLE enterprise_idp_ci_rt LOGIN PASSWORD 'ci-test-only' NOSUPERUSER NOCREATEDB NOCREATEROLE NOBYPASSRLS;
ALTER DATABASE enterprise_idp_ci OWNER TO enterprise_idp_ci_rt;
ALTER SCHEMA public OWNER TO enterprise_idp_ci_rt;
SQL
echo 'DATABASE_URL=postgresql://enterprise_idp_ci_rt:ci-test-only@127.0.0.1:5432/enterprise_idp_ci?schema=public' >> "$GITHUB_ENV"
- name: Generate Prisma clients
run: pnpm --dir identity prisma:generate
- name: IdP static sub-checks (independent of runtime / UI reports)
run: pnpm identity:check:static
- name: IdP real DB acceptance (255 tests, serialized)
run: pnpm identity:check:runtime
- name: Install Playwright browser
run: pnpm --dir identity --filter web exec playwright install --with-deps chromium
- name: IdP UI acceptance (12 cases)
run: pnpm identity:check:ui
- name: IdP final governance aggregation (same checkout, fresh runtime / UI reports)
run: pnpm identity:check:governance
- if: always()
name: Upload identity evidence
uses: actions/upload-artifact@v3
with:
if-no-files-found: warn
name: platform-identity-${{ env.CANDIDATE_TAG }}
path: identity/reports/*.latest.json
retention-days: "30"
timeout-minutes: "50"
services:
postgres:
image: postgres:16
env:
POSTGRES_DB: enterprise_idp_ci
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
ports:
- 5432:5432
options: --health-cmd "pg_isready -U postgres -d enterprise_idp_ci" --health-interval 5s --health-timeout 5s --health-retries 20
redis:
image: redis:7
ports:
- 6379:6379
options: --health-cmd "redis-cli ping" --health-interval 5s --health-timeout 5s --health-retries 20
permissions:
contents: read
...
|
identity
|
["static"]
|
["ubuntu-latest"]
|
32301
|
4
|
1791680247
|
1791680247
|
1791680184
|
1791680247
|
|
1
|
|
0
|
Edit
Delete
|
|
38663
|
25465
|
116
|
5
|
01890ce8dc2c6393290cb03df060b772a08a4461
|
0
|
Runtime and UI acceptance (real PostgreSQL + Redis Runtime and UI acceptance (real PostgreSQL + Redis)...
|
1
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
runtime:
name: Runtime and UI acceptance (real PostgreSQL + Redis)
runs-on: ubuntu-latest
env:
# 库名前缀由 runtime/package.json name 派生(G15 基座守卫:enterprise_platform*)
DATABASE_URL: postgresql://postgres:postgres@127.0.0.1:5432/enterprise_platform_ci?schema=public
REDIS_URL: redis://127.0.0.1:6379
KAFKA_BROKERS: 127.0.0.1:59092
MAINLINE_CHAOS_CONTAINER: enterprise-platform-ms23-ci-redpanda-1
# Compose parses all services even for --no-deps redpanda and down.
# These unused service values deliberately cannot start a runtime.
PLATFORM_DEPLOYMENT_ENV: test
PLATFORM_RUNTIME_IMAGE: enterprise-platform/runtime:ci-not-started
PLATFORM_RUNTIME_DATABASE_RUNTIME_URL: postgresql://unused@127.0.0.1:1/unused
PLATFORM_RUNTIME_DATABASE_SYSTEM_URL: postgresql://unused@127.0.0.1:1/unused
PLATFORM_RUNTIME_REDIS_URL: redis://127.0.0.1:1/15
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: actions/setup-node@v4
with:
cache: pnpm
cache-dependency-path: runtime/pnpm-lock.yaml
node-version: "20"
- name: Private registry auth (temporary userconfig)
uses: ./.github/actions/private-npm
with:
token: ${{ secrets.GITEA_NPM_TOKEN }}
- name: Install runtime workspace (frozen lockfile)
run: pnpm --dir runtime install --frozen-lockfile
- name: Install Playwright browser
run: pnpm --dir runtime --filter web exec playwright install --with-deps chromium
- name: Workbench browser regressions (intercepted read APIs)
run: pnpm check:workbench-ui
- name: Generate Prisma clients
run: pnpm --dir runtime prisma:generate
- name: Build persistence modules and provision every module acceptance database
run: |
pnpm runtime:build:modules
node governance/prepare-module-databases.mjs
- name: Prepare mainline fixtures and verify identity ordinary-role databases
run: |
pnpm mainline:prepare
pnpm identity:prepare
- name: Policy activation concurrency and lease fencing (isolated PostgreSQL with RLS)
run: pnpm check:policy-governance
- name: Build isolated MinIO from pinned upstream source
run: docker build -t enterprise-platform/test-minio:a6c538c5 stack/test-minio
- name: Real file and notification execution slices (S3, ClamAV, durable receiver receipts)
run: pnpm check:execution-slices
env:
EXECUTION_CLAMAV_PORT: "3310"
- name: Registry admission and central audit recovery
run: pnpm check:registry-admission
- name: Start isolated Redpanda and provision registered topics
run: |
docker compose -p enterprise-platform-ms23-ci -f stack/compose.yaml -f stack/overlays/test.yaml up -d --wait --no-deps redpanda
bash stack/provision/redpanda-topics.sh --apply
- name: Real DB and Redis acceptance (deploy → RLS roles → differential → tests incl. 7 profile boots)
run: pnpm runtime:check:runtime
- name: Configuration snapshots, tenant isolation and remote SDK acceptance
run: pnpm acceptance:configuration
- name: Persistent mainline, audit tamper, revocation SLA and real broker failure
run: pnpm mainline:check
- name: Identity signing against isolated OpenBao Transit
run: pnpm identity:check:transit
- name: UI acceptance (NestJS / Fastify x WS / SSE)
run: pnpm runtime:check:ui
env:
UI_MATRIX: "1"
- name: Identity module browser acceptance (login / MFA / consent / sessions)
run: pnpm identity:check:module-ui
- name: MCP controlled writes (isolated IdP, Owner receipt, retry and revocation)
run: pnpm check:mcp-writes
- if: always()
name: Upload workbench browser diagnostics
uses: actions/upload-artifact@v3
with:
if-no-files-found: warn
name: platform-workbench-browser-${{ env.CANDIDATE_TAG }}
path: /tmp/platform-workbench-ui-*/
retention-days: "7"
- if: always()
name: Upload runtime and UI evidence
uses: actions/upload-artifact@v3
with:
if-no-files-found: warn
name: platform-runtime-${{ env.CANDIDATE_TAG }}
path: |
runtime/reports/runtime-acceptance.latest.json
runtime/reports/conformance-differential.latest.json
runtime/reports/ui-acceptance.latest.json
reports/workbench-ui.latest.json
reports/identity-ui.latest.json
reports/mcp-writes.latest.json
reports/mainline-acceptance.latest.json
reports/configuration-runtime.latest.json
reports/revocation-sla.latest.json
reports/policy-governance.latest.json
reports/execution-slices.latest.json
reports/registry-admission.latest.json
reports/identity-transit.latest.json
reports/scope-http.latest.json
reports/scope-fact-sla.latest.json
reports/machine-revocation-sla.latest.json
reports/credential-m1-sla.latest.json
retention-days: "30"
- if: always()
name: Stop isolated acceptance broker
run: docker compose -p enterprise-platform-ms23-ci -f stack/compose.yaml -f stack/overlays/test.yaml down
timeout-minutes: "50"
services:
clamav:
image: clamav/clamav-debian@sha256:be3cb41d9833ce9ffb98f3d3e1483c35c0d87060c2bda3624d75fd28bbf0b3bd
ports:
- 3310:3310
options: --health-cmd "clamdcheck.sh" --health-start-period 120s --health-interval 10s --health-timeout 5s --health-retries 24
postgres:
image: postgres:16
env:
POSTGRES_DB: enterprise_platform_ci
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
ports:
- 5432:5432
options: --health-cmd "pg_isready -U postgres -d enterprise_platform_ci" --health-interval 5s --health-timeout 5s --health-retries 20
redis:
image: redis:7
ports:
- 6379:6379
options: --health-cmd "redis-cli ping" --health-interval 5s --health-timeout 5s --health-retries 20
permissions:
contents: read
...
|
runtime
|
["static"]
|
["ubuntu-latest"]
|
32300
|
4
|
1791680245
|
1791680245
|
1791680184
|
1791680245
|
|
1
|
|
0
|
Edit
Delete
|
|
38662
|
25465
|
116
|
5
|
01890ce8dc2c6393290cb03df060b772a08a4461
|
0
|
Port conformance (kernel / modules / clients)
|
1
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
port-conformance:
name: Port conformance (kernel / modules / clients)
runs-on: ubuntu-latest
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: actions/setup-node@v4
with:
cache: pnpm
cache-dependency-path: runtime/pnpm-lock.yaml
node-version: "20"
- name: Private registry auth (temporary userconfig)
uses: ./.github/actions/private-npm
with:
token: ${{ secrets.GITEA_NPM_TOKEN }}
- name: Install runtime workspace (frozen lockfile)
run: pnpm --dir runtime install --frozen-lockfile
- name: Run port conformance with complete suite coverage
run: pnpm check:port-conformance
- if: always()
name: Upload port conformance evidence
uses: actions/upload-artifact@v3
with:
if-no-files-found: error
name: platform-port-conformance-${{ env.CANDIDATE_TAG }}
path: reports/port-conformance.latest.json
retention-days: "30"
timeout-minutes: "20"
permissions:
contents: read
...
|
port-conformance
|
["static"]
|
["ubuntu-latest"]
|
32299
|
4
|
1791680243
|
1791680243
|
1791680184
|
1791680243
|
|
1
|
|
0
|
Edit
Delete
|
|
38661
|
25465
|
116
|
5
|
01890ce8dc2c6393290cb03df060b772a08a4461
|
0
|
Unit tests without DB (modules / packages / govern Unit tests without DB (modules / packages / governance)...
|
1
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
unit:
name: Unit tests without DB (modules / packages / governance)
runs-on: ubuntu-latest
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: actions/setup-node@v4
with:
cache: pnpm
cache-dependency-path: runtime/pnpm-lock.yaml
node-version: "20"
- name: Private registry auth (temporary userconfig)
uses: ./.github/actions/private-npm
with:
token: ${{ secrets.GITEA_NPM_TOKEN }}
- name: Install runtime workspace (frozen lockfile)
run: pnpm --dir runtime install --frozen-lockfile
- name: Generate clients for authority module unit imports (no database)
run: pnpm --dir runtime prisma:generate
- name: Module / package unit tests
run: pnpm --dir runtime exec turbo run test --filter='./modules/*' --filter='./packages/*' --filter='./clients/*' --force
- name: Governance package tests
run: pnpm governance:test
timeout-minutes: "20"
permissions:
contents: read
...
|
unit
|
["static"]
|
["ubuntu-latest"]
|
32298
|
4
|
1791680241
|
1791680241
|
1791680184
|
1791680241
|
|
1
|
|
0
|
Edit
Delete
|
|
38660
|
25465
|
116
|
5
|
01890ce8dc2c6393290cb03df060b772a08a4461
|
0
|
Static governance (repo root, private packages)
|
1
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
static:
name: Static governance (repo root, private packages)
runs-on: ubuntu-latest
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: actions/setup-node@v4
with:
cache: pnpm
cache-dependency-path: runtime/pnpm-lock.yaml
node-version: "20"
- name: Private registry auth (temporary userconfig)
uses: ./.github/actions/private-npm
with:
token: ${{ secrets.GITEA_NPM_TOKEN }}
- name: Install runtime workspace (frozen lockfile)
run: pnpm --dir runtime install --frozen-lockfile
- name: Install contracts dependencies (public npm only, frozen lockfile; CT-1 build / validators / generated-types check)
run: pnpm --dir contracts install --frozen-lockfile
- name: Generate Prisma clients
run: pnpm --dir runtime prisma:generate
- name: Build runtime modules (fixture suites evaluate migrated rules from dist)
run: pnpm runtime:build:modules
- name: Repo-root governance gate
run: pnpm check
- name: Source tree must stay clean apart from latest reports (no tracked .npmrc mutation)
run: |
git status --porcelain | grep -vE '\.latest\.json$' && { echo "::error::静态门禁修改了报告以外的跟踪文件"; exit 1; } || echo "clean apart from latest reports"
- if: always()
name: Upload static evidence
uses: actions/upload-artifact@v3
with:
if-no-files-found: warn
name: platform-static-${{ env.CANDIDATE_TAG }}
path: |
reports/*.latest.json
runtime/reports/*.latest.json
!runtime/reports/runtime-acceptance.latest.json
!runtime/reports/conformance-differential.latest.json
!runtime/reports/ui-acceptance.latest.json
retention-days: "30"
timeout-minutes: "30"
permissions:
contents: read
...
|
static
|
null
|
["ubuntu-latest"]
|
32297
|
2
|
1791680225
|
1791680238
|
1791680184
|
1791680239
|
|
0
|
|
0
|
Edit
Delete
|
|
38659
|
25465
|
116
|
5
|
01890ce8dc2c6393290cb03df060b772a08a4461
|
0
|
Public static checks (no private packages)
|
1
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
public-static:
name: Public static checks (no private packages)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: actions/setup-node@v4
with:
node-version: "20"
- name: Test image release credential preflight (synthetic credentials only)
run: node --test .github/scripts/test/*.test.mjs
- name: Install contracts dependencies (public npm only, frozen lockfile; CT-1 build / validators / generated-types check)
run: pnpm --dir contracts install --frozen-lockfile
- name: Governance checks (no private packages; contracts deps from public npm)
run: |
pnpm check:module-imports
pnpm check:fact-pii
pnpm check:catalog
pnpm check:migration-decs
pnpm check:caddy
pnpm test
pnpm contracts:check:local
- name: Pack publishable packages (contracts + governance; no publish)
run: |
rm -rf dist-artifacts
pnpm --dir contracts build
pnpm --dir governance pack --pack-destination ../dist-artifacts
pnpm --dir contracts pack --pack-destination ../dist-artifacts
ls -la dist-artifacts
- if: always()
name: Upload package tarballs
uses: actions/upload-artifact@v3
with:
if-no-files-found: error
name: platform-packages-${{ env.CANDIDATE_TAG }}
path: dist-artifacts/*.tgz
retention-days: "30"
- if: always()
name: Upload public static evidence
uses: actions/upload-artifact@v3
with:
if-no-files-found: warn
name: platform-public-static-${{ env.CANDIDATE_TAG }}
path: reports/*.latest.json
retention-days: "30"
timeout-minutes: "15"
permissions:
contents: read
...
|
public-static
|
null
|
["ubuntu-latest"]
|
32296
|
1
|
1791680184
|
1791680225
|
1791680184
|
1791680225
|
|
0
|
|
0
|
Edit
Delete
|
|
37694
|
25310
|
116
|
5
|
017c1dcb543cbdab615ea5052fab29903b061996
|
0
|
Release candidate verification + manifest
|
0
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
candidate:
name: Release candidate verification + manifest
runs-on: ubuntu-latest
if: always()
steps:
- uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: actions/setup-node@v4
with:
node-version: "20"
- name: Download static evidence
uses: actions/download-artifact@v3
with:
name: platform-static-${{ env.CANDIDATE_TAG }}
path: candidate/static
continue-on-error: true
- name: Download runtime evidence
uses: actions/download-artifact@v3
with:
name: platform-runtime-${{ env.CANDIDATE_TAG }}
path: candidate/runtime/runtime/reports
continue-on-error: true
- name: Download identity evidence
uses: actions/download-artifact@v3
with:
name: platform-identity-${{ env.CANDIDATE_TAG }}
path: candidate/identity/identity/reports
continue-on-error: true
- name: Download port-conformance evidence
uses: actions/download-artifact@v3
with:
name: platform-port-conformance-${{ env.CANDIDATE_TAG }}
path: candidate/port-conformance/reports
continue-on-error: true
- id: verify
name: Verify candidate (per-report sourceSha / dirty / status / digest; missing → ineligible)
run: node governance/verify-candidate.mjs --candidate candidate --sha "${{ github.sha }}" --run-id "${{ github.run_id }}" --attempt "${{ github.run_attempt }}" --out reports/release-candidate.latest.json
continue-on-error: true
- name: Download image and full SBOM evidence for the same candidate
uses: actions/download-artifact@v3
with:
name: platform-image-${{ env.CANDIDATE_TAG }}
path: reports
- name: Release Manifest (known facts, status partial until all deliverables exist)
run: node governance/release-manifest.mjs
- if: always()
name: Upload candidate evidence
uses: actions/upload-artifact@v3
with:
if-no-files-found: error
name: platform-candidate-${{ env.CANDIDATE_TAG }}
path: |
reports/release-candidate.latest.json
reports/release-manifest.latest.json
retention-days: "30"
- if: always()
name: Propagate upstream results and candidate eligibility
run: |
echo "public-static=${{ needs.public-static.result }} static=${{ needs.static.result }} runtime=${{ needs.runtime.result }} identity=${{ needs.identity.result }} verify=${{ steps.verify.outcome }}"
test "${{ needs.public-static.result }}" = "success"
test "${{ needs.static.result }}" = "success"
test "${{ needs.unit.result }}" = "success"
test "${{ needs.port-conformance.result }}" = "success"
test "${{ needs.runtime.result }}" = "success"
test "${{ needs.identity.result }}" = "success"
test "${{ needs.image.result }}" = "success"
test "${{ steps.verify.outcome }}" = "success"
timeout-minutes: "10"
permissions:
contents: read
...
|
candidate
|
["public-static","static","uni ["public-static","static","unit","port-conformance","runtime","identity","image"]...
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1791599108
|
1791598521
|
1791599108
|
|
0
|
|
0
|
Edit
Delete
|
|
37693
|
25310
|
116
|
5
|
017c1dcb543cbdab615ea5052fab29903b061996
|
0
|
Runtime image build + SBOM (+ cosign when a key is Runtime image build + SBOM (+ cosign when a key is provided)...
|
0
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
image:
name: Runtime image build + SBOM (+ cosign when a key is provided)
runs-on: ubuntu-latest
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: actions/setup-node@v4
with:
node-version: "20"
- name: Private registry auth (temporary userconfig)
uses: ./.github/actions/private-npm
with:
token: ${{ secrets.GITEA_NPM_TOKEN }}
- name: Resolve npmrc for BuildKit secret (never printed)
run: |
cfg="${RUNNER_TEMP}/platform-npmrc-resolved"
umask 077
printf '@juhai:registry=https://gitea.g-hi.com/api/packages/luoanwu/npm/\n//gitea.g-hi.com/api/packages/luoanwu/npm/:_authToken=%s\n' "${GITEA_NPM_TOKEN}" > "${cfg}"
echo "PLATFORM_NPMRC=${cfg}" >> "${GITHUB_ENV}"
- name: Build runtime image from git archive HEAD:runtime (reports/image-digest.json)
run: node governance/build-image.mjs --context head --npmrc "${PLATFORM_NPMRC}"
- name: Install syft (pinned) and generate SPDX SBOM
run: |
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b "${RUNNER_TEMP}/bin" v1.20.0
PATH="${RUNNER_TEMP}/bin:${PATH}" node governance/sbom.mjs
- name: Install cosign (pinned)
uses: sigstore/cosign-installer@v3
with:
cosign-release: v2.4.1
- name: Sign image when COSIGN_PRIVATE_KEY is provided (otherwise explicit skip)
run: |
if [ -n "${COSIGN_PRIVATE_KEY}" ]; then
umask 077; printf '%s' "${COSIGN_PRIVATE_KEY}" > "${RUNNER_TEMP}/cosign.key"
COSIGN_KEY="${RUNNER_TEMP}/cosign.key" node governance/sign-image.mjs
else
node governance/sign-image.mjs
fi
env:
COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }}
COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}
- if: always()
name: Upload image evidence
uses: actions/upload-artifact@v3
with:
if-no-files-found: warn
name: platform-image-${{ env.CANDIDATE_TAG }}
path: |
reports/image-digest.json
reports/sbom.spdx.json
reports/sbom.latest.json
reports/signature.json
retention-days: "30"
timeout-minutes: "40"
permissions:
contents: read
...
|
image
|
["static"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1791599108
|
1791598521
|
1791599108
|
|
0
|
|
0
|
Edit
Delete
|
|
37692
|
25310
|
116
|
5
|
017c1dcb543cbdab615ea5052fab29903b061996
|
0
|
M1 identity transitional workspace (IdP static → E M1 identity transitional workspace (IdP static → E2 → governance)...
|
0
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
identity:
name: M1 identity transitional workspace (IdP static → E2 → governance)
runs-on: ubuntu-latest
env:
# 库名前缀由 identity/package.json name 派生(enterprise_idp*);Redis 必须 db 0(老框架 C22)
DATABASE_URL: postgresql://postgres:postgres@127.0.0.1:5432/enterprise_idp_ci?schema=public
REDIS_URL: redis://127.0.0.1:6379/0
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: actions/setup-node@v4
with:
cache: pnpm
cache-dependency-path: identity/pnpm-lock.yaml
node-version: "20"
- name: Private registry auth (temporary userconfig; identity 目前无私包依赖,保持同一配置步骤以便后续 pin)
uses: ./.github/actions/private-npm
with:
token: ${{ secrets.GITEA_NPM_TOKEN }}
- name: Install identity workspace (frozen lockfile)
run: pnpm --dir identity install --frozen-lockfile
- name: Generate Prisma clients
run: pnpm --dir identity prisma:generate
- name: IdP static sub-checks (independent of runtime / UI reports)
run: pnpm identity:check:static
- name: IdP real DB acceptance (255 tests, serialized)
run: pnpm identity:check:runtime
- name: Install Playwright browser
run: pnpm --dir identity --filter web exec playwright install --with-deps chromium
- name: IdP UI acceptance (12 cases)
run: pnpm identity:check:ui
- name: IdP final governance aggregation (same checkout, fresh runtime / UI reports)
run: pnpm identity:check:governance
- if: always()
name: Upload identity evidence
uses: actions/upload-artifact@v3
with:
if-no-files-found: warn
name: platform-identity-${{ env.CANDIDATE_TAG }}
path: identity/reports/*.latest.json
retention-days: "30"
timeout-minutes: "50"
services:
postgres:
image: postgres:16
env:
POSTGRES_DB: enterprise_idp_ci
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
ports:
- 5432:5432
options: --health-cmd "pg_isready -U postgres -d enterprise_idp_ci" --health-interval 5s --health-timeout 5s --health-retries 20
redis:
image: redis:7
ports:
- 6379:6379
options: --health-cmd "redis-cli ping" --health-interval 5s --health-timeout 5s --health-retries 20
permissions:
contents: read
...
|
identity
|
["static"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1791599108
|
1791598521
|
1791599108
|
|
0
|
|
0
|
Edit
Delete
|
|
37691
|
25310
|
116
|
5
|
017c1dcb543cbdab615ea5052fab29903b061996
|
0
|
Runtime and UI acceptance (real PostgreSQL + Redis Runtime and UI acceptance (real PostgreSQL + Redis)...
|
0
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
runtime:
name: Runtime and UI acceptance (real PostgreSQL + Redis)
runs-on: ubuntu-latest
env:
# 库名前缀由 runtime/package.json name 派生(G15 基座守卫:enterprise_platform*)
DATABASE_URL: postgresql://postgres:postgres@127.0.0.1:5432/enterprise_platform_ci?schema=public
REDIS_URL: redis://127.0.0.1:6379
KAFKA_BROKERS: 127.0.0.1:59092
MAINLINE_CHAOS_CONTAINER: enterprise-platform-ms23-ci-redpanda-1
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: actions/setup-node@v4
with:
cache: pnpm
cache-dependency-path: runtime/pnpm-lock.yaml
node-version: "20"
- name: Private registry auth (temporary userconfig)
uses: ./.github/actions/private-npm
with:
token: ${{ secrets.GITEA_NPM_TOKEN }}
- name: Install runtime workspace (frozen lockfile)
run: pnpm --dir runtime install --frozen-lockfile
- name: Generate Prisma clients
run: pnpm --dir runtime prisma:generate
- name: Build persistence modules and prepare isolated ordinary-role databases
run: |
pnpm runtime:build:modules
pnpm mainline:prepare
pnpm identity:prepare
- name: Policy activation concurrency and lease fencing (isolated PostgreSQL with RLS)
run: pnpm check:policy-governance
- name: Real file and notification execution slices (S3, ClamAV, durable receiver receipts)
run: pnpm check:execution-slices
env:
EXECUTION_CLAMAV_PORT: "3310"
- name: Start isolated Redpanda and provision registered topics
run: |
docker compose -p enterprise-platform-ms23-ci -f stack/compose.yaml -f stack/overlays/test.yaml up -d --wait --no-deps redpanda
bash stack/provision/redpanda-topics.sh --apply
- name: Real DB and Redis acceptance (deploy → RLS roles → differential → tests incl. 7 profile boots)
run: pnpm runtime:check:runtime
- name: Persistent mainline, audit tamper, revocation SLA and real broker failure
run: pnpm mainline:check
- name: Identity signing against isolated OpenBao Transit
run: pnpm identity:check:transit
- name: Install Playwright browser
run: pnpm --dir runtime --filter web exec playwright install --with-deps chromium
- name: Workbench browser regressions (intercepted read APIs)
run: pnpm check:workbench-ui
- name: UI acceptance (NestJS / Fastify x WS / SSE)
run: pnpm runtime:check:ui
env:
UI_MATRIX: "1"
- name: Identity module browser acceptance (login / MFA / consent / sessions)
run: pnpm identity:check:module-ui
- name: MCP controlled writes (isolated IdP, Owner receipt, retry and revocation)
run: pnpm check:mcp-writes
- if: always()
name: Upload runtime and UI evidence
uses: actions/upload-artifact@v3
with:
if-no-files-found: warn
name: platform-runtime-${{ env.CANDIDATE_TAG }}
path: |
runtime/reports/runtime-acceptance.latest.json
runtime/reports/conformance-differential.latest.json
runtime/reports/ui-acceptance.latest.json
reports/workbench-ui.latest.json
reports/identity-ui.latest.json
reports/mcp-writes.latest.json
reports/mainline-acceptance.latest.json
reports/revocation-sla.latest.json
reports/policy-governance.latest.json
reports/execution-slices.latest.json
reports/identity-transit.latest.json
reports/scope-http.latest.json
reports/scope-fact-sla.latest.json
reports/machine-revocation-sla.latest.json
reports/credential-m1-sla.latest.json
retention-days: "30"
- if: always()
name: Stop isolated acceptance broker
run: docker compose -p enterprise-platform-ms23-ci -f stack/compose.yaml -f stack/overlays/test.yaml down
timeout-minutes: "50"
services:
clamav:
image: clamav/clamav-debian@sha256:be3cb41d9833ce9ffb98f3d3e1483c35c0d87060c2bda3624d75fd28bbf0b3bd
ports:
- 3310:3310
options: --health-cmd "clamdcheck.sh" --health-start-period 120s --health-interval 10s --health-timeout 5s --health-retries 24
postgres:
image: postgres:16
env:
POSTGRES_DB: enterprise_platform_ci
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
ports:
- 5432:5432
options: --health-cmd "pg_isready -U postgres -d enterprise_platform_ci" --health-interval 5s --health-timeout 5s --health-retries 20
redis:
image: redis:7
ports:
- 6379:6379
options: --health-cmd "redis-cli ping" --health-interval 5s --health-timeout 5s --health-retries 20
permissions:
contents: read
...
|
runtime
|
["static"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1791599108
|
1791598521
|
1791599108
|
|
0
|
|
0
|
Edit
Delete
|
|
37690
|
25310
|
116
|
5
|
017c1dcb543cbdab615ea5052fab29903b061996
|
0
|
Port conformance (kernel / modules / clients)
|
0
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
port-conformance:
name: Port conformance (kernel / modules / clients)
runs-on: ubuntu-latest
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: actions/setup-node@v4
with:
cache: pnpm
cache-dependency-path: runtime/pnpm-lock.yaml
node-version: "20"
- name: Private registry auth (temporary userconfig)
uses: ./.github/actions/private-npm
with:
token: ${{ secrets.GITEA_NPM_TOKEN }}
- name: Install runtime workspace (frozen lockfile)
run: pnpm --dir runtime install --frozen-lockfile
- name: Run port conformance with complete suite coverage
run: pnpm check:port-conformance
- if: always()
name: Upload port conformance evidence
uses: actions/upload-artifact@v3
with:
if-no-files-found: error
name: platform-port-conformance-${{ env.CANDIDATE_TAG }}
path: reports/port-conformance.latest.json
retention-days: "30"
timeout-minutes: "20"
permissions:
contents: read
...
|
port-conformance
|
["static"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1791599108
|
1791598521
|
1791599108
|
|
0
|
|
0
|
Edit
Delete
|
|
37689
|
25310
|
116
|
5
|
017c1dcb543cbdab615ea5052fab29903b061996
|
0
|
Unit tests without DB (modules / packages / govern Unit tests without DB (modules / packages / governance)...
|
0
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
unit:
name: Unit tests without DB (modules / packages / governance)
runs-on: ubuntu-latest
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: actions/setup-node@v4
with:
cache: pnpm
cache-dependency-path: runtime/pnpm-lock.yaml
node-version: "20"
- name: Private registry auth (temporary userconfig)
uses: ./.github/actions/private-npm
with:
token: ${{ secrets.GITEA_NPM_TOKEN }}
- name: Install runtime workspace (frozen lockfile)
run: pnpm --dir runtime install --frozen-lockfile
- name: Generate clients for authority module unit imports (no database)
run: pnpm --dir runtime prisma:generate
- name: Module / package unit tests
run: pnpm --dir runtime exec turbo run test --filter='./modules/*' --filter='./packages/*' --filter='./clients/*' --force
- name: Governance package tests
run: pnpm governance:test
timeout-minutes: "20"
permissions:
contents: read
...
|
unit
|
["static"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1791599108
|
1791598521
|
1791599108
|
|
0
|
|
0
|
Edit
Delete
|