|
31215
|
23553
|
90
|
5
|
46dce73b5cfc83e6e6cfb87922f22faee76fdd28
|
0
|
Runtime and UI acceptance
|
0
|
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/minimax_h3_studio_ci?schema=public
REDIS_URL: redis://127.0.0.1:6379
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@9.15.9 --activate
- name: Install dependencies
run: pnpm install --frozen-lockfile
- 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
services:
postgres:
image: postgres:16
env:
POSTGRES_DB: minimax_h3_studio_ci
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
ports:
- 5432:5432
options: --health-cmd "pg_isready -U postgres -d minimax_h3_studio_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
...
|
runtime-acceptance
|
["static-governance"]
|
["ubuntu-latest"]
|
0
|
4
|
0
|
0
|
1788059668
|
1788059693
|
|
1
|
|
0
|
Edit
Delete
|
|
31059
|
23492
|
74
|
5
|
470495fbe7a9692bbb9ef869546e0050c9c73b7e
|
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@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@9.15.9 --activate
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Generate Prisma clients
run: pnpm prisma:generate
- name: Run static governance gate
run: pnpm check
...
|
static-governance
|
null
|
["ubuntu-latest"]
|
27166
|
1
|
1787010159
|
1787010215
|
1787010158
|
1787010215
|
|
0
|
|
0
|
Edit
Delete
|
|
31060
|
23492
|
74
|
5
|
470495fbe7a9692bbb9ef869546e0050c9c73b7e
|
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/base_framework_ci?schema=public
REDIS_URL: redis://127.0.0.1:6379
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@9.15.9 --activate
- name: Install dependencies
run: pnpm install --frozen-lockfile
- 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
services:
postgres:
image: postgres:16
env:
POSTGRES_DB: base_framework_ci
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
ports:
- 5432:5432
options: --health-cmd "pg_isready -U postgres -d base_framework_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
...
|
runtime-acceptance
|
["static-governance"]
|
["ubuntu-latest"]
|
27167
|
2
|
1787010217
|
1787010237
|
1787010158
|
1787010237
|
|
1
|
|
0
|
Edit
Delete
|
|
37888
|
25343
|
57
|
5
|
47141f914ffb9f5d389d13877e8e1f2fe4b59038
|
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@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: .node-version
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@9.15.9 --activate
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Generate Prisma clients
run: pnpm prisma:generate
- name: Run static governance gate
run: pnpm check
- name: Runtime and development dependency audit
run: pnpm check:deps
permissions:
contents: read
...
|
static-governance
|
null
|
["ubuntu-latest"]
|
31881
|
2
|
1791616763
|
1791616793
|
1791616762
|
1791616794
|
|
0
|
|
0
|
Edit
Delete
|
|
36755
|
24984
|
121
|
5
|
4786002b94b47c86f0b5d80069153e482333ec8f
|
0
|
acceptance
|
1
|
name: Kernel V1.0 CI
"on":
push:
name: Kernel V1.0 CI
"on":
push:
branches: [main]
jobs:
acceptance:
name: acceptance
runs-on: ubuntu-latest
steps:
- name: Checkout fixed source
uses: https://gitea.com/actions/checkout@v4
with:
fetch-depth: "0"
persist-credentials: "false"
- name: Verify host runner and locked toolchain
run: |
set -eu
echo "Node executable: $(command -v node || true)"
node --version
node -e "if (Number(process.versions.node.split('.')[0]) < 22) { console.error('Node.js >=22 is required'); process.exit(1); }"
echo "Docker executable: $(command -v docker || true)"
docker version
docker image inspect postgres:16-alpine >/dev/null
corepack --version
corepack enable
corepack prepare pnpm@9.15.9 --activate
- name: Run isolated PostgreSQL acceptance
run: pnpm ci:local
env:
ERK_TEST_CONCURRENCY: "1"
permissions:
contents: read
...
|
acceptance
|
null
|
["ubuntu-latest"]
|
31118
|
2
|
1790943030
|
1790943070
|
1790943009
|
1790943070
|
|
0
|
|
0
|
Edit
Delete
|
|
34338
|
24271
|
117
|
5
|
47a3de602dfa355f1dce32f192ddf4478d0c923a
|
0
|
Governance tests (report-only until act_runner is Governance tests (report-only until act_runner is enabled)...
|
1
|
name: Governance
"on":
push:
b name: Governance
"on":
push:
branches: [main]
pull_request:
workflow_dispatch:
env:
FOUNDATION_REPORT_DIR: ${{ runner.temp }}/foundation-reports
PNPM_VERSION: 9.15.9
jobs:
governance-tests:
name: Governance tests (report-only until act_runner is enabled)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: actions/setup-node@v4
with:
node-version: "22"
- name: Governance tests
run: pnpm --dir 平台治理/基础 test
continue-on-error: true
- name: Governance gates (all gates run to completion; not blocking yet)
run: pnpm --dir 平台治理/基础 check
continue-on-error: true
- name: Tracked-secrets gate (root scope; the only gate whose CI result is meaningful without nested repos)
run: node 平台治理/基础/scripts/check-tracked-secrets.mjs --scope=root
timeout-minutes: "20"
permissions:
contents: read
...
|
governance-tests
|
null
|
["ubuntu-latest"]
|
29326
|
1
|
1789867919
|
1789867935
|
1789867918
|
1789867935
|
|
0
|
|
0
|
Edit
Delete
|
|
34960
|
24379
|
116
|
5
|
47e722b94fbf825cde7510b807c6b8d75c1d1e4d
|
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"]
|
29821
|
1
|
1790158866
|
1790158904
|
1790158866
|
1790158904
|
|
0
|
|
0
|
Edit
Delete
|
|
34961
|
24379
|
116
|
5
|
47e722b94fbf825cde7510b807c6b8d75c1d1e4d
|
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"]
|
29822
|
2
|
1790158904
|
1790158917
|
1790158866
|
1790158917
|
|
0
|
|
0
|
Edit
Delete
|
|
34962
|
24379
|
116
|
5
|
47e722b94fbf825cde7510b807c6b8d75c1d1e4d
|
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"]
|
29823
|
4
|
1790158917
|
1790158917
|
1790158866
|
1790158917
|
|
1
|
|
0
|
Edit
Delete
|
|
34963
|
24379
|
116
|
5
|
47e722b94fbf825cde7510b807c6b8d75c1d1e4d
|
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"]
|
29824
|
4
|
1790158919
|
1790158919
|
1790158866
|
1790158919
|
|
1
|
|
0
|
Edit
Delete
|
|
34964
|
24379
|
116
|
5
|
47e722b94fbf825cde7510b807c6b8d75c1d1e4d
|
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: 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
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"]
|
29825
|
4
|
1790158921
|
1790158921
|
1790158866
|
1790158921
|
|
1
|
|
0
|
Edit
Delete
|
|
34965
|
24379
|
116
|
5
|
47e722b94fbf825cde7510b807c6b8d75c1d1e4d
|
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"]
|
29826
|
4
|
1790158923
|
1790158923
|
1790158866
|
1790158923
|
|
1
|
|
0
|
Edit
Delete
|
|
34966
|
24379
|
116
|
5
|
47e722b94fbf825cde7510b807c6b8d75c1d1e4d
|
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
|
1790158925
|
1790158866
|
1790158925
|
|
1
|
|
0
|
Edit
Delete
|
|
34967
|
24379
|
116
|
5
|
47e722b94fbf825cde7510b807c6b8d75c1d1e4d
|
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
|
1790158925
|
1790158866
|
1790158925
|
|
0
|
|
0
|
Edit
Delete
|
|
36740
|
24969
|
121
|
5
|
47fc4d4845efac10a0b21bab24a0b1588ccf9ab6
|
0
|
acceptance
|
1
|
name: Kernel V1.0 CI
"on":
push:
name: Kernel V1.0 CI
"on":
push:
branches: [main]
jobs:
acceptance:
name: acceptance
runs-on: ubuntu-latest
steps:
- name: Checkout fixed source
uses: https://gitea.com/actions/checkout@v4
with:
fetch-depth: "0"
persist-credentials: "false"
- name: Verify host runner and locked toolchain
run: |
set -eu
echo "Node executable: $(command -v node || true)"
node --version
node -e "if (Number(process.versions.node.split('.')[0]) < 22) { console.error('Node.js >=22 is required'); process.exit(1); }"
echo "Docker executable: $(command -v docker || true)"
docker version
docker image inspect postgres:16-alpine >/dev/null
corepack --version
corepack enable
corepack prepare pnpm@9.15.9 --activate
- name: Run isolated PostgreSQL acceptance
run: pnpm ci:local
env:
ERK_TEST_CONCURRENCY: "1"
permissions:
contents: read
...
|
acceptance
|
null
|
["ubuntu-latest"]
|
31103
|
2
|
1790938766
|
1790938803
|
1790938765
|
1790938803
|
|
0
|
|
0
|
Edit
Delete
|
|
32758
|
24004
|
116
|
5
|
482d67363f779f0f0726d14450afbbc3f1642f19
|
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: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"]
|
28363
|
2
|
1789623319
|
1789623346
|
1789623317
|
1789623346
|
|
0
|
|
0
|
Edit
Delete
|
|
32759
|
24004
|
116
|
5
|
482d67363f779f0f0726d14450afbbc3f1642f19
|
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"]
|
28364
|
2
|
1789623346
|
1789623445
|
1789623317
|
1789623445
|
|
0
|
|
0
|
Edit
Delete
|
|
32760
|
24004
|
116
|
5
|
482d67363f779f0f0726d14450afbbc3f1642f19
|
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"]
|
28365
|
4
|
1789623447
|
1789623447
|
1789623317
|
1789623448
|
|
1
|
|
0
|
Edit
Delete
|
|
32761
|
24004
|
116
|
5
|
482d67363f779f0f0726d14450afbbc3f1642f19
|
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"]
|
28366
|
4
|
1789623449
|
1789623449
|
1789623317
|
1789623450
|
|
1
|
|
0
|
Edit
Delete
|
|
32762
|
24004
|
116
|
5
|
482d67363f779f0f0726d14450afbbc3f1642f19
|
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: 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: Install Playwright browser
run: pnpm --dir runtime --filter web exec playwright install --with-deps chromium
- name: UI acceptance
run: pnpm runtime:check:ui
- name: Identity module browser acceptance (login / MFA / consent / sessions)
run: pnpm identity:check:module-ui
- 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/identity-ui.latest.json
reports/mainline-acceptance.latest.json
reports/revocation-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:
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"]
|
28367
|
4
|
1789623451
|
1789623451
|
1789623317
|
1789623452
|
|
1
|
|
0
|
Edit
Delete
|
|
32763
|
24004
|
116
|
5
|
482d67363f779f0f0726d14450afbbc3f1642f19
|
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"]
|
28368
|
4
|
1789623453
|
1789623453
|
1789623317
|
1789623454
|
|
1
|
|
0
|
Edit
Delete
|
|
32764
|
24004
|
116
|
5
|
482d67363f779f0f0726d14450afbbc3f1642f19
|
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"]
|
28369
|
4
|
1789623455
|
1789623455
|
1789623317
|
1789623456
|
|
1
|
|
0
|
Edit
Delete
|
|
32765
|
24004
|
116
|
5
|
482d67363f779f0f0726d14450afbbc3f1642f19
|
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"]
|
28370
|
2
|
1789623457
|
1789623487
|
1789623317
|
1789623488
|
|
1
|
|
0
|
Edit
Delete
|
|
36477
|
24713
|
121
|
5
|
483c6963490e29e417b1ef4c3e94ac8ca2898f92
|
0
|
acceptance
|
1
|
name: Kernel V1.0 CI
"on":
push:
name: Kernel V1.0 CI
"on":
push:
branches: [main]
jobs:
acceptance:
name: acceptance
runs-on: ubuntu-latest
steps:
- name: Checkout fixed source
uses: https://gitea.com/actions/checkout@v4
with:
fetch-depth: "0"
persist-credentials: "false"
- name: Verify host runner and locked toolchain
run: |
set -eu
echo "Node executable: $(command -v node || true)"
node --version
node -e "if (Number(process.versions.node.split('.')[0]) < 22) { console.error('Node.js >=22 is required'); process.exit(1); }"
echo "Docker executable: $(command -v docker || true)"
docker version
docker image inspect postgres:16-alpine >/dev/null
corepack --version
corepack enable
corepack prepare pnpm@9.15.9 --activate
- name: Run isolated PostgreSQL acceptance
run: pnpm ci:local
env:
ERK_TEST_CONCURRENCY: "1"
permissions:
contents: read
...
|
acceptance
|
null
|
["ubuntu-latest"]
|
30840
|
1
|
1790739707
|
1790740188
|
1790739706
|
1790740188
|
|
0
|
|
0
|
Edit
Delete
|
|
42141
|
26057
|
116
|
5
|
4879f961a57123477c417c4edf4ab552b97b9c56
|
0
|
Public static checks (no private packages)
|
1
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
GITEA_ACTIONS: "true"
PNPM_VERSION: 9.15.9
jobs:
public-static:
name: Public static checks (no private packages)
runs-on: ubuntu-latest
steps:
- name: Candidate tag (real run attempt, computed per job)
run: |
if ! [[ "${GITHUB_RUN_ATTEMPT:-}" =~ ^[1-9][0-9]*$ ]]; then
echo "::error::GITHUB_RUN_ATTEMPT is missing or invalid on this runner; the candidate tag needs the real attempt (no fallback, decision 2026-10-11)"
exit 1
fi
echo "CANDIDATE_TAG=${GITHUB_SHA}-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" >> "$GITHUB_ENV"
- uses: https://gitea.g-hi.com/luoanwu/actions-checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: https://gitea.g-hi.com/luoanwu/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: https://gitea.g-hi.com/luoanwu/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: https://gitea.g-hi.com/luoanwu/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"]
|
34582
|
2
|
1792286931
|
1792286931
|
1792286929
|
1792286931
|
|
0
|
|
0
|
Edit
Delete
|
|
42142
|
26057
|
116
|
5
|
4879f961a57123477c417c4edf4ab552b97b9c56
|
0
|
Static governance (repo root, private packages)
|
1
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
GITEA_ACTIONS: "true"
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:
- name: Candidate tag (real run attempt, computed per job)
run: |
if ! [[ "${GITHUB_RUN_ATTEMPT:-}" =~ ^[1-9][0-9]*$ ]]; then
echo "::error::GITHUB_RUN_ATTEMPT is missing or invalid on this runner; the candidate tag needs the real attempt (no fallback, decision 2026-10-11)"
exit 1
fi
echo "CANDIDATE_TAG=${GITHUB_SHA}-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" >> "$GITHUB_ENV"
- uses: https://gitea.g-hi.com/luoanwu/actions-checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: https://gitea.g-hi.com/luoanwu/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.PLATFORM_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: https://gitea.g-hi.com/luoanwu/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"]
|
34583
|
2
|
1792286933
|
1792286933
|
1792286929
|
1792286933
|
|
0
|
|
0
|
Edit
Delete
|
|
42143
|
26057
|
116
|
5
|
4879f961a57123477c417c4edf4ab552b97b9c56
|
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:
GITEA_ACTIONS: "true"
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: https://gitea.g-hi.com/luoanwu/actions-checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: https://gitea.g-hi.com/luoanwu/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.PLATFORM_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"]
|
34584
|
4
|
1792286935
|
1792286935
|
1792286929
|
1792286935
|
|
1
|
|
0
|
Edit
Delete
|
|
42144
|
26057
|
116
|
5
|
4879f961a57123477c417c4edf4ab552b97b9c56
|
0
|
Port conformance (kernel / modules / clients)
|
1
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
GITEA_ACTIONS: "true"
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:
- name: Candidate tag (real run attempt, computed per job)
run: |
if ! [[ "${GITHUB_RUN_ATTEMPT:-}" =~ ^[1-9][0-9]*$ ]]; then
echo "::error::GITHUB_RUN_ATTEMPT is missing or invalid on this runner; the candidate tag needs the real attempt (no fallback, decision 2026-10-11)"
exit 1
fi
echo "CANDIDATE_TAG=${GITHUB_SHA}-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" >> "$GITHUB_ENV"
- uses: https://gitea.g-hi.com/luoanwu/actions-checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: https://gitea.g-hi.com/luoanwu/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.PLATFORM_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: https://gitea.g-hi.com/luoanwu/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"]
|
34585
|
4
|
1792286937
|
1792286937
|
1792286929
|
1792286937
|
|
1
|
|
0
|
Edit
Delete
|
|
42145
|
26057
|
116
|
5
|
4879f961a57123477c417c4edf4ab552b97b9c56
|
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:
GITEA_ACTIONS: "true"
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:
- name: Candidate tag (real run attempt, computed per job)
run: |
if ! [[ "${GITHUB_RUN_ATTEMPT:-}" =~ ^[1-9][0-9]*$ ]]; then
echo "::error::GITHUB_RUN_ATTEMPT is missing or invalid on this runner; the candidate tag needs the real attempt (no fallback, decision 2026-10-11)"
exit 1
fi
echo "CANDIDATE_TAG=${GITHUB_SHA}-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" >> "$GITHUB_ENV"
- uses: https://gitea.g-hi.com/luoanwu/actions-checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: https://gitea.g-hi.com/luoanwu/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.PLATFORM_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: https://gitea.g-hi.com/luoanwu/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: https://gitea.g-hi.com/luoanwu/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"]
|
34586
|
4
|
1792286939
|
1792286939
|
1792286929
|
1792286939
|
|
1
|
|
0
|
Edit
Delete
|
|
42146
|
26057
|
116
|
5
|
4879f961a57123477c417c4edf4ab552b97b9c56
|
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:
GITEA_ACTIONS: "true"
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:
- name: Candidate tag (real run attempt, computed per job)
run: |
if ! [[ "${GITHUB_RUN_ATTEMPT:-}" =~ ^[1-9][0-9]*$ ]]; then
echo "::error::GITHUB_RUN_ATTEMPT is missing or invalid on this runner; the candidate tag needs the real attempt (no fallback, decision 2026-10-11)"
exit 1
fi
echo "CANDIDATE_TAG=${GITHUB_SHA}-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" >> "$GITHUB_ENV"
- uses: https://gitea.g-hi.com/luoanwu/actions-checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: https://gitea.g-hi.com/luoanwu/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.PLATFORM_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: https://gitea.g-hi.com/luoanwu/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"]
|
34587
|
4
|
1792286941
|
1792286941
|
1792286929
|
1792286941
|
|
1
|
|
0
|
Edit
Delete
|
|
42147
|
26057
|
116
|
5
|
4879f961a57123477c417c4edf4ab552b97b9c56
|
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:
GITEA_ACTIONS: "true"
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:
- name: Candidate tag (real run attempt, computed per job)
run: |
if ! [[ "${GITHUB_RUN_ATTEMPT:-}" =~ ^[1-9][0-9]*$ ]]; then
echo "::error::GITHUB_RUN_ATTEMPT is missing or invalid on this runner; the candidate tag needs the real attempt (no fallback, decision 2026-10-11)"
exit 1
fi
echo "CANDIDATE_TAG=${GITHUB_SHA}-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" >> "$GITHUB_ENV"
- uses: https://gitea.g-hi.com/luoanwu/actions-checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: https://gitea.g-hi.com/luoanwu/actions-setup-node@v4
with:
node-version: "20"
- name: Private registry auth (temporary userconfig)
uses: ./.github/actions/private-npm
with:
token: ${{ secrets.PLATFORM_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: https://gitea.g-hi.com/luoanwu/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: https://gitea.g-hi.com/luoanwu/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"]
|
34588
|
4
|
1792286943
|
1792286943
|
1792286929
|
1792286943
|
|
1
|
|
0
|
Edit
Delete
|
|
42148
|
26057
|
116
|
5
|
4879f961a57123477c417c4edf4ab552b97b9c56
|
0
|
Release candidate verification + manifest
|
1
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
GITEA_ACTIONS: "true"
PNPM_VERSION: 9.15.9
jobs:
candidate:
name: Release candidate verification + manifest
runs-on: ubuntu-latest
if: always()
steps:
- name: Candidate tag (real run attempt, computed per job)
run: |
if ! [[ "${GITHUB_RUN_ATTEMPT:-}" =~ ^[1-9][0-9]*$ ]]; then
echo "::error::GITHUB_RUN_ATTEMPT is missing or invalid on this runner; the candidate tag needs the real attempt (no fallback, decision 2026-10-11)"
exit 1
fi
echo "CANDIDATE_TAG=${GITHUB_SHA}-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" >> "$GITHUB_ENV"
- uses: https://gitea.g-hi.com/luoanwu/actions-checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
- uses: https://gitea.g-hi.com/luoanwu/actions-setup-node@v4
with:
node-version: "20"
- name: Download static evidence
uses: https://gitea.g-hi.com/luoanwu/actions-download-artifact@v3
with:
name: platform-static-${{ env.CANDIDATE_TAG }}
path: candidate/static
continue-on-error: true
- name: Download runtime evidence
uses: https://gitea.g-hi.com/luoanwu/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: https://gitea.g-hi.com/luoanwu/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: https://gitea.g-hi.com/luoanwu/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: https://gitea.g-hi.com/luoanwu/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: https://gitea.g-hi.com/luoanwu/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"]
|
34589
|
2
|
1792286945
|
1792286945
|
1792286929
|
1792286945
|
|
1
|
|
0
|
Edit
Delete
|
|
31212
|
23552
|
91
|
5
|
48c7ef665e210ef004970fc6f1fdc443a03b48a1
|
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
env:
# check:os-product 的上游:同实例私有仓,按 SHA 钉版(与本地验收口径一致)。
# 升级流程:先在本地以新 SHA 跑绿 check:os-product(:runtime),再改这里的 OS_SHA。
OS_REPO: luoanwu/digital-employee-os
OS_SHA: fcbd389107386fa0a13d0abd3c8d7c272cc2a7f7
# Digital Employee OS 的 engines 要求 node >=22(本仓自身 >=20,取并集)
NODE_VERSION: v22.16.0
steps:
- name: Checkout (shell, full history)
run: |
set -euo pipefail
cd "$GITHUB_WORKSPACE"
HOST_PATH="${GITHUB_SERVER_URL#*://}"
git init -q .
git remote remove origin 2>/dev/null || true
git remote add origin "https://oauth2:${CLONE_TOKEN}@${HOST_PATH}/${GITHUB_REPOSITORY}.git"
git fetch -q origin "$GITHUB_SHA"
git checkout -q -f --detach "$GITHUB_SHA"
git clean -fdxq -e node_modules -e .turbo
git log --oneline -1
env:
CLONE_TOKEN: ${{ secrets.OS_CHECKOUT_TOKEN || github.token }}
- name: Provision Node.js (npmmirror)
run: |
set -euo pipefail
case "$(uname -m)" in
x86_64) NODE_ARCH=x64 ;;
aarch64|arm64) NODE_ARCH=arm64 ;;
*) echo "::error::未支持的 runner 架构 $(uname -m)"; exit 1 ;;
esac
NODE_DIR="$RUNNER_TEMP/node-${NODE_VERSION}-${NODE_ARCH}"
if [ ! -x "$NODE_DIR/bin/node" ]; then
mkdir -p "$NODE_DIR"
curl -fsSL "https://cdn.npmmirror.com/binaries/node/${NODE_VERSION}/node-${NODE_VERSION}-linux-${NODE_ARCH}.tar.xz" \
| tar -xJ -C "$NODE_DIR" --strip-components 1
fi
echo "$NODE_DIR/bin" >> "$GITHUB_PATH"
"$NODE_DIR/bin/node" --version
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@9.15.9 --activate
pnpm --version
- name: Checkout Digital Employee OS (check:os-product upstream)
run: |
set -euo pipefail
HOST_PATH="${GITHUB_SERVER_URL#*://}"
OS_DIR="$RUNNER_TEMP/digital-employee-os"
rm -rf "$OS_DIR" && mkdir -p "$OS_DIR" && cd "$OS_DIR"
git init -q .
git remote add origin "https://oauth2:${OS_TOKEN}@${HOST_PATH}/${OS_REPO}.git"
git fetch -q --depth 1 origin "$OS_SHA"
git checkout -q --detach FETCH_HEAD
echo "DIGITAL_EMPLOYEE_OS_ROOT=$OS_DIR" >> "$GITHUB_ENV"
echo "DIGITAL_EMPLOYEE_OS_SHA=$OS_SHA" >> "$GITHUB_ENV"
env:
OS_TOKEN: ${{ secrets.OS_CHECKOUT_TOKEN || github.token }}
- name: Build Digital Employee OS contracts
run: |
set -euo pipefail
cd "$DIGITAL_EMPLOYEE_OS_ROOT"
pnpm install --frozen-lockfile
pnpm --filter @repo/contracts build
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Generate Prisma clients
run: pnpm prisma:generate
- name: Run static governance gate
run: pnpm check
...
|
static-governance
|
null
|
["ubuntu-latest"]
|
27256
|
1
|
1788058397
|
1788058457
|
1788058396
|
1788058457
|
|
0
|
|
0
|
Edit
Delete
|
|
31213
|
23552
|
91
|
5
|
48c7ef665e210ef004970fc6f1fdc443a03b48a1
|
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:
NODE_VERSION: v22.16.0
# 大陆网络直连 Playwright CDN 会长时间零进度假死(本机实测 8 分钟 0 字节,
# npmmirror 30 秒完成);runner 与本机同网段,直接走镜像。
PLAYWRIGHT_DOWNLOAD_HOST: https://cdn.npmmirror.com/binaries/playwright
steps:
- name: Checkout (shell, full history)
run: |
set -euo pipefail
cd "$GITHUB_WORKSPACE"
HOST_PATH="${GITHUB_SERVER_URL#*://}"
git init -q .
git remote remove origin 2>/dev/null || true
git remote add origin "https://oauth2:${CLONE_TOKEN}@${HOST_PATH}/${GITHUB_REPOSITORY}.git"
git fetch -q origin "$GITHUB_SHA"
git checkout -q -f --detach "$GITHUB_SHA"
git clean -fdxq -e node_modules -e .turbo
git log --oneline -1
env:
CLONE_TOKEN: ${{ secrets.OS_CHECKOUT_TOKEN || github.token }}
- name: Provision Node.js (npmmirror)
run: |
set -euo pipefail
case "$(uname -m)" in
x86_64) NODE_ARCH=x64 ;;
aarch64|arm64) NODE_ARCH=arm64 ;;
*) echo "::error::未支持的 runner 架构 $(uname -m)"; exit 1 ;;
esac
NODE_DIR="$RUNNER_TEMP/node-${NODE_VERSION}-${NODE_ARCH}"
if [ ! -x "$NODE_DIR/bin/node" ]; then
mkdir -p "$NODE_DIR"
curl -fsSL "https://cdn.npmmirror.com/binaries/node/${NODE_VERSION}/node-${NODE_VERSION}-linux-${NODE_ARCH}.tar.xz" \
| tar -xJ -C "$NODE_DIR" --strip-components 1
fi
echo "$NODE_DIR/bin" >> "$GITHUB_PATH"
"$NODE_DIR/bin/node" --version
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@9.15.9 --activate
pnpm --version
- name: Provision PostgreSQL and Redis
run: |
set -euo pipefail
command -v docker >/dev/null 2>&1 || { echo "::error::runner 宿主缺 docker——runtime 验收需要它启动隔离 PostgreSQL/Redis(或改用支持 services 的容器模式 runner)"; exit 1; }
# runner 宿主直连 Docker Hub 被拒(run #7:pull access denied)——大陆网络
# 常态。解析顺序:本地已有镜像(任一命名)→ daocloud/1ms 镜像站 → hub 兜底;
# 首次拉取成功后镜像常驻宿主,后续 run 不再依赖外网。
resolve_image() {
local image="$1" ref
for ref in "docker.io/library/${image}" "docker.m.daocloud.io/library/${image}" "docker.1ms.run/library/${image}" "${image}"; do
if docker image inspect "$ref" >/dev/null 2>&1; then echo "$ref"; return 0; fi
done
for ref in "docker.m.daocloud.io/library/${image}" "docker.1ms.run/library/${image}" "docker.io/library/${image}"; do
if docker pull --quiet "$ref" >/dev/null 2>&1; then echo "$ref"; return 0; fi
done
echo "::error::拉取 ${image} 失败:daocloud/1ms 镜像站与 Docker Hub 均不可达;可在 runner 宿主预拉镜像或给 dockerd 配 registry-mirrors" >&2
return 1
}
PG_IMAGE="$(resolve_image postgres:16)"
REDIS_IMAGE="$(resolve_image redis:7)"
echo "镜像解析:$PG_IMAGE / $REDIS_IMAGE"
PG_NAME="qwen38fn-ci-pg-${GITHUB_RUN_ID}"
REDIS_NAME="qwen38fn-ci-redis-${GITHUB_RUN_ID}"
docker rm -f "$PG_NAME" "$REDIS_NAME" >/dev/null 2>&1 || true
docker run -d --name "$PG_NAME" \
-e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres \
-e POSTGRES_DB=qwen3_8_flash_next_ci \
-p 127.0.0.1::5432 "$PG_IMAGE" >/dev/null
docker run -d --name "$REDIS_NAME" -p 127.0.0.1::6379 "$REDIS_IMAGE" >/dev/null
PG_PORT="$(docker port "$PG_NAME" 5432/tcp | head -n1 | awk -F: '{print $NF}')"
REDIS_PORT="$(docker port "$REDIS_NAME" 6379/tcp | head -n1 | awk -F: '{print $NF}')"
for _ in $(seq 1 60); do
docker exec "$PG_NAME" pg_isready -U postgres >/dev/null 2>&1 && break
sleep 1
done
docker exec "$PG_NAME" pg_isready -U postgres -d qwen3_8_flash_next_ci
[ "$(docker exec "$REDIS_NAME" redis-cli ping)" = "PONG" ]
{
echo "PG_NAME=$PG_NAME"
echo "REDIS_NAME=$REDIS_NAME"
echo "DATABASE_URL=postgresql://postgres:postgres@127.0.0.1:${PG_PORT}/qwen3_8_flash_next_ci?schema=public"
echo "REDIS_URL=redis://127.0.0.1:${REDIS_PORT}"
} >> "$GITHUB_ENV"
echo "PostgreSQL 127.0.0.1:${PG_PORT} / Redis 127.0.0.1:${REDIS_PORT} 就绪"
- name: Install dependencies
run: pnpm install --frozen-lockfile
- 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
- if: always()
name: Tear down PostgreSQL and Redis
run: docker rm -f "${PG_NAME:-}" "${REDIS_NAME:-}" >/dev/null 2>&1 || true
...
|
runtime-acceptance
|
["static-governance"]
|
["ubuntu-latest"]
|
27257
|
1
|
1788058459
|
1788058564
|
1788058396
|
1788058565
|
|
1
|
|
0
|
Edit
Delete
|
|
36894
|
25123
|
121
|
5
|
4915494eb71729938e3f2dbcee58b3f04cdf7dd4
|
0
|
acceptance
|
0
|
name: Kernel V1.0 CI
"on":
push:
name: Kernel V1.0 CI
"on":
push:
branches: [main]
jobs:
acceptance:
name: acceptance
runs-on: ubuntu-latest
steps:
- name: Checkout fixed source
uses: https://gitea.com/actions/checkout@v4
with:
fetch-depth: "0"
persist-credentials: "false"
- name: Verify host runner and locked toolchain
run: |
set -eu
echo "Node executable: $(command -v node || true)"
node --version
node -e "if (Number(process.versions.node.split('.')[0]) < 22) { console.error('Node.js >=22 is required'); process.exit(1); }"
echo "Docker executable: $(command -v docker || true)"
docker version
docker image inspect postgres:16-alpine >/dev/null
corepack --version
corepack enable
corepack prepare pnpm@9.15.9 --activate
- name: Run isolated PostgreSQL acceptance
run: pnpm ci:local
env:
ERK_TEST_CONCURRENCY: "1"
permissions:
contents: read
...
|
acceptance
|
null
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1791108075
|
1791002853
|
1791108075
|
|
0
|
|
0
|
Edit
Delete
|
|
36417
|
24653
|
121
|
5
|
495fc74942c3d101613165202d9e5b8016969eb8
|
0
|
acceptance
|
1
|
name: Kernel V1.0 CI
"on":
push:
name: Kernel V1.0 CI
"on":
push:
branches: [main]
pull_request:
workflow_dispatch:
jobs:
acceptance:
name: acceptance
runs-on: ubuntu-latest
steps:
- name: Checkout fixed source
uses: https://gitea.com/actions/checkout@v4
with:
fetch-depth: "0"
persist-credentials: "false"
- name: Use Node.js 22
uses: https://gitea.com/actions/setup-node@v4
with:
node-version: "22"
- name: Install locked dependencies
run: |
set -eu
corepack enable
corepack prepare pnpm@9.15.9 --activate
pnpm install --frozen-lockfile
- name: Check documentation claims
run: node scripts/check-doc-claims.js
- name: Check invariants
run: node scripts/check-invariants.js
- name: Check module boundaries
run: node scripts/check-module-boundaries.js
- name: Check model
run: node scripts/check-model.js
- name: Check spec source
run: node scripts/check-spec-source.js
- name: Check full spec
run: node scripts/check-full-spec.js
- name: Check cross-owner write exceptions
run: node scripts/check-cross-owner-writes.js
- name: Check plan ledger against Git history
run: pnpm check:plan-ledger
- name: Configure isolated database roles
run: |
set -eu
node --input-type=module <<'NODE'
import { randomBytes } from 'node:crypto';
import { appendFileSync } from 'node:fs';
import { readFileSync } from 'node:fs';
import pg from 'pg';
const runtimePassword = randomBytes(24).toString('hex');
const tokenSecret = randomBytes(32).toString('hex');
const migrationTestDatabase = `erk_migration_test_${randomBytes(6).toString('hex')}`;
const port = Number(process.env.CI_POSTGRES_PORT);
if (!Number.isInteger(port) || port < 1 || port > 65535) {
throw new Error('PostgreSQL service did not publish a valid port');
}
const defaultRoute = readFileSync('/proc/net/route', 'utf8').split('\n').find((line) => line.split('\t')[1] === '00000000');
const gatewayHex = defaultRoute?.split('\t')[2];
const gateway = gatewayHex && gatewayHex.length === 8
? gatewayHex.match(/../g).reverse().map((part) => parseInt(part, 16)).join('.')
: null;
const hosts = ['127.0.0.1', 'host.docker.internal', gateway].filter(Boolean);
let admin;
let client;
for (const host of hosts) {
const candidate = new URL(`postgres://postgres@${host}:${port}/enterprise_reality_kernel`);
candidate.password = process.env.CI_ADMIN_PASSWORD;
const probe = new pg.Client({ connectionString: candidate.href, connectionTimeoutMillis: 2000 });
try {
await probe.connect();
const identity = await probe.query('SELECT current_database() AS name, current_user AS role');
if (identity.rows[0]?.name !== 'enterprise_reality_kernel' || identity.rows[0]?.role !== 'postgres') {
throw new Error('Unexpected PostgreSQL service identity');
}
admin = candidate;
client = probe;
break;
} catch {
await probe.end().catch(() => {});
}
}
if (!admin || !client) throw new Error('Disposable PostgreSQL service is unreachable from this runner');
const runtime = new URL(admin.href);
runtime.username = 'erk_app';
runtime.password = runtimePassword;
try {
await client.query(`CREATE DATABASE ${migrationTestDatabase}`);
} finally {
await client.end();
}
const migrationTest = new URL(admin.href);
migrationTest.pathname = `/${migrationTestDatabase}`;
appendFileSync(process.env.GITHUB_ENV, [
`MIGRATION_DATABASE_URL=${admin.href}`,
`MIGRATION_TEST_DATABASE_URL=${migrationTest.href}`,
`DATABASE_URL=${runtime.href}`,
`TEST_DATABASE_URL=${runtime.href}`,
`RUNTIME_DB_PASSWORD=${runtimePassword}`,
`KERNEL_TOKEN_SECRET=${tokenSecret}`
].join('\n') + '\n');
NODE
env:
CI_ADMIN_PASSWORD: erk_ci_disposable_admin
CI_POSTGRES_PORT: '55432'
- name: Migrate as postgres owner
run: pnpm db:migrate
- name: Test as restricted erk_app
run: pnpm test
- name: Check database roles and cross-owner references
run: |
set -eu
pnpm check:db-roles
pnpm check:cross-refs
pnpm check:cross-fks
- name: Check event histories
run: |
set -eu
pnpm check:all-events
pnpm check:integration-events
pnpm check:external-sales-order-history
pnpm check:schedule-history
pnpm check:trigger-condition-history
pnpm check:trigger-authorization-history
pnpm check:trigger-state-history
- name: Check partitions and audit chain
run: |
set -eu
pnpm check:partition-identities
pnpm check:partition-references
pnpm check:partition-horizon
pnpm check:partition-cutover
pnpm check:audit-chain
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_DB: enterprise_reality_kernel
POSTGRES_PASSWORD: erk_ci_disposable_admin
POSTGRES_USER: postgres
ports:
- 55432:5432
options: --health-cmd "pg_isready -U postgres -d enterprise_reality_kernel" --health-interval 2s --health-timeout 3s --health-retries 30
permissions:
contents: read
...
|
acceptance
|
null
|
["ubuntu-latest"]
|
30780
|
2
|
1790701525
|
1790701542
|
1790701524
|
1790701542
|
|
0
|
|
0
|
Edit
Delete
|
|
39739
|
25635
|
116
|
5
|
4997793143353073b38f2633c9424924b3f976ca
|
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"]
|
33090
|
2
|
1791821563
|
1791821976
|
1791821561
|
1791821977
|
|
0
|
|
0
|
Edit
Delete
|
|
39740
|
25635
|
116
|
5
|
4997793143353073b38f2633c9424924b3f976ca
|
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"]
|
33091
|
2
|
1791821977
|
1791821990
|
1791821561
|
1791821990
|
|
0
|
|
0
|
Edit
Delete
|
|
39741
|
25635
|
116
|
5
|
4997793143353073b38f2633c9424924b3f976ca
|
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"]
|
33094
|
4
|
1791822057
|
1791822057
|
1791821561
|
1791822057
|
|
1
|
|
0
|
Edit
Delete
|
|
39742
|
25635
|
116
|
5
|
4997793143353073b38f2633c9424924b3f976ca
|
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"]
|
33095
|
4
|
1791822059
|
1791822059
|
1791821561
|
1791822059
|
|
1
|
|
0
|
Edit
Delete
|
|
39743
|
25635
|
116
|
5
|
4997793143353073b38f2633c9424924b3f976ca
|
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"]
|
33096
|
4
|
1791822061
|
1791822061
|
1791821561
|
1791822061
|
|
1
|
|
0
|
Edit
Delete
|
|
39744
|
25635
|
116
|
5
|
4997793143353073b38f2633c9424924b3f976ca
|
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"]
|
33097
|
4
|
1791822063
|
1791822063
|
1791821561
|
1791822063
|
|
1
|
|
0
|
Edit
Delete
|
|
39745
|
25635
|
116
|
5
|
4997793143353073b38f2633c9424924b3f976ca
|
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"]
|
33098
|
4
|
1791822065
|
1791822065
|
1791821561
|
1791822065
|
|
1
|
|
0
|
Edit
Delete
|
|
39746
|
25635
|
116
|
5
|
4997793143353073b38f2633c9424924b3f976ca
|
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"]
|
33104
|
2
|
1791822077
|
1791822092
|
1791821561
|
1791822092
|
|
1
|
|
0
|
Edit
Delete
|
|
23739
|
17873
|
6
|
5
|
49ceca46def207082a6f7c5bf4718306d971843a
|
0
|
Frontend Type Check
|
1
|
name: CI
"on":
push:
branches: name: CI
"on":
push:
branches: [main]
pull_request:
branches: [main]
env:
NODE_VERSION: "20"
PNPM_VERSION: "9"
jobs:
frontend-typecheck:
name: Frontend Type Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- run: pnpm install --frozen-lockfile
- name: Build shared package
run: pnpm -C shared run build
- name: 前端类型检查(vue-tsc --noEmit)
run: pnpm --filter ./frontend run type-check
permissions:
contents: read
...
|
frontend-typecheck
|
null
|
["ubuntu-latest"]
|
20456
|
2
|
1777247080
|
1777247100
|
1777247078
|
1777247100
|
|
0
|
|
0
|
Edit
Delete
|
|
23740
|
17873
|
6
|
5
|
49ceca46def207082a6f7c5bf4718306d971843a
|
0
|
Lint & Type Check
|
1
|
name: CI
"on":
push:
branches: name: CI
"on":
push:
branches: [main]
pull_request:
branches: [main]
env:
NODE_VERSION: "20"
PNPM_VERSION: "9"
jobs:
lint-and-typecheck:
name: Lint & Type Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- run: pnpm install --frozen-lockfile
- name: Generate Prisma Client
run: pnpm -C backend exec prisma generate
- name: Build shared package
run: pnpm -C shared run build
- name: Backend type check
run: pnpm -C backend run type-check
- name: Lint
run: pnpm -C backend run lint
permissions:
contents: read
...
|
lint-and-typecheck
|
null
|
["ubuntu-latest"]
|
20457
|
2
|
1777247100
|
1777247205
|
1777247078
|
1777247205
|
|
0
|
|
0
|
Edit
Delete
|
|
23741
|
17873
|
6
|
5
|
49ceca46def207082a6f7c5bf4718306d971843a
|
0
|
Unit Tests
|
0
|
name: CI
"on":
push:
branches: name: CI
"on":
push:
branches: [main]
pull_request:
branches: [main]
env:
NODE_VERSION: "20"
PNPM_VERSION: "9"
jobs:
test:
name: Unit Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- run: pnpm install --frozen-lockfile
- name: Generate Prisma Client
run: pnpm -C backend exec prisma generate
- name: Build shared package
run: pnpm -C shared run build
- name: Run unit tests
run: pnpm -C backend run test:unit
permissions:
contents: read
...
|
test
|
["frontend-typecheck","lint-and-typech ["frontend-typecheck","lint-and-typecheck"]...
|
["ubuntu-latest"]
|
0
|
4
|
0
|
0
|
1777247078
|
1777247207
|
|
1
|
|
0
|
Edit
Delete
|
|
23742
|
17873
|
6
|
5
|
49ceca46def207082a6f7c5bf4718306d971843a
|
0
|
Governance Audit (HIGH=0 gate)
|
0
|
name: CI
"on":
push:
branches: name: CI
"on":
push:
branches: [main]
pull_request:
branches: [main]
env:
NODE_VERSION: "20"
PNPM_VERSION: "9"
jobs:
governance-audit:
name: Governance Audit (HIGH=0 gate)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- run: pnpm install --frozen-lockfile
- name: Generate Prisma Client
run: pnpm -C backend exec prisma generate
- name: Build shared package
run: pnpm -C shared run build
- name: Audit Prisma↔Zod 契约
run: pnpm -C backend run audit:prisma-zod-contract
continue-on-error: true
- name: Audit FormRules↔Zod
run: pnpm run audit:formrules-zod
continue-on-error: true
- name: Audit Response Columns
run: pnpm run audit:response-columns
continue-on-error: true
- name: Audit Field Payload
run: pnpm run audit:field-payload
continue-on-error: true
- name: Audit Enum Consistency
run: pnpm run audit:enum-consistency
continue-on-error: true
- name: Harness Report 聚合
run: pnpm harness report
continue-on-error: true
- if: always()
name: Upload audit reports
uses: actions/upload-artifact@v4
with:
name: governance-audit-reports
path: |
reports/prisma-zod-contract-audit.latest.json
reports/formrules-zod-audit.latest.json
reports/response-columns-audit.latest.json
reports/field-payload-audit.latest.json
reports/enum-consistency-audit.latest.json
reports/harness-dashboard.latest.json
reports/module-grades.latest.json
retention-days: "14"
- if: always()
name: 输出 governance summary
run: |
if [ -f reports/harness-dashboard.latest.json ]; then
node -e "
const d = require('./reports/harness-dashboard.latest.json');
const s = d.summary || {};
const lines = [
'## Governance Audit Summary',
'',
'| Severity | Count |',
'|---|---|',
\`| CRITICAL | \${s.critical ?? 0} |\`,
\`| HIGH | \${s.high ?? 0} |\`,
\`| MEDIUM | \${s.medium ?? 0} |\`,
\`| LOW | \${s.low ?? 0} |\`,
\`| INFO | \${s.info ?? 0} |\`,
'',
\`- 总 finding: \${s.total ?? 0}\`,
\`- 涉及模块: \${s.modulesAffected ?? 0}\`,
\`- 审计执行: \${s.auditsRun ?? 0}\`,
'',
'**HIGH+CRITICAL 必须为 0;任何新增高危 finding 阻塞 PR 合并。**',
];
require('fs').appendFileSync(process.env.GITHUB_STEP_SUMMARY, lines.join('\n') + '\n');
"
else
echo '⚠️ harness-dashboard.latest.json 未生成,治理门禁判定失败' >> $GITHUB_STEP_SUMMARY
fi
- name: 校验 HIGH+CRITICAL 必须为 0
run: |
if [ ! -f reports/harness-dashboard.latest.json ]; then
echo "::error::治理门禁失败:harness-dashboard 未生成"
exit 1
fi
node -e "
const d = require('./reports/harness-dashboard.latest.json');
const s = d.summary || {};
const blocking = (s.high || 0) + (s.critical || 0);
if (blocking > 0) {
console.error('::error::治理门禁失败:HIGH+CRITICAL = ' + blocking + ',必须为 0');
console.error('详见 governance-audit-reports artifact 中的 harness-dashboard.latest.json');
process.exit(1);
}
console.log('治理门禁通过:HIGH+CRITICAL = 0');
"
permissions:
contents: read
...
|
governance-audit
|
["lint-and-typecheck"]
|
["ubuntu-latest"]
|
0
|
4
|
0
|
0
|
1777247078
|
1777247207
|
|
1
|
|
0
|
Edit
Delete
|
|
23743
|
17873
|
6
|
5
|
49ceca46def207082a6f7c5bf4718306d971843a
|
0
|
Build Docker Images
|
1
|
name: CI
"on":
push:
branches: name: CI
"on":
push:
branches: [main]
pull_request:
branches: [main]
env:
NODE_VERSION: "20"
PNPM_VERSION: "9"
jobs:
build:
name: Build Docker Images
runs-on: ubuntu-latest
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
password: ${{ secrets.GITHUB_TOKEN }}
registry: ghcr.io
username: ${{ github.actor }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build API image
uses: docker/build-push-action@v6
with:
cache-from: type=gha
cache-to: type=gha,mode=max
context: .
file: backend/Dockerfile
load: "true"
push: "false"
tags: |
ghcr.io/${{ github.repository_owner }}/juhi-api:latest
ghcr.io/${{ github.repository_owner }}/juhi-api:${{ github.sha }}
- name: Build Frontend image
uses: docker/build-push-action@v6
with:
cache-from: type=gha
cache-to: type=gha,mode=max
context: .
file: frontend/Dockerfile
load: "true"
push: "false"
tags: |
ghcr.io/${{ github.repository_owner }}/juhi-frontend:latest
ghcr.io/${{ github.repository_owner }}/juhi-frontend:${{ github.sha }}
- id: trivy-api
name: Trivy 扫描 API 镜像
uses: aquasecurity/trivy-action@0.28.0
with:
exit-code: "1"
format: sarif
image-ref: ghcr.io/${{ github.repository_owner }}/juhi-api:${{ github.sha }}
output: trivy-api-results.sarif
severity: MEDIUM,HIGH,CRITICAL
- id: trivy-frontend
if: always()
name: Trivy 扫描前端镜像
uses: aquasecurity/trivy-action@0.28.0
with:
exit-code: "1"
format: sarif
image-ref: ghcr.io/${{ github.repository_owner }}/juhi-frontend:${{ github.sha }}
output: trivy-frontend-results.sarif
severity: MEDIUM,HIGH,CRITICAL
- if: always()
name: 上传 API 镜像安全扫描报告到 GitHub Security
uses: github/codeql-action/upload-sarif@v3
with:
category: trivy-api-image
sarif_file: trivy-api-results.sarif
- if: always()
name: 上传前端镜像安全扫描报告到 GitHub Security
uses: github/codeql-action/upload-sarif@v3
with:
category: trivy-frontend-image
sarif_file: trivy-frontend-results.sarif
- id: trivy-gate
if: always()
name: 检查 Trivy 扫描结果
run: |
# 任一镜像扫描失败则阻断后续推送
if [ "${{ steps.trivy-api.outcome }}" != "success" ] || [ "${{ steps.trivy-frontend.outcome }}" != "success" ]; then
echo "scan_passed=false" >> $GITHUB_OUTPUT
echo "::error::Trivy 安全扫描未通过,阻断镜像推送"
else
echo "scan_passed=true" >> $GITHUB_OUTPUT
fi
- if: always()
name: 生成 API 镜像 SBOM
uses: anchore/sbom-action@v0
with:
artifact-name: sbom-api
format: spdx-json
image: ghcr.io/${{ github.repository_owner }}/juhi-api:${{ github.sha }}
output-file: sbom-api.spdx.json
- if: always()
name: 生成前端镜像 SBOM
uses: anchore/sbom-action@v0
with:
artifact-name: sbom-frontend
format: spdx-json
image: ghcr.io/${{ github.repository_owner }}/juhi-frontend:${{ github.sha }}
output-file: sbom-frontend.spdx.json
- if: steps.trivy-gate.outputs.scan_passed == 'true'
name: Push API image
run: |
docker push ghcr.io/${{ github.repository_owner }}/juhi-api:latest
docker push ghcr.io/${{ github.repository_owner }}/juhi-api:${{ github.sha }}
- if: steps.trivy-gate.outputs.scan_passed == 'true'
name: Push Frontend image
run: |
docker push ghcr.io/${{ github.repository_owner }}/juhi-frontend:latest
docker push ghcr.io/${{ github.repository_owner }}/juhi-frontend:${{ github.sha }}
- if: steps.trivy-gate.outputs.scan_passed != 'true'
name: 扫描未通过时终止流水线
run: |
echo "Trivy 扫描发现安全漏洞,镜像未推送"
exit 1
permissions:
contents: read
packages: write
security-events: write # 上传 SARIF 安全报告所需权限
...
|
build
|
["frontend-typecheck","lint-and-typech ["frontend-typecheck","lint-and-typecheck","test","governance-audit"]...
|
["ubuntu-latest"]
|
20468
|
4
|
1777247903
|
1777247904
|
1777247078
|
1777247904
|
|
1
|
|
0
|
Edit
Delete
|
|
23744
|
17874
|
6
|
5
|
49ceca46def207082a6f7c5bf4718306d971843a
|
0
|
pr-validation
|
1
|
name: E2E Tests
"on":
# PR validation name: E2E Tests
"on":
# PR validation - 运行关键测试
pull_request:
branches: [main, develop]
paths:
- 'frontend/**'
- 'backend/**'
- 'e2e/**'
- 'package.json'
- 'pnpm-lock.yaml'
# Push to main - 运行完整测试套件
push:
branches: [main]
# 每日定时全量测试 (UTC 时间 00:00 = 北京时间 08:00)
schedule:
- cron: '0 0 * * *'
# 手动触发
workflow_dispatch:
inputs:
test_suite:
description: 'Test suite to run'
required: true
default: 'all'
type: choice
options:
- all
- critical
- business-flows
- visual-regression
- performance
env:
NODE_VERSION: "20"
PNPM_VERSION: "9"
jobs:
pr-validation:
name: pr-validation
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Setup test database
run: |
cd backend
npx prisma migrate deploy
npx prisma db seed
env:
DATABASE_URL: postgresql://test_user:test_password@localhost:5432/juhi_test
- name: Build backend
run: |
cd backend
npm run build
- name: Build frontend
run: |
cd frontend
npm run build
- name: Install Playwright Browsers
run: npx playwright install --with-deps chromium
- name: Start backend server
run: |
cd backend
npm run start &
sleep 10
env:
DATABASE_URL: postgresql://test_user:test_password@localhost:5432/juhi_test
REDIS_URL: redis://localhost:6379
NODE_ENV: test
- name: Start frontend server
run: |
cd frontend
npm run preview &
sleep 5
env:
VITE_API_URL: http://localhost:3000
- name: Run critical E2E tests
run: |
cd e2e
npx playwright test \
tests/auth/login.spec.ts \
tests/navigation/full-menu-click.spec.ts \
tests/multi-tenant/data-isolation.spec.ts \
tests/form-interactions/ \
--reporter=html
env:
E2E_BASE_URL: http://localhost:5173
E2E_TEST_USER: admin@juhi.com
E2E_TEST_PASSWORD: Admin@123
- if: always()
name: Upload test results
uses: actions/upload-artifact@v4
with:
name: playwright-report-pr
path: e2e/playwright-report/
retention-days: "7"
- if: always() && github.event_name == 'pull_request'
name: Comment PR with test results
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const reportPath = 'e2e/playwright-report/index.html';
const testsPassed = !fs.existsSync('e2e/test-results/');
const comment = testsPassed
? '✅ E2E 测试通过!'
: '❌ E2E 测试失败,请查看报告';
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: comment
});
timeout-minutes: "30"
services:
postgres:
image: postgres:15
env:
POSTGRES_DB: juhi_test
POSTGRES_PASSWORD: test_password
POSTGRES_USER: test_user
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
redis:
image: redis:7
ports:
- 6379:6379
options: --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5
...
|
pr-validation
|
null
|
["ubuntu-latest"]
|
20458
|
4
|
1777247205
|
1777247206
|
1777247079
|
1777247206
|
|
0
|
|
0
|
Edit
Delete
|