|
40579
|
25793
|
116
|
5
|
8d8ac0538d35eaaa2fe0e103f55fb38a81ceec5b
|
0
|
Static governance (repo root, private packages)
|
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:
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: 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.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: 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"]
|
0
|
3
|
0
|
1791857663
|
1791857239
|
1791857663
|
|
0
|
|
0
|
Edit
Delete
|
|
40580
|
25793
|
116
|
5
|
8d8ac0538d35eaaa2fe0e103f55fb38a81ceec5b
|
0
|
Unit tests without DB (modules / packages / govern Unit tests without DB (modules / packages / governance)...
|
0
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
unit:
name: Unit tests without DB (modules / packages / governance)
runs-on: ubuntu-latest
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
steps:
- uses: 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.GITEA_NPM_TOKEN }}
- name: Install runtime workspace (frozen lockfile)
run: pnpm --dir runtime install --frozen-lockfile
- name: Generate clients for authority module unit imports (no database)
run: pnpm --dir runtime prisma:generate
- name: Module / package unit tests
run: pnpm --dir runtime exec turbo run test --filter='./modules/*' --filter='./packages/*' --filter='./clients/*' --force
- name: Governance package tests
run: pnpm governance:test
timeout-minutes: "20"
permissions:
contents: read
...
|
unit
|
["static"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1791857663
|
1791857239
|
1791857663
|
|
0
|
|
0
|
Edit
Delete
|
|
40581
|
25793
|
116
|
5
|
8d8ac0538d35eaaa2fe0e103f55fb38a81ceec5b
|
0
|
Port conformance (kernel / modules / clients)
|
0
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
port-conformance:
name: Port conformance (kernel / modules / clients)
runs-on: ubuntu-latest
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
steps:
- uses: 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.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: 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"]
|
0
|
3
|
0
|
1791857663
|
1791857239
|
1791857663
|
|
0
|
|
0
|
Edit
Delete
|
|
40582
|
25793
|
116
|
5
|
8d8ac0538d35eaaa2fe0e103f55fb38a81ceec5b
|
0
|
Runtime and UI acceptance (real PostgreSQL + Redis Runtime and UI acceptance (real PostgreSQL + Redis)...
|
0
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
runtime:
name: Runtime and UI acceptance (real PostgreSQL + Redis)
runs-on: ubuntu-latest
env:
# 库名前缀由 runtime/package.json name 派生(G15 基座守卫:enterprise_platform*)
DATABASE_URL: postgresql://postgres:postgres@127.0.0.1:5432/enterprise_platform_ci?schema=public
REDIS_URL: redis://127.0.0.1:6379
KAFKA_BROKERS: 127.0.0.1:59092
MAINLINE_CHAOS_CONTAINER: enterprise-platform-ms23-ci-redpanda-1
# 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: 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.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: 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"]
|
0
|
3
|
0
|
1791857663
|
1791857239
|
1791857663
|
|
0
|
|
0
|
Edit
Delete
|
|
40583
|
25793
|
116
|
5
|
8d8ac0538d35eaaa2fe0e103f55fb38a81ceec5b
|
0
|
M1 identity transitional workspace (IdP static → E M1 identity transitional workspace (IdP static → E2 → governance)...
|
0
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
identity:
name: M1 identity transitional workspace (IdP static → E2 → governance)
runs-on: ubuntu-latest
env:
# 库名前缀由 identity/package.json name 派生(enterprise_idp*);Redis 必须 db 0(老框架 C22)
DATABASE_URL: postgresql://postgres:postgres@127.0.0.1:5432/enterprise_idp_ci?schema=public
REDIS_URL: redis://127.0.0.1:6379/0
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
steps:
- uses: 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.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: 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"]
|
0
|
3
|
0
|
1791857663
|
1791857239
|
1791857663
|
|
0
|
|
0
|
Edit
Delete
|
|
40584
|
25793
|
116
|
5
|
8d8ac0538d35eaaa2fe0e103f55fb38a81ceec5b
|
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: 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.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: 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"]
|
0
|
3
|
0
|
1791857663
|
1791857239
|
1791857663
|
|
0
|
|
0
|
Edit
Delete
|
|
40585
|
25793
|
116
|
5
|
8d8ac0538d35eaaa2fe0e103f55fb38a81ceec5b
|
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: 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"]
|
0
|
3
|
0
|
1791857663
|
1791857239
|
1791857663
|
|
0
|
|
0
|
Edit
Delete
|
|
40587
|
25795
|
116
|
5
|
10b7b9d9a85ff43bd1a633e8c64b83ca08748bd4
|
0
|
Public static checks (no private packages)
|
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:
public-static:
name: Public static checks (no private packages)
runs-on: ubuntu-latest
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:
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"]
|
0
|
3
|
0
|
1791857848
|
1791857663
|
1791857848
|
|
0
|
|
0
|
Edit
Delete
|
|
40588
|
25795
|
116
|
5
|
10b7b9d9a85ff43bd1a633e8c64b83ca08748bd4
|
0
|
Static governance (repo root, private packages)
|
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:
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: 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.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: 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"]
|
0
|
3
|
0
|
1791857848
|
1791857663
|
1791857848
|
|
0
|
|
0
|
Edit
Delete
|
|
40589
|
25795
|
116
|
5
|
10b7b9d9a85ff43bd1a633e8c64b83ca08748bd4
|
0
|
Unit tests without DB (modules / packages / govern Unit tests without DB (modules / packages / governance)...
|
0
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
unit:
name: Unit tests without DB (modules / packages / governance)
runs-on: ubuntu-latest
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
steps:
- uses: 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.GITEA_NPM_TOKEN }}
- name: Install runtime workspace (frozen lockfile)
run: pnpm --dir runtime install --frozen-lockfile
- name: Generate clients for authority module unit imports (no database)
run: pnpm --dir runtime prisma:generate
- name: Module / package unit tests
run: pnpm --dir runtime exec turbo run test --filter='./modules/*' --filter='./packages/*' --filter='./clients/*' --force
- name: Governance package tests
run: pnpm governance:test
timeout-minutes: "20"
permissions:
contents: read
...
|
unit
|
["static"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1791857848
|
1791857663
|
1791857848
|
|
0
|
|
0
|
Edit
Delete
|
|
40590
|
25795
|
116
|
5
|
10b7b9d9a85ff43bd1a633e8c64b83ca08748bd4
|
0
|
Port conformance (kernel / modules / clients)
|
0
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
port-conformance:
name: Port conformance (kernel / modules / clients)
runs-on: ubuntu-latest
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
steps:
- uses: 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.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: 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"]
|
0
|
3
|
0
|
1791857848
|
1791857663
|
1791857848
|
|
0
|
|
0
|
Edit
Delete
|
|
40591
|
25795
|
116
|
5
|
10b7b9d9a85ff43bd1a633e8c64b83ca08748bd4
|
0
|
Runtime and UI acceptance (real PostgreSQL + Redis Runtime and UI acceptance (real PostgreSQL + Redis)...
|
0
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
runtime:
name: Runtime and UI acceptance (real PostgreSQL + Redis)
runs-on: ubuntu-latest
env:
# 库名前缀由 runtime/package.json name 派生(G15 基座守卫:enterprise_platform*)
DATABASE_URL: postgresql://postgres:postgres@127.0.0.1:5432/enterprise_platform_ci?schema=public
REDIS_URL: redis://127.0.0.1:6379
KAFKA_BROKERS: 127.0.0.1:59092
MAINLINE_CHAOS_CONTAINER: enterprise-platform-ms23-ci-redpanda-1
# 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: 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.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: 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"]
|
0
|
3
|
0
|
1791857848
|
1791857663
|
1791857848
|
|
0
|
|
0
|
Edit
Delete
|
|
40592
|
25795
|
116
|
5
|
10b7b9d9a85ff43bd1a633e8c64b83ca08748bd4
|
0
|
M1 identity transitional workspace (IdP static → E M1 identity transitional workspace (IdP static → E2 → governance)...
|
0
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
identity:
name: M1 identity transitional workspace (IdP static → E2 → governance)
runs-on: ubuntu-latest
env:
# 库名前缀由 identity/package.json name 派生(enterprise_idp*);Redis 必须 db 0(老框架 C22)
DATABASE_URL: postgresql://postgres:postgres@127.0.0.1:5432/enterprise_idp_ci?schema=public
REDIS_URL: redis://127.0.0.1:6379/0
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
steps:
- uses: 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.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: 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"]
|
0
|
3
|
0
|
1791857848
|
1791857663
|
1791857848
|
|
0
|
|
0
|
Edit
Delete
|
|
40593
|
25795
|
116
|
5
|
10b7b9d9a85ff43bd1a633e8c64b83ca08748bd4
|
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: 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.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: 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"]
|
0
|
3
|
0
|
1791857848
|
1791857663
|
1791857848
|
|
0
|
|
0
|
Edit
Delete
|
|
40594
|
25795
|
116
|
5
|
10b7b9d9a85ff43bd1a633e8c64b83ca08748bd4
|
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: 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"]
|
0
|
3
|
0
|
1791857848
|
1791857663
|
1791857848
|
|
0
|
|
0
|
Edit
Delete
|
|
40242
|
25730
|
139
|
5
|
c850b930e6ba138125429b7e5c93fc707a7f8427
|
0
|
Build (ubuntu-latest)
|
1
|
name: Test
"on":
push:
paths-i name: Test
"on":
push:
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
build:
name: Build (ubuntu-latest)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node 20
uses: actions/setup-node@v4
with:
cache: npm
node-version: 20.x
- name: npm install
run: npm install
- name: Compile
run: npm run build
- name: Lint
run: npm run lint
- name: Format
run: npm run format-check
- name: Create artifacts
run: |
mkdir -p path/to/artifact-A
mkdir -p path/to/artifact-B
echo "Lorem ipsum dolor sit amet" > path/to/artifact-A/file-A.txt
echo "Hello world from file B" > path/to/artifact-B/file-B.txt
- name: Upload artifact A
uses: actions/upload-artifact@v4
with:
name: Artifact-A-${{ matrix.runs-on }}
path: path/to/artifact-A
- name: Upload artifact B
uses: actions/upload-artifact@v4
with:
name: Artifact-B-${{ matrix.runs-on }}
path: path/to/artifact-B
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: some/new/path
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: ~/some/path/with/a/tilde
- name: Verify successful download
run: |
$file1 = "some/new/path/file-A.txt"
$file2 = "~/some/path/with/a/tilde/file-A.txt"
if(!(Test-Path -path $file1) -or !(Test-Path -path $file2))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $file1) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $file2) -ceq "Lorem ipsum dolor sit amet"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
path: some/other/path
- name: Verify successful download
run: |
$fileA = "some/other/path/Artifact-A-${{ matrix.runs-on }}/file-A.txt"
$fileB = "some/other/path/Artifact-B-${{ matrix.runs-on }}/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
merge-multiple: "true"
path: single/directory
pattern: Artifact-*
- name: Verify successful download
run: |
$fileA = "single/directory/file-A.txt"
$fileB = "single/directory/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
strategy:
fail-fast: "false"
matrix:
runs-on:
- ubuntu-latest
...
|
build
|
null
|
["ubuntu-latest"]
|
33359
|
2
|
1791857048
|
1791858083
|
1791844745
|
1791858083
|
|
0
|
|
0
|
Edit
Delete
|
|
40245
|
25731
|
139
|
5
|
8caf195ad4b1dee92908e23f56eeb0696f1dd42d
|
0
|
Build (ubuntu-latest)
|
1
|
name: Test
"on":
push:
paths-i name: Test
"on":
push:
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
build:
name: Build (ubuntu-latest)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node 20
uses: actions/setup-node@v4
with:
cache: npm
node-version: 20.x
- name: npm install
run: npm install
- name: Compile
run: npm run build
- name: Lint
run: npm run lint
- name: Format
run: npm run format-check
- name: Create artifacts
run: |
mkdir -p path/to/artifact-A
mkdir -p path/to/artifact-B
echo "Lorem ipsum dolor sit amet" > path/to/artifact-A/file-A.txt
echo "Hello world from file B" > path/to/artifact-B/file-B.txt
- name: Upload artifact A
uses: actions/upload-artifact@v4
with:
name: Artifact-A-${{ matrix.runs-on }}
path: path/to/artifact-A
- name: Upload artifact B
uses: actions/upload-artifact@v4
with:
name: Artifact-B-${{ matrix.runs-on }}
path: path/to/artifact-B
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: some/new/path
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: ~/some/path/with/a/tilde
- name: Verify successful download
run: |
$file1 = "some/new/path/file-A.txt"
$file2 = "~/some/path/with/a/tilde/file-A.txt"
if(!(Test-Path -path $file1) -or !(Test-Path -path $file2))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $file1) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $file2) -ceq "Lorem ipsum dolor sit amet"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
path: some/other/path
- name: Verify successful download
run: |
$fileA = "some/other/path/Artifact-A-${{ matrix.runs-on }}/file-A.txt"
$fileB = "some/other/path/Artifact-B-${{ matrix.runs-on }}/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
merge-multiple: "true"
path: single/directory
pattern: Artifact-*
- name: Verify successful download
run: |
$fileA = "single/directory/file-A.txt"
$fileB = "single/directory/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
strategy:
fail-fast: "false"
matrix:
runs-on:
- ubuntu-latest
...
|
build
|
null
|
["ubuntu-latest"]
|
33360
|
2
|
1791858083
|
1791858112
|
1791844746
|
1791858112
|
|
0
|
|
0
|
Edit
Delete
|
|
40248
|
25732
|
139
|
5
|
9c19ed7fe5d278cd354c7dfd5d3b88589c7e2395
|
0
|
Build (ubuntu-latest)
|
1
|
name: Test
"on":
push:
paths-i name: Test
"on":
push:
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
build:
name: Build (ubuntu-latest)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node 20
uses: actions/setup-node@v4
with:
cache: npm
node-version: 20.x
- name: npm install
run: npm install
- name: Compile
run: npm run build
- name: Lint
run: npm run lint
- name: Format
run: npm run format-check
- name: Create artifacts
run: |
mkdir -p path/to/artifact-A
mkdir -p path/to/artifact-B
echo "Lorem ipsum dolor sit amet" > path/to/artifact-A/file-A.txt
echo "Hello world from file B" > path/to/artifact-B/file-B.txt
- name: Upload artifact A
uses: actions/upload-artifact@v4
with:
name: Artifact-A-${{ matrix.runs-on }}
path: path/to/artifact-A
- name: Upload artifact B
uses: actions/upload-artifact@v4
with:
name: Artifact-B-${{ matrix.runs-on }}
path: path/to/artifact-B
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: some/new/path
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: ~/some/path/with/a/tilde
- name: Verify successful download
run: |
$file1 = "some/new/path/file-A.txt"
$file2 = "~/some/path/with/a/tilde/file-A.txt"
if(!(Test-Path -path $file1) -or !(Test-Path -path $file2))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $file1) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $file2) -ceq "Lorem ipsum dolor sit amet"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
path: some/other/path
- name: Verify successful download
run: |
$fileA = "some/other/path/Artifact-A-${{ matrix.runs-on }}/file-A.txt"
$fileB = "some/other/path/Artifact-B-${{ matrix.runs-on }}/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
merge-multiple: "true"
path: single/directory
pattern: Artifact-*
- name: Verify successful download
run: |
$fileA = "single/directory/file-A.txt"
$fileB = "single/directory/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
strategy:
fail-fast: "false"
matrix:
runs-on:
- ubuntu-latest
...
|
build
|
null
|
["ubuntu-latest"]
|
33361
|
2
|
1791858112
|
1791858140
|
1791844746
|
1791858140
|
|
0
|
|
0
|
Edit
Delete
|
|
40251
|
25733
|
139
|
5
|
65a9edc5881444af0b9093a5e628f2fe47ea3b2e
|
0
|
Build (ubuntu-latest)
|
1
|
name: Test
"on":
push:
paths-i name: Test
"on":
push:
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
build:
name: Build (ubuntu-latest)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node 20
uses: actions/setup-node@v4
with:
cache: npm
node-version: 20.x
- name: npm install
run: npm install
- name: Compile
run: npm run build
- name: Lint
run: npm run lint
- name: Format
run: npm run format-check
- name: Create artifacts
run: |
mkdir -p path/to/artifact-A
mkdir -p path/to/artifact-B
echo "Lorem ipsum dolor sit amet" > path/to/artifact-A/file-A.txt
echo "Hello world from file B" > path/to/artifact-B/file-B.txt
- name: Upload artifact A
uses: actions/upload-artifact@v4
with:
name: Artifact-A-${{ matrix.runs-on }}
path: path/to/artifact-A
- name: Upload artifact B
uses: actions/upload-artifact@v4
with:
name: Artifact-B-${{ matrix.runs-on }}
path: path/to/artifact-B
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: some/new/path
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: ~/some/path/with/a/tilde
- name: Verify successful download
run: |
$file1 = "some/new/path/file-A.txt"
$file2 = "~/some/path/with/a/tilde/file-A.txt"
if(!(Test-Path -path $file1) -or !(Test-Path -path $file2))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $file1) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $file2) -ceq "Lorem ipsum dolor sit amet"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
path: some/other/path
- name: Verify successful download
run: |
$fileA = "some/other/path/Artifact-A-${{ matrix.runs-on }}/file-A.txt"
$fileB = "some/other/path/Artifact-B-${{ matrix.runs-on }}/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
merge-multiple: "true"
path: single/directory
pattern: Artifact-*
- name: Verify successful download
run: |
$fileA = "single/directory/file-A.txt"
$fileB = "single/directory/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
strategy:
fail-fast: "false"
matrix:
runs-on:
- ubuntu-latest
...
|
build
|
null
|
["ubuntu-latest"]
|
33362
|
2
|
1791858140
|
1791858168
|
1791844746
|
1791858168
|
|
0
|
|
0
|
Edit
Delete
|
|
40254
|
25734
|
139
|
5
|
fa0a91b85d4f404e444e00e005971372dc801d16
|
0
|
Build (ubuntu-latest)
|
1
|
name: Test
"on":
push:
paths-i name: Test
"on":
push:
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
build:
name: Build (ubuntu-latest)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node 20
uses: actions/setup-node@v4
with:
cache: npm
node-version: 20.x
- name: npm install
run: npm install
- name: Compile
run: npm run build
- name: Lint
run: npm run lint
- name: Format
run: npm run format-check
- name: Create artifacts
run: |
mkdir -p path/to/artifact-A
mkdir -p path/to/artifact-B
echo "Lorem ipsum dolor sit amet" > path/to/artifact-A/file-A.txt
echo "Hello world from file B" > path/to/artifact-B/file-B.txt
- name: Upload artifact A
uses: actions/upload-artifact@v4
with:
name: Artifact-A-${{ matrix.runs-on }}
path: path/to/artifact-A
- name: Upload artifact B
uses: actions/upload-artifact@v4
with:
name: Artifact-B-${{ matrix.runs-on }}
path: path/to/artifact-B
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: some/new/path
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: ~/some/path/with/a/tilde
- name: Verify successful download
run: |
$file1 = "some/new/path/file-A.txt"
$file2 = "~/some/path/with/a/tilde/file-A.txt"
if(!(Test-Path -path $file1) -or !(Test-Path -path $file2))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $file1) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $file2) -ceq "Lorem ipsum dolor sit amet"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
path: some/other/path
- name: Verify successful download
run: |
$fileA = "some/other/path/Artifact-A-${{ matrix.runs-on }}/file-A.txt"
$fileB = "some/other/path/Artifact-B-${{ matrix.runs-on }}/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
merge-multiple: "true"
path: single/directory
pattern: Artifact-*
- name: Verify successful download
run: |
$fileA = "single/directory/file-A.txt"
$fileB = "single/directory/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
strategy:
fail-fast: "false"
matrix:
runs-on:
- ubuntu-latest
...
|
build
|
null
|
["ubuntu-latest"]
|
33363
|
2
|
1791858168
|
1791858196
|
1791844746
|
1791858196
|
|
0
|
|
0
|
Edit
Delete
|
|
40257
|
25735
|
139
|
5
|
cc203385981b70ca67e1cc392babf9cc229d5806
|
0
|
Build (ubuntu-latest)
|
1
|
name: Test
"on":
push:
paths-i name: Test
"on":
push:
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
build:
name: Build (ubuntu-latest)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node 20
uses: actions/setup-node@v4
with:
cache: npm
node-version: 20.x
- name: npm install
run: npm install
- name: Compile
run: npm run build
- name: Lint
run: npm run lint
- name: Format
run: npm run format-check
- name: Create artifacts
run: |
mkdir -p path/to/artifact-A
mkdir -p path/to/artifact-B
echo "Lorem ipsum dolor sit amet" > path/to/artifact-A/file-A.txt
echo "Hello world from file B" > path/to/artifact-B/file-B.txt
- name: Upload artifact A
uses: actions/upload-artifact@v4
with:
name: Artifact-A-${{ matrix.runs-on }}
path: path/to/artifact-A
- name: Upload artifact B
uses: actions/upload-artifact@v4
with:
name: Artifact-B-${{ matrix.runs-on }}
path: path/to/artifact-B
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: some/new/path
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: ~/some/path/with/a/tilde
- name: Verify successful download
run: |
$file1 = "some/new/path/file-A.txt"
$file2 = "~/some/path/with/a/tilde/file-A.txt"
if(!(Test-Path -path $file1) -or !(Test-Path -path $file2))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $file1) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $file2) -ceq "Lorem ipsum dolor sit amet"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
path: some/other/path
- name: Verify successful download
run: |
$fileA = "some/other/path/Artifact-A-${{ matrix.runs-on }}/file-A.txt"
$fileB = "some/other/path/Artifact-B-${{ matrix.runs-on }}/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
merge-multiple: "true"
path: single/directory
pattern: Artifact-*
- name: Verify successful download
run: |
$fileA = "single/directory/file-A.txt"
$fileB = "single/directory/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
strategy:
fail-fast: "false"
matrix:
runs-on:
- ubuntu-latest
...
|
build
|
null
|
["ubuntu-latest"]
|
33364
|
2
|
1791858196
|
1791858224
|
1791844746
|
1791858224
|
|
0
|
|
0
|
Edit
Delete
|
|
40260
|
25736
|
139
|
5
|
b14cf4c92620c250e1c074ab0a5800e37df86765
|
0
|
Build (ubuntu-latest)
|
1
|
name: Test
"on":
push:
paths-i name: Test
"on":
push:
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
build:
name: Build (ubuntu-latest)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node 20
uses: actions/setup-node@v4
with:
cache: npm
node-version: 20.x
- name: npm install
run: npm install
- name: Compile
run: npm run build
- name: Lint
run: npm run lint
- name: Format
run: npm run format-check
- name: Create artifacts
run: |
mkdir -p path/to/artifact-A
mkdir -p path/to/artifact-B
echo "Lorem ipsum dolor sit amet" > path/to/artifact-A/file-A.txt
echo "Hello world from file B" > path/to/artifact-B/file-B.txt
- name: Upload artifact A
uses: actions/upload-artifact@v4
with:
name: Artifact-A-${{ matrix.runs-on }}
path: path/to/artifact-A
- name: Upload artifact B
uses: actions/upload-artifact@v4
with:
name: Artifact-B-${{ matrix.runs-on }}
path: path/to/artifact-B
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: some/new/path
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: ~/some/path/with/a/tilde
- name: Verify successful download
run: |
$file1 = "some/new/path/file-A.txt"
$file2 = "~/some/path/with/a/tilde/file-A.txt"
if(!(Test-Path -path $file1) -or !(Test-Path -path $file2))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $file1) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $file2) -ceq "Lorem ipsum dolor sit amet"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
path: some/other/path
- name: Verify successful download
run: |
$fileA = "some/other/path/Artifact-A-${{ matrix.runs-on }}/file-A.txt"
$fileB = "some/other/path/Artifact-B-${{ matrix.runs-on }}/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
merge-multiple: "true"
path: single/directory
pattern: Artifact-*
- name: Verify successful download
run: |
$fileA = "single/directory/file-A.txt"
$fileB = "single/directory/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
strategy:
fail-fast: "false"
matrix:
runs-on:
- ubuntu-latest
...
|
build
|
null
|
["ubuntu-latest"]
|
33365
|
2
|
1791858224
|
1791858251
|
1791844747
|
1791858251
|
|
0
|
|
0
|
Edit
Delete
|
|
40263
|
25737
|
139
|
5
|
95815c38cf2ff2164869cbab79da8d1f422bc89e
|
0
|
Build (ubuntu-latest)
|
1
|
name: Test
"on":
push:
paths-i name: Test
"on":
push:
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
build:
name: Build (ubuntu-latest)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node 20
uses: actions/setup-node@v4
with:
cache: npm
node-version: 20.x
- name: npm install
run: npm install
- name: Compile
run: npm run build
- name: Lint
run: npm run lint
- name: Format
run: npm run format-check
- name: Run Unit Tests
run: npm test
- name: Create artifacts
run: |
mkdir -p path/to/artifact-A
mkdir -p path/to/artifact-B
echo "Lorem ipsum dolor sit amet" > path/to/artifact-A/file-A.txt
echo "Hello world from file B" > path/to/artifact-B/file-B.txt
- name: Upload artifact A
uses: actions/upload-artifact@v4
with:
name: Artifact-A-${{ matrix.runs-on }}
path: path/to/artifact-A
- name: Upload artifact B
uses: actions/upload-artifact@v4
with:
name: Artifact-B-${{ matrix.runs-on }}
path: path/to/artifact-B
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: some/new/path
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: ~/some/path/with/a/tilde
- name: Verify successful download
run: |
$file1 = "some/new/path/file-A.txt"
$file2 = "~/some/path/with/a/tilde/file-A.txt"
if(!(Test-Path -path $file1) -or !(Test-Path -path $file2))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $file1) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $file2) -ceq "Lorem ipsum dolor sit amet"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
path: some/other/path
- name: Verify successful download
run: |
$fileA = "some/other/path/Artifact-A-${{ matrix.runs-on }}/file-A.txt"
$fileB = "some/other/path/Artifact-B-${{ matrix.runs-on }}/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
merge-multiple: "true"
path: single/directory
pattern: Artifact-*
- name: Verify successful download
run: |
$fileA = "single/directory/file-A.txt"
$fileB = "single/directory/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
strategy:
fail-fast: "false"
matrix:
runs-on:
- ubuntu-latest
...
|
build
|
null
|
["ubuntu-latest"]
|
33366
|
2
|
1791858252
|
1791858288
|
1791844747
|
1791858288
|
|
0
|
|
0
|
Edit
Delete
|
|
40266
|
25738
|
139
|
5
|
d3f86a106a0bac45b974a628896c90dbdf5c8093
|
0
|
Build (ubuntu-latest)
|
1
|
name: Test
"on":
push:
paths-i name: Test
"on":
push:
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
build:
name: Build (ubuntu-latest)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node 20
uses: actions/setup-node@v4
with:
cache: npm
node-version: 20.x
- name: npm install
run: npm install
- name: Compile
run: npm run build
- name: Lint
run: npm run lint
- name: Format
run: npm run format-check
- name: Run Unit Tests
run: npm test
- name: Create artifacts
run: |
mkdir -p path/to/artifact-A
mkdir -p path/to/artifact-B
echo "Lorem ipsum dolor sit amet" > path/to/artifact-A/file-A.txt
echo "Hello world from file B" > path/to/artifact-B/file-B.txt
- name: Upload artifact A
uses: actions/upload-artifact@v4
with:
name: Artifact-A-${{ matrix.runs-on }}
path: path/to/artifact-A
- name: Upload artifact B
uses: actions/upload-artifact@v4
with:
name: Artifact-B-${{ matrix.runs-on }}
path: path/to/artifact-B
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: some/new/path
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: ~/some/path/with/a/tilde
- name: Verify successful download
run: |
$file1 = "some/new/path/file-A.txt"
$file2 = "~/some/path/with/a/tilde/file-A.txt"
if(!(Test-Path -path $file1) -or !(Test-Path -path $file2))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $file1) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $file2) -ceq "Lorem ipsum dolor sit amet"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
path: some/other/path
- name: Verify successful download
run: |
$fileA = "some/other/path/Artifact-A-${{ matrix.runs-on }}/file-A.txt"
$fileB = "some/other/path/Artifact-B-${{ matrix.runs-on }}/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
merge-multiple: "true"
path: single/directory
pattern: Artifact-*
- name: Verify successful download
run: |
$fileA = "single/directory/file-A.txt"
$fileB = "single/directory/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
strategy:
fail-fast: "false"
matrix:
runs-on:
- ubuntu-latest
...
|
build
|
null
|
["ubuntu-latest"]
|
33367
|
2
|
1791858288
|
1791858327
|
1791844747
|
1791858327
|
|
0
|
|
0
|
Edit
Delete
|
|
40269
|
25739
|
139
|
5
|
634f93cb2916e3fdff6788551b99b062d0335ce0
|
0
|
Build (ubuntu-latest)
|
1
|
name: Test
"on":
push:
paths-i name: Test
"on":
push:
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
build:
name: Build (ubuntu-latest)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node 20
uses: actions/setup-node@v4
with:
cache: npm
node-version: 20.x
- name: npm install
run: npm install
- name: Compile
run: npm run build
- name: Lint
run: npm run lint
- name: Format
run: npm run format-check
- name: Run Unit Tests
run: npm test
- name: Create artifacts
run: |
mkdir -p path/to/artifact-A
mkdir -p path/to/artifact-B
echo "Lorem ipsum dolor sit amet" > path/to/artifact-A/file-A.txt
echo "Hello world from file B" > path/to/artifact-B/file-B.txt
- name: Upload artifact A
uses: actions/upload-artifact@v4
with:
name: Artifact-A-${{ matrix.runs-on }}
path: path/to/artifact-A
- name: Upload artifact B
uses: actions/upload-artifact@v4
with:
name: Artifact-B-${{ matrix.runs-on }}
path: path/to/artifact-B
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: some/new/path
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: ~/some/path/with/a/tilde
- name: Verify successful download
run: |
$file1 = "some/new/path/file-A.txt"
$file2 = "~/some/path/with/a/tilde/file-A.txt"
if(!(Test-Path -path $file1) -or !(Test-Path -path $file2))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $file1) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $file2) -ceq "Lorem ipsum dolor sit amet"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
path: some/other/path
- name: Verify successful download
run: |
$fileA = "some/other/path/Artifact-A-${{ matrix.runs-on }}/file-A.txt"
$fileB = "some/other/path/Artifact-B-${{ matrix.runs-on }}/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
merge-multiple: "true"
path: single/directory
pattern: Artifact-*
- name: Verify successful download
run: |
$fileA = "single/directory/file-A.txt"
$fileB = "single/directory/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
strategy:
fail-fast: "false"
matrix:
runs-on:
- ubuntu-latest
...
|
build
|
null
|
["ubuntu-latest"]
|
33368
|
2
|
1791858327
|
1791858364
|
1791844747
|
1791858365
|
|
0
|
|
0
|
Edit
Delete
|
|
40272
|
25740
|
139
|
5
|
634f93cb2916e3fdff6788551b99b062d0335ce0
|
0
|
Build (ubuntu-latest)
|
1
|
name: Test
"on":
push:
paths-i name: Test
"on":
push:
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
build:
name: Build (ubuntu-latest)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node 20
uses: actions/setup-node@v4
with:
cache: npm
node-version: 20.x
- name: npm install
run: npm install
- name: Compile
run: npm run build
- name: Lint
run: npm run lint
- name: Format
run: npm run format-check
- name: Run Unit Tests
run: npm test
- name: Create artifacts
run: |
mkdir -p path/to/artifact-A
mkdir -p path/to/artifact-B
echo "Lorem ipsum dolor sit amet" > path/to/artifact-A/file-A.txt
echo "Hello world from file B" > path/to/artifact-B/file-B.txt
- name: Upload artifact A
uses: actions/upload-artifact@v4
with:
name: Artifact-A-${{ matrix.runs-on }}
path: path/to/artifact-A
- name: Upload artifact B
uses: actions/upload-artifact@v4
with:
name: Artifact-B-${{ matrix.runs-on }}
path: path/to/artifact-B
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: some/new/path
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: ~/some/path/with/a/tilde
- name: Verify successful download
run: |
$file1 = "some/new/path/file-A.txt"
$file2 = "~/some/path/with/a/tilde/file-A.txt"
if(!(Test-Path -path $file1) -or !(Test-Path -path $file2))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $file1) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $file2) -ceq "Lorem ipsum dolor sit amet"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
path: some/other/path
- name: Verify successful download
run: |
$fileA = "some/other/path/Artifact-A-${{ matrix.runs-on }}/file-A.txt"
$fileB = "some/other/path/Artifact-B-${{ matrix.runs-on }}/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
merge-multiple: "true"
path: single/directory
pattern: Artifact-*
- name: Verify successful download
run: |
$fileA = "single/directory/file-A.txt"
$fileB = "single/directory/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
strategy:
fail-fast: "false"
matrix:
runs-on:
- ubuntu-latest
...
|
build
|
null
|
["ubuntu-latest"]
|
33369
|
2
|
1791858365
|
1791858403
|
1791844747
|
1791858403
|
|
0
|
|
0
|
Edit
Delete
|
|
40275
|
25741
|
139
|
5
|
018cc2cf5baa6db3ef3c5f8a56943fffe632ef53
|
0
|
Build (ubuntu-latest)
|
1
|
name: Test
"on":
push:
paths-i name: Test
"on":
push:
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
build:
name: Build (ubuntu-latest)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node 20
uses: actions/setup-node@v4
with:
cache: npm
node-version: 20.x
- name: npm install
run: npm install
- name: Compile
run: npm run build
- name: Lint
run: npm run lint
- name: Format
run: npm run format-check
- name: Run Unit Tests
run: npm test
- name: Create artifacts
run: |
mkdir -p path/to/artifact-A
mkdir -p path/to/artifact-B
echo "Lorem ipsum dolor sit amet" > path/to/artifact-A/file-A.txt
echo "Hello world from file B" > path/to/artifact-B/file-B.txt
- name: Upload artifact A
uses: actions/upload-artifact@v4
with:
name: Artifact-A-${{ matrix.runs-on }}
path: path/to/artifact-A
- name: Upload artifact B
uses: actions/upload-artifact@v4
with:
name: Artifact-B-${{ matrix.runs-on }}
path: path/to/artifact-B
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: some/new/path
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: ~/some/path/with/a/tilde
- name: Verify successful download
run: |
$file1 = "some/new/path/file-A.txt"
$file2 = "~/some/path/with/a/tilde/file-A.txt"
if(!(Test-Path -path $file1) -or !(Test-Path -path $file2))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $file1) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $file2) -ceq "Lorem ipsum dolor sit amet"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
path: some/other/path
- name: Verify successful download
run: |
$fileA = "some/other/path/Artifact-A-${{ matrix.runs-on }}/file-A.txt"
$fileB = "some/other/path/Artifact-B-${{ matrix.runs-on }}/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
merge-multiple: "true"
path: single/directory
pattern: Artifact-*
- name: Verify successful download
run: |
$fileA = "single/directory/file-A.txt"
$fileB = "single/directory/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
strategy:
fail-fast: "false"
matrix:
runs-on:
- ubuntu-latest
...
|
build
|
null
|
["ubuntu-latest"]
|
33370
|
2
|
1791858403
|
1791858440
|
1791844747
|
1791858441
|
|
0
|
|
0
|
Edit
Delete
|
|
40278
|
25742
|
139
|
5
|
018cc2cf5baa6db3ef3c5f8a56943fffe632ef53
|
0
|
Build (ubuntu-latest)
|
1
|
name: Test
"on":
push:
paths-i name: Test
"on":
push:
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
build:
name: Build (ubuntu-latest)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node 20
uses: actions/setup-node@v4
with:
cache: npm
node-version: 20.x
- name: npm install
run: npm install
- name: Compile
run: npm run build
- name: Lint
run: npm run lint
- name: Format
run: npm run format-check
- name: Run Unit Tests
run: npm test
- name: Create artifacts
run: |
mkdir -p path/to/artifact-A
mkdir -p path/to/artifact-B
echo "Lorem ipsum dolor sit amet" > path/to/artifact-A/file-A.txt
echo "Hello world from file B" > path/to/artifact-B/file-B.txt
- name: Upload artifact A
uses: actions/upload-artifact@v4
with:
name: Artifact-A-${{ matrix.runs-on }}
path: path/to/artifact-A
- name: Upload artifact B
uses: actions/upload-artifact@v4
with:
name: Artifact-B-${{ matrix.runs-on }}
path: path/to/artifact-B
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: some/new/path
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: ~/some/path/with/a/tilde
- name: Verify successful download
run: |
$file1 = "some/new/path/file-A.txt"
$file2 = "~/some/path/with/a/tilde/file-A.txt"
if(!(Test-Path -path $file1) -or !(Test-Path -path $file2))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $file1) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $file2) -ceq "Lorem ipsum dolor sit amet"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
path: some/other/path
- name: Verify successful download
run: |
$fileA = "some/other/path/Artifact-A-${{ matrix.runs-on }}/file-A.txt"
$fileB = "some/other/path/Artifact-B-${{ matrix.runs-on }}/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
merge-multiple: "true"
path: single/directory
pattern: Artifact-*
- name: Verify successful download
run: |
$fileA = "single/directory/file-A.txt"
$fileB = "single/directory/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
strategy:
fail-fast: "false"
matrix:
runs-on:
- ubuntu-latest
...
|
build
|
null
|
["ubuntu-latest"]
|
33371
|
2
|
1791858441
|
1791858478
|
1791844748
|
1791858478
|
|
0
|
|
0
|
Edit
Delete
|
|
40595
|
25796
|
116
|
5
|
239468b0b86d1fdc5d5e9f7430a8404562a71261
|
0
|
Public static checks (no private packages)
|
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:
public-static:
name: Public static checks (no private packages)
runs-on: ubuntu-latest
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:
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"]
|
0
|
3
|
0
|
1791858573
|
1791857848
|
1791858573
|
|
0
|
|
0
|
Edit
Delete
|
|
40596
|
25796
|
116
|
5
|
239468b0b86d1fdc5d5e9f7430a8404562a71261
|
0
|
Static governance (repo root, private packages)
|
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:
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: 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.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: 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"]
|
0
|
3
|
0
|
1791858573
|
1791857848
|
1791858573
|
|
0
|
|
0
|
Edit
Delete
|
|
40597
|
25796
|
116
|
5
|
239468b0b86d1fdc5d5e9f7430a8404562a71261
|
0
|
Unit tests without DB (modules / packages / govern Unit tests without DB (modules / packages / governance)...
|
0
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
unit:
name: Unit tests without DB (modules / packages / governance)
runs-on: ubuntu-latest
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
steps:
- uses: 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.GITEA_NPM_TOKEN }}
- name: Install runtime workspace (frozen lockfile)
run: pnpm --dir runtime install --frozen-lockfile
- name: Generate clients for authority module unit imports (no database)
run: pnpm --dir runtime prisma:generate
- name: Module / package unit tests
run: pnpm --dir runtime exec turbo run test --filter='./modules/*' --filter='./packages/*' --filter='./clients/*' --force
- name: Governance package tests
run: pnpm governance:test
timeout-minutes: "20"
permissions:
contents: read
...
|
unit
|
["static"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1791858573
|
1791857848
|
1791858573
|
|
0
|
|
0
|
Edit
Delete
|
|
40598
|
25796
|
116
|
5
|
239468b0b86d1fdc5d5e9f7430a8404562a71261
|
0
|
Port conformance (kernel / modules / clients)
|
0
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
port-conformance:
name: Port conformance (kernel / modules / clients)
runs-on: ubuntu-latest
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
steps:
- uses: 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.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: 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"]
|
0
|
3
|
0
|
1791858573
|
1791857848
|
1791858573
|
|
0
|
|
0
|
Edit
Delete
|
|
40599
|
25796
|
116
|
5
|
239468b0b86d1fdc5d5e9f7430a8404562a71261
|
0
|
Runtime and UI acceptance (real PostgreSQL + Redis Runtime and UI acceptance (real PostgreSQL + Redis)...
|
0
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
runtime:
name: Runtime and UI acceptance (real PostgreSQL + Redis)
runs-on: ubuntu-latest
env:
# 库名前缀由 runtime/package.json name 派生(G15 基座守卫:enterprise_platform*)
DATABASE_URL: postgresql://postgres:postgres@127.0.0.1:5432/enterprise_platform_ci?schema=public
REDIS_URL: redis://127.0.0.1:6379
KAFKA_BROKERS: 127.0.0.1:59092
MAINLINE_CHAOS_CONTAINER: enterprise-platform-ms23-ci-redpanda-1
# 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: 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.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: 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"]
|
0
|
3
|
0
|
1791858573
|
1791857848
|
1791858573
|
|
0
|
|
0
|
Edit
Delete
|
|
40600
|
25796
|
116
|
5
|
239468b0b86d1fdc5d5e9f7430a8404562a71261
|
0
|
M1 identity transitional workspace (IdP static → E M1 identity transitional workspace (IdP static → E2 → governance)...
|
0
|
name: Platform
"on":
pull_request:
name: Platform
"on":
pull_request:
push:
branches: [main]
workflow_dispatch:
env:
CANDIDATE_TAG: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
GOV_REPORT_RUNNER: gitea-actions
PNPM_VERSION: 9.15.9
jobs:
identity:
name: M1 identity transitional workspace (IdP static → E2 → governance)
runs-on: ubuntu-latest
env:
# 库名前缀由 identity/package.json name 派生(enterprise_idp*);Redis 必须 db 0(老框架 C22)
DATABASE_URL: postgresql://postgres:postgres@127.0.0.1:5432/enterprise_idp_ci?schema=public
REDIS_URL: redis://127.0.0.1:6379/0
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
steps:
- uses: 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.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: 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"]
|
0
|
3
|
0
|
1791858573
|
1791857848
|
1791858573
|
|
0
|
|
0
|
Edit
Delete
|
|
40601
|
25796
|
116
|
5
|
239468b0b86d1fdc5d5e9f7430a8404562a71261
|
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: 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.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: 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"]
|
0
|
3
|
0
|
1791858573
|
1791857848
|
1791858573
|
|
0
|
|
0
|
Edit
Delete
|
|
40602
|
25796
|
116
|
5
|
239468b0b86d1fdc5d5e9f7430a8404562a71261
|
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: 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"]
|
0
|
3
|
0
|
1791858573
|
1791857848
|
1791858573
|
|
0
|
|
0
|
Edit
Delete
|
|
40281
|
25743
|
139
|
5
|
37930b1c2abaa49bbe596cd826c3c89aef350131
|
0
|
Build (ubuntu-latest)
|
1
|
name: Test
"on":
push:
paths-i name: Test
"on":
push:
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
build:
name: Build (ubuntu-latest)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node 24
uses: actions/setup-node@v4
with:
cache: npm
node-version: 24.x
- name: npm install
run: npm install
- name: Compile
run: npm run build
- name: Lint
run: npm run lint
- name: Format
run: npm run format-check
- name: Run Unit Tests
run: npm test
- name: Create artifacts
run: |
mkdir -p path/to/artifact-A
mkdir -p path/to/artifact-B
echo "Lorem ipsum dolor sit amet" > path/to/artifact-A/file-A.txt
echo "Hello world from file B" > path/to/artifact-B/file-B.txt
- name: Upload artifact A
uses: actions/upload-artifact@v4
with:
name: Artifact-A-${{ matrix.runs-on }}
path: path/to/artifact-A
- name: Upload artifact B
uses: actions/upload-artifact@v4
with:
name: Artifact-B-${{ matrix.runs-on }}
path: path/to/artifact-B
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: some/new/path
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: ~/some/path/with/a/tilde
- name: Verify successful download
run: |
$file1 = "some/new/path/file-A.txt"
$file2 = "~/some/path/with/a/tilde/file-A.txt"
if(!(Test-Path -path $file1) -or !(Test-Path -path $file2))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $file1) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $file2) -ceq "Lorem ipsum dolor sit amet"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
path: some/other/path
- name: Verify successful download
run: |
$fileA = "some/other/path/Artifact-A-${{ matrix.runs-on }}/file-A.txt"
$fileB = "some/other/path/Artifact-B-${{ matrix.runs-on }}/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
merge-multiple: "true"
path: single/directory
pattern: Artifact-*
- name: Verify successful download
run: |
$fileA = "single/directory/file-A.txt"
$fileB = "single/directory/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
strategy:
fail-fast: "false"
matrix:
runs-on:
- ubuntu-latest
...
|
build
|
null
|
["ubuntu-latest"]
|
33372
|
2
|
1791858478
|
1791858673
|
1791844748
|
1791858673
|
|
0
|
|
0
|
Edit
Delete
|
|
40284
|
25744
|
139
|
5
|
37930b1c2abaa49bbe596cd826c3c89aef350131
|
0
|
Build (ubuntu-latest)
|
1
|
name: Test
"on":
push:
paths-i name: Test
"on":
push:
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
build:
name: Build (ubuntu-latest)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node 24
uses: actions/setup-node@v4
with:
cache: npm
node-version: 24.x
- name: npm install
run: npm install
- name: Compile
run: npm run build
- name: Lint
run: npm run lint
- name: Format
run: npm run format-check
- name: Run Unit Tests
run: npm test
- name: Create artifacts
run: |
mkdir -p path/to/artifact-A
mkdir -p path/to/artifact-B
echo "Lorem ipsum dolor sit amet" > path/to/artifact-A/file-A.txt
echo "Hello world from file B" > path/to/artifact-B/file-B.txt
- name: Upload artifact A
uses: actions/upload-artifact@v4
with:
name: Artifact-A-${{ matrix.runs-on }}
path: path/to/artifact-A
- name: Upload artifact B
uses: actions/upload-artifact@v4
with:
name: Artifact-B-${{ matrix.runs-on }}
path: path/to/artifact-B
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: some/new/path
- name: Download artifact A
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: ~/some/path/with/a/tilde
- name: Verify successful download
run: |
$file1 = "some/new/path/file-A.txt"
$file2 = "~/some/path/with/a/tilde/file-A.txt"
if(!(Test-Path -path $file1) -or !(Test-Path -path $file2))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $file1) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $file2) -ceq "Lorem ipsum dolor sit amet"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
path: some/other/path
- name: Verify successful download
run: |
$fileA = "some/other/path/Artifact-A-${{ matrix.runs-on }}/file-A.txt"
$fileB = "some/other/path/Artifact-B-${{ matrix.runs-on }}/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
merge-multiple: "true"
path: single/directory
pattern: Artifact-*
- name: Verify successful download
run: |
$fileA = "single/directory/file-A.txt"
$fileB = "single/directory/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
strategy:
fail-fast: "false"
matrix:
runs-on:
- ubuntu-latest
...
|
build
|
null
|
["ubuntu-latest"]
|
33373
|
2
|
1791858673
|
1791858763
|
1791844748
|
1791858764
|
|
0
|
|
0
|
Edit
Delete
|
|
40287
|
25745
|
139
|
5
|
9000827ccba6bdab643e8b6fd33ac0654aef8333
|
0
|
Build (ubuntu-latest)
|
1
|
name: Test
"on":
push:
paths-i name: Test
"on":
push:
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
build:
name: Build (ubuntu-latest)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node 24
uses: actions/setup-node@v4
with:
cache: npm
node-version: 24.x
- name: npm install
run: npm install
- name: Compile
run: npm run build
- name: Lint
run: npm run lint
- name: Format
run: npm run format-check
- name: Run Unit Tests
run: npm test
- name: Create artifacts
run: |
mkdir -p path/to/artifact-A
mkdir -p path/to/artifact-B
echo "Lorem ipsum dolor sit amet" > path/to/artifact-A/file-A.txt
echo "Hello world from file B" > path/to/artifact-B/file-B.txt
- name: Upload artifact A
uses: actions/upload-artifact@v4
with:
name: Artifact-A-${{ matrix.runs-on }}
path: path/to/artifact-A
- name: Upload artifact B
uses: actions/upload-artifact@v4
with:
name: Artifact-B-${{ matrix.runs-on }}
path: path/to/artifact-B
- name: Download artifact A (absolute path)
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: some/new/path
- name: Download artifact A (tilde expansion)
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: ~/some/path/with/a/tilde
- name: Verify successful download
run: |
$file1 = "some/new/path/file-A.txt"
$file2 = "~/some/path/with/a/tilde/file-A.txt"
if(!(Test-Path -path $file1) -or !(Test-Path -path $file2))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $file1) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $file2) -ceq "Lorem ipsum dolor sit amet"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
path: some/other/path
- name: Verify successful download
run: |
$fileA = "some/other/path/Artifact-A-${{ matrix.runs-on }}/file-A.txt"
$fileB = "some/other/path/Artifact-B-${{ matrix.runs-on }}/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
merge-multiple: "true"
path: single/directory
pattern: Artifact-*
- name: Verify successful download
run: |
$fileA = "single/directory/file-A.txt"
$fileB = "single/directory/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download artifact A without decompressing
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: skip-decompress-test
skip-decompress: "true"
- name: Verify skip-decompress download
run: |
$rawFile = "skip-decompress-test/Artifact-A-${{ matrix.runs-on }}.zip"
if(!(Test-Path -path $rawFile))
{
Write-Error "Expected raw artifact file does not exist at $rawFile"
}
$fileInfo = Get-Item $rawFile
if($fileInfo.Length -eq 0)
{
Write-Error "Downloaded artifact file is empty"
}
Write-Host "Successfully downloaded artifact without decompressing: $rawFile (size: $($fileInfo.Length) bytes)"
shell: pwsh
- name: Create and upload archived artifact with misleading extension
run: |
mkdir -p path/to/extension-test
echo '{"key": "value"}' > path/to/extension-test/data.json
shell: bash
- uses: actions/upload-artifact@v4
with:
name: report.txt-${{ matrix.runs-on }}.json
path: path/to/extension-test/data.json
- name: Download misleading-extension artifact without decompressing
uses: ./
with:
name: report.txt-${{ matrix.runs-on }}.json
path: ext-test/raw
skip-decompress: "true"
- name: Verify downloaded file has .zip extension appended
run: |
expected="ext-test/raw/report.txt-${{ matrix.runs-on }}.json.zip"
if [ -f "$expected" ]; then
echo "PASS: Downloaded file has .zip appended: $expected"
else
echo "FAIL: Expected $expected but got:"
ls -al ext-test/raw/
exit 1
fi
shell: bash
- name: Create artifacts with CJK names
run: |
mkdir -p path/to/cjk-artifacts
# Chinese - 土 (U+571F) known to fail, 日 (U+65E5) known to work
echo "Content for 土" > "path/to/cjk-artifacts/file-土-${{ matrix.runs-on }}.txt"
echo "Content for 中文测试" > "path/to/cjk-artifacts/file-中文测试-${{ matrix.runs-on }}.txt"
# Japanese - katakana and kanji
echo "Content for テスト" > "path/to/cjk-artifacts/file-テスト-${{ matrix.runs-on }}.txt"
echo "Content for 東京タワー" > "path/to/cjk-artifacts/file-東京タワー-${{ matrix.runs-on }}.txt"
# Korean - Hangul
echo "Content for 테스트" > "path/to/cjk-artifacts/file-테스트-${{ matrix.runs-on }}.txt"
echo "Content for 서울시" > "path/to/cjk-artifacts/file-서울시-${{ matrix.runs-on }}.txt"
shell: bash
- name: Upload CJK artifact - Chinese 土
uses: actions/upload-artifact@v7
with:
archive: "false"
path: path/to/cjk-artifacts/file-土-${{ matrix.runs-on }}.txt
- name: Upload CJK artifact - Chinese 中文测试
uses: actions/upload-artifact@v7
with:
archive: "false"
path: path/to/cjk-artifacts/file-中文测试-${{ matrix.runs-on }}.txt
- name: Upload CJK artifact - Japanese テスト
uses: actions/upload-artifact@v7
with:
archive: "false"
path: path/to/cjk-artifacts/file-テスト-${{ matrix.runs-on }}.txt
- name: Upload CJK artifact - Japanese 東京タワー
uses: actions/upload-artifact@v7
with:
archive: "false"
path: path/to/cjk-artifacts/file-東京タワー-${{ matrix.runs-on }}.txt
- name: Upload CJK artifact - Korean 테스트
uses: actions/upload-artifact@v7
with:
archive: "false"
path: path/to/cjk-artifacts/file-테스트-${{ matrix.runs-on }}.txt
- name: Upload CJK artifact - Korean 서울시
uses: actions/upload-artifact@v7
with:
archive: "false"
path: path/to/cjk-artifacts/file-서울시-${{ matrix.runs-on }}.txt
- name: Download CJK artifact - Chinese 土
uses: ./
with:
name: file-土-${{ matrix.runs-on }}.txt
path: cjk-download/土
- name: Download CJK artifact - Chinese 中文测试
uses: ./
with:
name: file-中文测试-${{ matrix.runs-on }}.txt
path: cjk-download/中文测试
- name: Download CJK artifact - Japanese テスト
uses: ./
with:
name: file-テスト-${{ matrix.runs-on }}.txt
path: cjk-download/テスト
- name: Download CJK artifact - Japanese 東京タワー
uses: ./
with:
name: file-東京タワー-${{ matrix.runs-on }}.txt
path: cjk-download/東京タワー
- name: Download CJK artifact - Korean 테스트
uses: ./
with:
name: file-테스트-${{ matrix.runs-on }}.txt
path: cjk-download/테스트
- name: Download CJK artifact - Korean 서울시
uses: ./
with:
name: file-서울시-${{ matrix.runs-on }}.txt
path: cjk-download/서울시
- name: Verify CJK artifact downloads
run: |
set -e
fail=0
check_file() {
local file="$1"
local expected="$2"
if [ ! -f "$file" ]; then
echo "FAIL: Missing file: $file"
fail=1
return
fi
actual=$(cat "$file")
if [ "$actual" != "$expected" ]; then
echo "FAIL: Content mismatch in $file"
echo " Expected: '$expected'"
echo " Got: '$actual'"
fail=1
return
fi
echo "PASS: $file"
}
echo "=== Chinese ==="
check_file "cjk-download/土/file-土-${{ matrix.runs-on }}.txt" "Content for 土"
check_file "cjk-download/中文测试/file-中文测试-${{ matrix.runs-on }}.txt" "Content for 中文测试"
echo "=== Japanese ==="
check_file "cjk-download/テスト/file-テスト-${{ matrix.runs-on }}.txt" "Content for テスト"
check_file "cjk-download/東京タワー/file-東京タワー-${{ matrix.runs-on }}.txt" "Content for 東京タワー"
echo "=== Korean ==="
check_file "cjk-download/테스트/file-테스트-${{ matrix.runs-on }}.txt" "Content for 테스트"
check_file "cjk-download/서울시/file-서울시-${{ matrix.runs-on }}.txt" "Content for 서울시"
if [ "$fail" -ne 0 ]; then
echo "Some CJK artifact checks failed"
ls -alR cjk-download/ || true
exit 1
fi
echo "All CJK artifact downloads verified successfully"
shell: bash
strategy:
fail-fast: "false"
matrix:
runs-on:
- ubuntu-latest
...
|
build
|
null
|
["ubuntu-latest"]
|
33374
|
2
|
1791858764
|
1791858794
|
1791844748
|
1791858794
|
|
0
|
|
0
|
Edit
Delete
|
|
40290
|
25746
|
139
|
5
|
70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3
|
0
|
Build (ubuntu-latest)
|
1
|
name: Test
"on":
push:
paths-i name: Test
"on":
push:
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
build:
name: Build (ubuntu-latest)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node 24
uses: actions/setup-node@v4
with:
cache: npm
node-version: 24.x
- name: npm install
run: npm install
- name: Compile
run: npm run build
- name: Lint
run: npm run lint
- name: Format
run: npm run format-check
- name: Run Unit Tests
run: npm test
- name: Create artifacts
run: |
mkdir -p path/to/artifact-A
mkdir -p path/to/artifact-B
echo "Lorem ipsum dolor sit amet" > path/to/artifact-A/file-A.txt
echo "Hello world from file B" > path/to/artifact-B/file-B.txt
- name: Upload artifact A
uses: actions/upload-artifact@v4
with:
name: Artifact-A-${{ matrix.runs-on }}
path: path/to/artifact-A
- name: Upload artifact B
uses: actions/upload-artifact@v4
with:
name: Artifact-B-${{ matrix.runs-on }}
path: path/to/artifact-B
- name: Download artifact A (absolute path)
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: some/new/path
- name: Download artifact A (tilde expansion)
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: ~/some/path/with/a/tilde
- name: Verify successful download
run: |
$file1 = "some/new/path/file-A.txt"
$file2 = "~/some/path/with/a/tilde/file-A.txt"
if(!(Test-Path -path $file1) -or !(Test-Path -path $file2))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $file1) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $file2) -ceq "Lorem ipsum dolor sit amet"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
path: some/other/path
- name: Verify successful download
run: |
$fileA = "some/other/path/Artifact-A-${{ matrix.runs-on }}/file-A.txt"
$fileB = "some/other/path/Artifact-B-${{ matrix.runs-on }}/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
merge-multiple: "true"
path: single/directory
pattern: Artifact-*
- name: Verify successful download
run: |
$fileA = "single/directory/file-A.txt"
$fileB = "single/directory/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download artifact A without decompressing
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: skip-decompress-test
skip-decompress: "true"
- name: Verify skip-decompress download
run: |
$rawFile = "skip-decompress-test/Artifact-A-${{ matrix.runs-on }}.zip"
if(!(Test-Path -path $rawFile))
{
Write-Error "Expected raw artifact file does not exist at $rawFile"
}
$fileInfo = Get-Item $rawFile
if($fileInfo.Length -eq 0)
{
Write-Error "Downloaded artifact file is empty"
}
Write-Host "Successfully downloaded artifact without decompressing: $rawFile (size: $($fileInfo.Length) bytes)"
shell: pwsh
strategy:
fail-fast: "false"
matrix:
runs-on:
- ubuntu-latest
...
|
build
|
null
|
["ubuntu-latest"]
|
33375
|
2
|
1791858794
|
1791858963
|
1791844748
|
1791858963
|
|
0
|
|
0
|
Edit
Delete
|
|
40293
|
25747
|
139
|
5
|
3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c
|
0
|
Build (ubuntu-latest)
|
1
|
name: Test
"on":
push:
paths-i name: Test
"on":
push:
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
build:
name: Build (ubuntu-latest)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node 24
uses: actions/setup-node@v4
with:
cache: npm
node-version: 24.x
- name: npm install
run: npm install
- name: Compile
run: npm run build
- name: Lint
run: npm run lint
- name: Format
run: npm run format-check
- name: Run Unit Tests
run: npm test
- name: Create artifacts
run: |
mkdir -p path/to/artifact-A
mkdir -p path/to/artifact-B
echo "Lorem ipsum dolor sit amet" > path/to/artifact-A/file-A.txt
echo "Hello world from file B" > path/to/artifact-B/file-B.txt
- name: Upload artifact A
uses: actions/upload-artifact@v4
with:
name: Artifact-A-${{ matrix.runs-on }}
path: path/to/artifact-A
- name: Upload artifact B
uses: actions/upload-artifact@v4
with:
name: Artifact-B-${{ matrix.runs-on }}
path: path/to/artifact-B
- name: Download artifact A (absolute path)
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: some/new/path
- name: Download artifact A (tilde expansion)
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: ~/some/path/with/a/tilde
- name: Verify successful download
run: |
$file1 = "some/new/path/file-A.txt"
$file2 = "~/some/path/with/a/tilde/file-A.txt"
if(!(Test-Path -path $file1) -or !(Test-Path -path $file2))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $file1) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $file2) -ceq "Lorem ipsum dolor sit amet"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
path: some/other/path
- name: Verify successful download
run: |
$fileA = "some/other/path/Artifact-A-${{ matrix.runs-on }}/file-A.txt"
$fileB = "some/other/path/Artifact-B-${{ matrix.runs-on }}/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
merge-multiple: "true"
path: single/directory
pattern: Artifact-*
- name: Verify successful download
run: |
$fileA = "single/directory/file-A.txt"
$fileB = "single/directory/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download artifact A without decompressing
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: skip-decompress-test
skip-decompress: "true"
- name: Verify skip-decompress download
run: |
$rawFile = "skip-decompress-test/Artifact-A-${{ matrix.runs-on }}.zip"
if(!(Test-Path -path $rawFile))
{
Write-Error "Expected raw artifact file does not exist at $rawFile"
}
$fileInfo = Get-Item $rawFile
if($fileInfo.Length -eq 0)
{
Write-Error "Downloaded artifact file is empty"
}
Write-Host "Successfully downloaded artifact without decompressing: $rawFile (size: $($fileInfo.Length) bytes)"
shell: pwsh
- name: Create and upload archived artifact with misleading extension
run: |
mkdir -p path/to/extension-test
echo '{"key": "value"}' > path/to/extension-test/data.json
shell: bash
- uses: actions/upload-artifact@v4
with:
name: report.txt-${{ matrix.runs-on }}.json
path: path/to/extension-test/data.json
- name: Download misleading-extension artifact without decompressing
uses: ./
with:
name: report.txt-${{ matrix.runs-on }}.json
path: ext-test/raw
skip-decompress: "true"
- name: Verify downloaded file has .zip extension appended
run: |
expected="ext-test/raw/report.txt-${{ matrix.runs-on }}.json.zip"
if [ -f "$expected" ]; then
echo "PASS: Downloaded file has .zip appended: $expected"
else
echo "FAIL: Expected $expected but got:"
ls -al ext-test/raw/
exit 1
fi
shell: bash
- name: Create artifacts with CJK names
run: |
mkdir -p path/to/cjk-artifacts
# Chinese - 土 (U+571F) known to fail, 日 (U+65E5) known to work
echo "Content for 土" > "path/to/cjk-artifacts/file-土-${{ matrix.runs-on }}.txt"
echo "Content for 中文测试" > "path/to/cjk-artifacts/file-中文测试-${{ matrix.runs-on }}.txt"
# Japanese - katakana and kanji
echo "Content for テスト" > "path/to/cjk-artifacts/file-テスト-${{ matrix.runs-on }}.txt"
echo "Content for 東京タワー" > "path/to/cjk-artifacts/file-東京タワー-${{ matrix.runs-on }}.txt"
# Korean - Hangul
echo "Content for 테스트" > "path/to/cjk-artifacts/file-테스트-${{ matrix.runs-on }}.txt"
echo "Content for 서울시" > "path/to/cjk-artifacts/file-서울시-${{ matrix.runs-on }}.txt"
shell: bash
- name: Upload CJK artifact - Chinese 土
uses: actions/upload-artifact@v7
with:
archive: "false"
path: path/to/cjk-artifacts/file-土-${{ matrix.runs-on }}.txt
- name: Upload CJK artifact - Chinese 中文测试
uses: actions/upload-artifact@v7
with:
archive: "false"
path: path/to/cjk-artifacts/file-中文测试-${{ matrix.runs-on }}.txt
- name: Upload CJK artifact - Japanese テスト
uses: actions/upload-artifact@v7
with:
archive: "false"
path: path/to/cjk-artifacts/file-テスト-${{ matrix.runs-on }}.txt
- name: Upload CJK artifact - Japanese 東京タワー
uses: actions/upload-artifact@v7
with:
archive: "false"
path: path/to/cjk-artifacts/file-東京タワー-${{ matrix.runs-on }}.txt
- name: Upload CJK artifact - Korean 테스트
uses: actions/upload-artifact@v7
with:
archive: "false"
path: path/to/cjk-artifacts/file-테스트-${{ matrix.runs-on }}.txt
- name: Upload CJK artifact - Korean 서울시
uses: actions/upload-artifact@v7
with:
archive: "false"
path: path/to/cjk-artifacts/file-서울시-${{ matrix.runs-on }}.txt
- name: Download CJK artifact - Chinese 土
uses: ./
with:
name: file-土-${{ matrix.runs-on }}.txt
path: cjk-download/土
- name: Download CJK artifact - Chinese 中文测试
uses: ./
with:
name: file-中文测试-${{ matrix.runs-on }}.txt
path: cjk-download/中文测试
- name: Download CJK artifact - Japanese テスト
uses: ./
with:
name: file-テスト-${{ matrix.runs-on }}.txt
path: cjk-download/テスト
- name: Download CJK artifact - Japanese 東京タワー
uses: ./
with:
name: file-東京タワー-${{ matrix.runs-on }}.txt
path: cjk-download/東京タワー
- name: Download CJK artifact - Korean 테스트
uses: ./
with:
name: file-테스트-${{ matrix.runs-on }}.txt
path: cjk-download/테스트
- name: Download CJK artifact - Korean 서울시
uses: ./
with:
name: file-서울시-${{ matrix.runs-on }}.txt
path: cjk-download/서울시
- name: Verify CJK artifact downloads
run: |
set -e
fail=0
check_file() {
local file="$1"
local expected="$2"
if [ ! -f "$file" ]; then
echo "FAIL: Missing file: $file"
fail=1
return
fi
actual=$(cat "$file")
if [ "$actual" != "$expected" ]; then
echo "FAIL: Content mismatch in $file"
echo " Expected: '$expected'"
echo " Got: '$actual'"
fail=1
return
fi
echo "PASS: $file"
}
echo "=== Chinese ==="
check_file "cjk-download/土/file-土-${{ matrix.runs-on }}.txt" "Content for 土"
check_file "cjk-download/中文测试/file-中文测试-${{ matrix.runs-on }}.txt" "Content for 中文测试"
echo "=== Japanese ==="
check_file "cjk-download/テスト/file-テスト-${{ matrix.runs-on }}.txt" "Content for テスト"
check_file "cjk-download/東京タワー/file-東京タワー-${{ matrix.runs-on }}.txt" "Content for 東京タワー"
echo "=== Korean ==="
check_file "cjk-download/테스트/file-테스트-${{ matrix.runs-on }}.txt" "Content for 테스트"
check_file "cjk-download/서울시/file-서울시-${{ matrix.runs-on }}.txt" "Content for 서울시"
if [ "$fail" -ne 0 ]; then
echo "Some CJK artifact checks failed"
ls -alR cjk-download/ || true
exit 1
fi
echo "All CJK artifact downloads verified successfully"
shell: bash
strategy:
fail-fast: "false"
matrix:
runs-on:
- ubuntu-latest
...
|
build
|
null
|
["ubuntu-latest"]
|
33376
|
2
|
1791858964
|
1791858994
|
1791844749
|
1791858994
|
|
0
|
|
0
|
Edit
Delete
|
|
40296
|
25748
|
139
|
5
|
9000827ccba6bdab643e8b6fd33ac0654aef8333
|
0
|
Build (ubuntu-latest)
|
1
|
name: Test
"on":
push:
paths-i name: Test
"on":
push:
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
build:
name: Build (ubuntu-latest)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node 24
uses: actions/setup-node@v4
with:
cache: npm
node-version: 24.x
- name: npm install
run: npm install
- name: Compile
run: npm run build
- name: Lint
run: npm run lint
- name: Format
run: npm run format-check
- name: Run Unit Tests
run: npm test
- name: Create artifacts
run: |
mkdir -p path/to/artifact-A
mkdir -p path/to/artifact-B
echo "Lorem ipsum dolor sit amet" > path/to/artifact-A/file-A.txt
echo "Hello world from file B" > path/to/artifact-B/file-B.txt
- name: Upload artifact A
uses: actions/upload-artifact@v4
with:
name: Artifact-A-${{ matrix.runs-on }}
path: path/to/artifact-A
- name: Upload artifact B
uses: actions/upload-artifact@v4
with:
name: Artifact-B-${{ matrix.runs-on }}
path: path/to/artifact-B
- name: Download artifact A (absolute path)
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: some/new/path
- name: Download artifact A (tilde expansion)
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: ~/some/path/with/a/tilde
- name: Verify successful download
run: |
$file1 = "some/new/path/file-A.txt"
$file2 = "~/some/path/with/a/tilde/file-A.txt"
if(!(Test-Path -path $file1) -or !(Test-Path -path $file2))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $file1) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $file2) -ceq "Lorem ipsum dolor sit amet"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
path: some/other/path
- name: Verify successful download
run: |
$fileA = "some/other/path/Artifact-A-${{ matrix.runs-on }}/file-A.txt"
$fileB = "some/other/path/Artifact-B-${{ matrix.runs-on }}/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download all Artifacts
uses: ./
with:
merge-multiple: "true"
path: single/directory
pattern: Artifact-*
- name: Verify successful download
run: |
$fileA = "single/directory/file-A.txt"
$fileB = "single/directory/file-B.txt"
if(!(Test-Path -path $fileA) -or !(Test-Path -path $fileB))
{
Write-Error "Expected files do not exist"
}
if(!((Get-Content $fileA) -ceq "Lorem ipsum dolor sit amet") -or !((Get-Content $fileB) -ceq "Hello world from file B"))
{
Write-Error "File contents of downloaded artifacts are incorrect"
}
shell: pwsh
- name: Download artifact A without decompressing
uses: ./
with:
name: Artifact-A-${{ matrix.runs-on }}
path: skip-decompress-test
skip-decompress: "true"
- name: Verify skip-decompress download
run: |
$rawFile = "skip-decompress-test/Artifact-A-${{ matrix.runs-on }}.zip"
if(!(Test-Path -path $rawFile))
{
Write-Error "Expected raw artifact file does not exist at $rawFile"
}
$fileInfo = Get-Item $rawFile
if($fileInfo.Length -eq 0)
{
Write-Error "Downloaded artifact file is empty"
}
Write-Host "Successfully downloaded artifact without decompressing: $rawFile (size: $($fileInfo.Length) bytes)"
shell: pwsh
- name: Create and upload archived artifact with misleading extension
run: |
mkdir -p path/to/extension-test
echo '{"key": "value"}' > path/to/extension-test/data.json
shell: bash
- uses: actions/upload-artifact@v4
with:
name: report.txt-${{ matrix.runs-on }}.json
path: path/to/extension-test/data.json
- name: Download misleading-extension artifact without decompressing
uses: ./
with:
name: report.txt-${{ matrix.runs-on }}.json
path: ext-test/raw
skip-decompress: "true"
- name: Verify downloaded file has .zip extension appended
run: |
expected="ext-test/raw/report.txt-${{ matrix.runs-on }}.json.zip"
if [ -f "$expected" ]; then
echo "PASS: Downloaded file has .zip appended: $expected"
else
echo "FAIL: Expected $expected but got:"
ls -al ext-test/raw/
exit 1
fi
shell: bash
- name: Create artifacts with CJK names
run: |
mkdir -p path/to/cjk-artifacts
# Chinese - 土 (U+571F) known to fail, 日 (U+65E5) known to work
echo "Content for 土" > "path/to/cjk-artifacts/file-土-${{ matrix.runs-on }}.txt"
echo "Content for 中文测试" > "path/to/cjk-artifacts/file-中文测试-${{ matrix.runs-on }}.txt"
# Japanese - katakana and kanji
echo "Content for テスト" > "path/to/cjk-artifacts/file-テスト-${{ matrix.runs-on }}.txt"
echo "Content for 東京タワー" > "path/to/cjk-artifacts/file-東京タワー-${{ matrix.runs-on }}.txt"
# Korean - Hangul
echo "Content for 테스트" > "path/to/cjk-artifacts/file-테스트-${{ matrix.runs-on }}.txt"
echo "Content for 서울시" > "path/to/cjk-artifacts/file-서울시-${{ matrix.runs-on }}.txt"
shell: bash
- name: Upload CJK artifact - Chinese 土
uses: actions/upload-artifact@v7
with:
archive: "false"
path: path/to/cjk-artifacts/file-土-${{ matrix.runs-on }}.txt
- name: Upload CJK artifact - Chinese 中文测试
uses: actions/upload-artifact@v7
with:
archive: "false"
path: path/to/cjk-artifacts/file-中文测试-${{ matrix.runs-on }}.txt
- name: Upload CJK artifact - Japanese テスト
uses: actions/upload-artifact@v7
with:
archive: "false"
path: path/to/cjk-artifacts/file-テスト-${{ matrix.runs-on }}.txt
- name: Upload CJK artifact - Japanese 東京タワー
uses: actions/upload-artifact@v7
with:
archive: "false"
path: path/to/cjk-artifacts/file-東京タワー-${{ matrix.runs-on }}.txt
- name: Upload CJK artifact - Korean 테스트
uses: actions/upload-artifact@v7
with:
archive: "false"
path: path/to/cjk-artifacts/file-테스트-${{ matrix.runs-on }}.txt
- name: Upload CJK artifact - Korean 서울시
uses: actions/upload-artifact@v7
with:
archive: "false"
path: path/to/cjk-artifacts/file-서울시-${{ matrix.runs-on }}.txt
- name: Download CJK artifact - Chinese 土
uses: ./
with:
name: file-土-${{ matrix.runs-on }}.txt
path: cjk-download/土
- name: Download CJK artifact - Chinese 中文测试
uses: ./
with:
name: file-中文测试-${{ matrix.runs-on }}.txt
path: cjk-download/中文测试
- name: Download CJK artifact - Japanese テスト
uses: ./
with:
name: file-テスト-${{ matrix.runs-on }}.txt
path: cjk-download/テスト
- name: Download CJK artifact - Japanese 東京タワー
uses: ./
with:
name: file-東京タワー-${{ matrix.runs-on }}.txt
path: cjk-download/東京タワー
- name: Download CJK artifact - Korean 테스트
uses: ./
with:
name: file-테스트-${{ matrix.runs-on }}.txt
path: cjk-download/테스트
- name: Download CJK artifact - Korean 서울시
uses: ./
with:
name: file-서울시-${{ matrix.runs-on }}.txt
path: cjk-download/서울시
- name: Verify CJK artifact downloads
run: |
set -e
fail=0
check_file() {
local file="$1"
local expected="$2"
if [ ! -f "$file" ]; then
echo "FAIL: Missing file: $file"
fail=1
return
fi
actual=$(cat "$file")
if [ "$actual" != "$expected" ]; then
echo "FAIL: Content mismatch in $file"
echo " Expected: '$expected'"
echo " Got: '$actual'"
fail=1
return
fi
echo "PASS: $file"
}
echo "=== Chinese ==="
check_file "cjk-download/土/file-土-${{ matrix.runs-on }}.txt" "Content for 土"
check_file "cjk-download/中文测试/file-中文测试-${{ matrix.runs-on }}.txt" "Content for 中文测试"
echo "=== Japanese ==="
check_file "cjk-download/テスト/file-テスト-${{ matrix.runs-on }}.txt" "Content for テスト"
check_file "cjk-download/東京タワー/file-東京タワー-${{ matrix.runs-on }}.txt" "Content for 東京タワー"
echo "=== Korean ==="
check_file "cjk-download/테스트/file-테스트-${{ matrix.runs-on }}.txt" "Content for 테스트"
check_file "cjk-download/서울시/file-서울시-${{ matrix.runs-on }}.txt" "Content for 서울시"
if [ "$fail" -ne 0 ]; then
echo "Some CJK artifact checks failed"
ls -alR cjk-download/ || true
exit 1
fi
echo "All CJK artifact downloads verified successfully"
shell: bash
strategy:
fail-fast: "false"
matrix:
runs-on:
- ubuntu-latest
...
|
build
|
null
|
["ubuntu-latest"]
|
33377
|
2
|
1791858994
|
1791859024
|
1791844749
|
1791859024
|
|
0
|
|
0
|
Edit
Delete
|
|
40298
|
25749
|
140
|
5
|
af595e623eec1ede52d6322f53b635d5def0a95a
|
0
|
Fetch current list of all Cosign releases for test Fetch current list of all Cosign releases for testing...
|
1
|
name: test-cosign
"on":
pull_request:
name: test-cosign
"on":
pull_request:
push:
branches:
- 'main'
jobs:
get_all_cosign_releases:
name: Fetch current list of all Cosign releases for testing
runs-on: ubuntu-latest
steps:
- id: get_tags
name: Get release tags
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
retries: "3"
script: |
const response = await github.rest.repos.listReleases({owner:'sigstore',repo:'cosign'});
const releases = response.data.map(release => release.tag_name);
console.log("Found releases: " + releases);
// filter out versions below v2.0.0
return releases.filter(rel => {
const version = rel.replace(/^v/, '');
const majorVersion = parseInt(version.split('.')[0]);
return majorVersion >= 2;
});
outputs:
releases: ${{ steps.get_tags.outputs.result }}
permissions:
contents: read
permissions: {}
...
|
get_all_cosign_releases
|
null
|
["ubuntu-latest"]
|
33378
|
2
|
1791859024
|
1791859054
|
1791844750
|
1791859055
|
|
0
|
|
0
|
Edit
Delete
|
|
40303
|
25749
|
140
|
5
|
af595e623eec1ede52d6322f53b635d5def0a95a
|
0
|
Install Cosign ${{ matrix.cosign_release }} on ${{ Install Cosign ${{ matrix.cosign_release }} on ${{ matrix.os }} and test presence in path...
|
0
|
name: test-cosign
"on":
pull_request:
name: test-cosign
"on":
pull_request:
push:
branches:
- 'main'
jobs:
test_cosign_action_custom:
name: Install Cosign ${{ matrix.cosign_release }} on ${{ matrix.os }} and test presence in path
runs-on: ""
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
persist-credentials: "false"
- name: Install Cosign
uses: ./
with:
cosign-release: ${{ matrix.cosign_release }}
- name: Check install!
run: cosign version
- name: Check root directory
run: |
if [[ $(git diff --stat) != '' ]]; then
echo 'should be clean'
exit 1
else
exit 0
fi
shell: bash
strategy:
fail-fast: "false"
permissions:
contents: read
permissions: {}
...
|
test_cosign_action_custom
|
["get_all_cosign_releases"]
|
[""]
|
0
|
4
|
0
|
0
|
1791844750
|
1791859055
|
|
1
|
|
0
|
Edit
Delete
|
|
40300
|
25749
|
140
|
5
|
af595e623eec1ede52d6322f53b635d5def0a95a
|
0
|
Install default version Cosign and test presence i Install default version Cosign and test presence in path (ubuntu-latest)...
|
1
|
name: test-cosign
"on":
pull_request:
name: test-cosign
"on":
pull_request:
push:
branches:
- 'main'
jobs:
test_default_version_cosign_action:
name: Install default version Cosign and test presence in path (ubuntu-latest)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
persist-credentials: "false"
- name: Install Cosign
uses: ./
- name: Check install!
run: cosign version
- name: Check root directory
run: |
if [[ $(git diff --stat) != '' ]]; then
echo 'should be clean'
exit 1
else
exit 0
fi
shell: bash
strategy:
matrix:
os:
- ubuntu-latest
permissions:
contents: read
permissions: {}
...
|
test_default_version_cosign_action
|
null
|
["ubuntu-latest"]
|
33379
|
2
|
1791859055
|
1791859085
|
1791844750
|
1791859085
|
|
0
|
|
0
|
Edit
Delete
|
|
40302
|
25749
|
140
|
5
|
af595e623eec1ede52d6322f53b635d5def0a95a
|
0
|
Install existing release of Cosign and test presen Install existing release of Cosign and test presence in path (ubuntu-latest)...
|
1
|
name: test-cosign
"on":
pull_request:
name: test-cosign
"on":
pull_request:
push:
branches:
- 'main'
jobs:
test_existing_release_action:
name: Install existing release of Cosign and test presence in path (ubuntu-latest)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
persist-credentials: "false"
- name: Install Cosign
uses: sigstore/cosign-installer@dd6b2e2b610a11fd73dd187a43d57cc1394e35f9
- name: Check install!
run: cosign version
- name: Check root directory
run: |
if [[ $(git diff --stat) != '' ]]; then
echo 'should be clean'
exit 1
else
exit 0
fi
strategy:
fail-fast: "false"
matrix:
os:
- ubuntu-latest
permissions:
contents: read
permissions: {}
...
|
test_existing_release_action
|
null
|
["ubuntu-latest"]
|
33380
|
2
|
1791859085
|
1791859115
|
1791844750
|
1791859115
|
|
0
|
|
0
|
Edit
Delete
|
|
40308
|
25749
|
140
|
5
|
af595e623eec1ede52d6322f53b635d5def0a95a
|
0
|
Test unsupported version v0.5.0 fails on ubuntu-la Test unsupported version v0.5.0 fails on ubuntu-latest...
|
1
|
name: test-cosign
"on":
pull_request:
name: test-cosign
"on":
pull_request:
push:
branches:
- 'main'
jobs:
test_unsupported_versions:
name: Test unsupported version v0.5.0 fails on ubuntu-latest
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
persist-credentials: "false"
- id: install-attempt
name: Install Cosign (should fail)
uses: ./
with:
cosign-release: ${{ matrix.version }}
continue-on-error: true
- name: Verify installation failed
run: |
if [[ "${{ steps.install-attempt.outcome }}" == "failure" ]]; then
echo "✅ Installation correctly failed for unsupported version ${{ matrix.version }}"
else
echo "❌ Installation should have failed for unsupported version ${{ matrix.version }}"
exit 1
fi
shell: bash
strategy:
fail-fast: "false"
matrix:
os:
- ubuntu-latest
version:
- v0.5.0
permissions: {}
permissions: {}
...
|
test_unsupported_versions
|
null
|
["ubuntu-latest"]
|
33381
|
2
|
1791859115
|
1791859206
|
1791844750
|
1791859206
|
|
0
|
|
0
|
Edit
Delete
|
|
40309
|
25749
|
140
|
5
|
af595e623eec1ede52d6322f53b635d5def0a95a
|
0
|
Test unsupported version v0.6.0 fails on ubuntu-la Test unsupported version v0.6.0 fails on ubuntu-latest...
|
1
|
name: test-cosign
"on":
pull_request:
name: test-cosign
"on":
pull_request:
push:
branches:
- 'main'
jobs:
test_unsupported_versions:
name: Test unsupported version v0.6.0 fails on ubuntu-latest
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
persist-credentials: "false"
- id: install-attempt
name: Install Cosign (should fail)
uses: ./
with:
cosign-release: ${{ matrix.version }}
continue-on-error: true
- name: Verify installation failed
run: |
if [[ "${{ steps.install-attempt.outcome }}" == "failure" ]]; then
echo "✅ Installation correctly failed for unsupported version ${{ matrix.version }}"
else
echo "❌ Installation should have failed for unsupported version ${{ matrix.version }}"
exit 1
fi
shell: bash
strategy:
fail-fast: "false"
matrix:
os:
- ubuntu-latest
version:
- v0.6.0
permissions: {}
permissions: {}
...
|
test_unsupported_versions
|
null
|
["ubuntu-latest"]
|
33382
|
1
|
1791859206
|
1791859209
|
1791844750
|
1791859209
|
|
0
|
|
0
|
Edit
Delete
|
|
40310
|
25749
|
140
|
5
|
af595e623eec1ede52d6322f53b635d5def0a95a
|
0
|
Test unsupported version v1.0.0 fails on ubuntu-la Test unsupported version v1.0.0 fails on ubuntu-latest...
|
1
|
name: test-cosign
"on":
pull_request:
name: test-cosign
"on":
pull_request:
push:
branches:
- 'main'
jobs:
test_unsupported_versions:
name: Test unsupported version v1.0.0 fails on ubuntu-latest
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
persist-credentials: "false"
- id: install-attempt
name: Install Cosign (should fail)
uses: ./
with:
cosign-release: ${{ matrix.version }}
continue-on-error: true
- name: Verify installation failed
run: |
if [[ "${{ steps.install-attempt.outcome }}" == "failure" ]]; then
echo "✅ Installation correctly failed for unsupported version ${{ matrix.version }}"
else
echo "❌ Installation should have failed for unsupported version ${{ matrix.version }}"
exit 1
fi
shell: bash
strategy:
fail-fast: "false"
matrix:
os:
- ubuntu-latest
version:
- v1.0.0
permissions: {}
permissions: {}
...
|
test_unsupported_versions
|
null
|
["ubuntu-latest"]
|
33383
|
1
|
1791859209
|
1791859211
|
1791844750
|
1791859212
|
|
0
|
|
0
|
Edit
Delete
|
|
40311
|
25749
|
140
|
5
|
af595e623eec1ede52d6322f53b635d5def0a95a
|
0
|
Test unsupported version v1.13.6 fails on ubuntu-l Test unsupported version v1.13.6 fails on ubuntu-latest...
|
1
|
name: test-cosign
"on":
pull_request:
name: test-cosign
"on":
pull_request:
push:
branches:
- 'main'
jobs:
test_unsupported_versions:
name: Test unsupported version v1.13.6 fails on ubuntu-latest
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
persist-credentials: "false"
- id: install-attempt
name: Install Cosign (should fail)
uses: ./
with:
cosign-release: ${{ matrix.version }}
continue-on-error: true
- name: Verify installation failed
run: |
if [[ "${{ steps.install-attempt.outcome }}" == "failure" ]]; then
echo "✅ Installation correctly failed for unsupported version ${{ matrix.version }}"
else
echo "❌ Installation should have failed for unsupported version ${{ matrix.version }}"
exit 1
fi
shell: bash
strategy:
fail-fast: "false"
matrix:
os:
- ubuntu-latest
version:
- v1.13.6
permissions: {}
permissions: {}
...
|
test_unsupported_versions
|
null
|
["ubuntu-latest"]
|
33384
|
1
|
1791859212
|
1791859214
|
1791844750
|
1791859214
|
|
0
|
|
0
|
Edit
Delete
|