quality gate #585
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: quality gate | |
| on: | |
| schedule: | |
| # Daily 02:00 Asia/Shanghai. | |
| - cron: "0 18 * * *" | |
| workflow_dispatch: | |
| inputs: | |
| target_branch: | |
| description: Target branch | |
| type: string | |
| default: latest | |
| scope: | |
| description: Quality gate scope | |
| type: choice | |
| default: ci | |
| options: | |
| - ci | |
| - repo | |
| - repo-tooling | |
| - repo-frontend | |
| - repo-frontend-pr | |
| - repo-frontend-react-doctor | |
| - repo-backend | |
| - repo-backend-static | |
| - repo-backend-fmt | |
| - repo-backend-image-llm-vision | |
| - repo-backend-official-i18n-seed | |
| - repo-backend-clippy-core-libs | |
| - repo-backend-clippy-runtime-storage | |
| - repo-backend-clippy-apps | |
| - repo-backend-test-core-libs | |
| - repo-backend-test-runtime-storage-fast | |
| - repo-backend-test-storage-postgres-1-of-4 | |
| - repo-backend-test-storage-postgres-2-of-4 | |
| - repo-backend-test-storage-postgres-3-of-4 | |
| - repo-backend-test-storage-postgres-4-of-4 | |
| - repo-backend-test-control-plane | |
| - repo-backend-test-api-server-1-of-4 | |
| - repo-backend-test-api-server-2-of-4 | |
| - repo-backend-test-api-server-3-of-4 | |
| - repo-backend-test-api-server-4-of-4 | |
| - repo-backend-test-plugin-runner | |
| - repo-backend-check-core-libs | |
| - repo-backend-check-runtime-storage | |
| - repo-backend-check-apps | |
| - backend | |
| - backend-consistency | |
| - backend-consistency-control-runtime | |
| - backend-consistency-storage | |
| - backend-consistency-api | |
| - state-protocols | |
| - coverage | |
| - coverage-frontend | |
| - coverage-backend | |
| - coverage-backend-control-plane | |
| - coverage-backend-orchestration-runtime | |
| - coverage-backend-plugin-runner | |
| - coverage-backend-storage-postgres | |
| - coverage-backend-api-server | |
| - container-images | |
| report_type: | |
| description: Report type | |
| type: choice | |
| default: ci | |
| options: | |
| - ci | |
| - cd | |
| environment: | |
| description: Optional environment label | |
| type: string | |
| required: false | |
| react_doctor_base: | |
| description: Protected baseline SHA for a manual React Doctor candidate run | |
| type: string | |
| required: false | |
| permissions: | |
| contents: read | |
| actions: read | |
| issues: write | |
| concurrency: | |
| group: quality-gate-${{ github.event_name }}-${{ github.event_name == 'workflow_dispatch' && inputs.target_branch || 'latest' }} | |
| cancel-in-progress: true | |
| env: | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true | |
| QUALITY_GATE_TARGET_BRANCH: ${{ github.event_name == 'workflow_dispatch' && inputs.target_branch || 'latest' }} | |
| QUALITY_GATE_SCOPE: ${{ github.event_name == 'workflow_dispatch' && inputs.scope || 'ci' }} | |
| QUALITY_GATE_REPORT_TYPE: ${{ github.event_name == 'workflow_dispatch' && inputs.report_type || 'ci' }} | |
| QUALITY_GATE_SCHEDULED_ENVIRONMENT: nightly-latest | |
| jobs: | |
| resolve-quality-gate-target: | |
| if: ${{ github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.scope == 'ci') }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| outputs: | |
| target_sha: ${{ steps.target.outputs.sha }} | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| ref: ${{ env.QUALITY_GATE_TARGET_BRANCH }} | |
| - id: target | |
| run: echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" | |
| foundation-contract-gate: | |
| if: ${{ github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.scope == 'ci') }} | |
| needs: resolve-quality-gate-target | |
| uses: ./.github/workflows/foundation-contracts.yml | |
| with: | |
| target_ref: ${{ needs.resolve-quality-gate-target.outputs.target_sha }} | |
| base_ref: '' | |
| foundation: all | |
| lane: project-health | |
| single-scope-gate: | |
| if: ${{ github.event_name == 'workflow_dispatch' && inputs.scope != 'ci' && inputs.scope != 'container-images' }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 60 | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| ref: ${{ env.QUALITY_GATE_TARGET_BRANCH }} | |
| fetch-depth: 0 | |
| - name: Resolve quality gate target SHA | |
| run: echo "QUALITY_GATE_TARGET_SHA=$(git rev-parse HEAD)" >> "$GITHUB_ENV" | |
| - uses: pnpm/action-setup@v5 | |
| with: | |
| version: 11.5.0 | |
| - uses: actions/setup-node@v5 | |
| with: | |
| node-version: 24 | |
| cache: pnpm | |
| cache-dependency-path: web/pnpm-lock.yaml | |
| - run: pnpm --dir web install --frozen-lockfile | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: taiki-e/install-action@cargo-llvm-cov | |
| - uses: taiki-e/install-action@nextest | |
| if: ${{ startsWith(inputs.scope, 'repo-backend-test-api-server-') || startsWith(inputs.scope, 'repo-backend-test-storage-postgres-') || inputs.scope == 'coverage' || inputs.scope == 'coverage-backend' || inputs.scope == 'coverage-backend-api-server' }} | |
| - name: Resolve release-seeded Rust cache architecture | |
| id: release_seed_arch | |
| if: ${{ inputs.scope == 'repo' || inputs.scope == 'backend' || startsWith(inputs.scope, 'backend-consistency') || inputs.scope == 'state-protocols' || inputs.scope == 'repo-backend' || startsWith(inputs.scope, 'repo-backend-') || inputs.scope == 'coverage' || inputs.scope == 'coverage-backend' || startsWith(inputs.scope, 'coverage-backend-') }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| case "${RUNNER_ARCH:-X64}" in | |
| ARM64) cache_arch=arm64 ;; | |
| *) cache_arch=amd64 ;; | |
| esac | |
| echo "cache_arch=$cache_arch" >> "$GITHUB_OUTPUT" | |
| - name: Restore release-seeded api-server Rust cache | |
| id: release_seed_api | |
| uses: actions/cache/restore@v5 | |
| with: | |
| path: | | |
| tmp/container-cache/api-server/${{ steps.release_seed_arch.outputs.cache_arch }}/cargo-registry | |
| tmp/container-cache/api-server/${{ steps.release_seed_arch.outputs.cache_arch }}/cargo-git | |
| tmp/container-cache/api-server/${{ steps.release_seed_arch.outputs.cache_arch }}/target | |
| key: rust-release-seeded-api-server-v2-${{ runner.os }}-${{ steps.release_seed_arch.outputs.cache_arch }}-rust-1-slim-bookworm-release-${{ hashFiles('api/Cargo.lock', 'api/**/Cargo.toml') }} | |
| restore-keys: | | |
| rust-release-seeded-api-server-v2-${{ runner.os }}-${{ steps.release_seed_arch.outputs.cache_arch }}-rust-1-slim-bookworm-release-${{ hashFiles('api/Cargo.lock') }}- | |
| rust-release-seeded-api-server-v2-${{ runner.os }}-${{ steps.release_seed_arch.outputs.cache_arch }}-rust-1-slim-bookworm-release- | |
| - name: Import release-seeded api-server Rust cache | |
| if: ${{ steps.release_seed_api.outputs.cache-hit != '' }} | |
| shell: bash | |
| env: | |
| RUST_RELEASE_SEEDED_CACHE_ARCH: ${{ steps.release_seed_arch.outputs.cache_arch }} | |
| CARGO_TARGET_DIR: tmp/quality-gate-cache/rust-single-${{ (inputs.scope == 'coverage' || inputs.scope == 'coverage-backend' || startsWith(inputs.scope, 'coverage-backend-')) && 'coverage' || 'backend' }}/${{ inputs.scope }}/target | |
| run: | | |
| set -euo pipefail | |
| cargo_home="${CARGO_HOME:-$HOME/.cargo}" | |
| mkdir -p "$cargo_home/registry" "$cargo_home/git" "$CARGO_TARGET_DIR" | |
| rsync -a "tmp/container-cache/api-server/$RUST_RELEASE_SEEDED_CACHE_ARCH/cargo-registry/" "$cargo_home/registry/" | |
| rsync -a "tmp/container-cache/api-server/$RUST_RELEASE_SEEDED_CACHE_ARCH/cargo-git/" "$cargo_home/git/" | |
| rsync -a "tmp/container-cache/api-server/$RUST_RELEASE_SEEDED_CACHE_ARCH/target/" "$CARGO_TARGET_DIR/" | |
| - name: Restore Rust single-scope quality gate cache | |
| if: ${{ inputs.scope == 'repo' || inputs.scope == 'backend' || startsWith(inputs.scope, 'backend-consistency') || inputs.scope == 'state-protocols' || inputs.scope == 'repo-backend' || startsWith(inputs.scope, 'repo-backend-') || inputs.scope == 'coverage' || inputs.scope == 'coverage-backend' || startsWith(inputs.scope, 'coverage-backend-') }} | |
| uses: actions/cache@v5 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| tmp/quality-gate-cache/rust-single-${{ (inputs.scope == 'coverage' || inputs.scope == 'coverage-backend' || startsWith(inputs.scope, 'coverage-backend-')) && 'coverage' || 'backend' }}/${{ inputs.scope }}/target | |
| key: rust-quality-gate-v2-${{ (inputs.scope == 'coverage' || inputs.scope == 'coverage-backend' || startsWith(inputs.scope, 'coverage-backend-')) && 'coverage' || 'backend' }}-${{ runner.os }}-${{ inputs.scope }}-${{ hashFiles('api/Cargo.lock', 'api/**/Cargo.toml') }} | |
| restore-keys: | | |
| rust-quality-gate-v2-${{ (inputs.scope == 'coverage' || inputs.scope == 'coverage-backend' || startsWith(inputs.scope, 'coverage-backend-')) && 'coverage' || 'backend' }}-${{ runner.os }}-${{ inputs.scope }}-${{ hashFiles('api/Cargo.lock') }}- | |
| rust-quality-gate-v2-${{ (inputs.scope == 'coverage' || inputs.scope == 'coverage-backend' || startsWith(inputs.scope, 'coverage-backend-')) && 'coverage' || 'backend' }}-${{ runner.os }}-${{ inputs.scope }}- | |
| - uses: ./.github/actions/quality-gate | |
| env: | |
| CARGO_TARGET_DIR: ../tmp/quality-gate-cache/rust-single-${{ (inputs.scope == 'coverage' || inputs.scope == 'coverage-backend' || startsWith(inputs.scope, 'coverage-backend-')) && 'coverage' || 'backend' }}/${{ inputs.scope }}/target | |
| GITHUB_REF_NAME: ${{ env.QUALITY_GATE_TARGET_BRANCH }} | |
| GITHUB_SHA: ${{ env.QUALITY_GATE_TARGET_SHA }} | |
| REACT_DOCTOR_DIFF_BASE: ${{ inputs.react_doctor_base }} | |
| REACT_DOCTOR_BASE_SOURCE: workflow_dispatch.react_doctor_base | |
| REACT_DOCTOR_CANDIDATE_SOURCE: quality-gate-target-sha | |
| with: | |
| scope: ${{ env.QUALITY_GATE_SCOPE }} | |
| report_type: ${{ env.QUALITY_GATE_REPORT_TYPE }} | |
| environment: ${{ github.event_name == 'schedule' && env.QUALITY_GATE_SCHEDULED_ENVIRONMENT || inputs.environment }} | |
| publish_issue: "true" | |
| start_postgres: ${{ inputs.scope == 'repo' || inputs.scope == 'backend' || startsWith(inputs.scope, 'backend-consistency') || inputs.scope == 'state-protocols' || inputs.scope == 'repo-backend' || startsWith(inputs.scope, 'repo-backend-test-') || inputs.scope == 'coverage' || inputs.scope == 'coverage-backend' || startsWith(inputs.scope, 'coverage-backend-') }} | |
| github_token: ${{ secrets.GITHUB_TOKEN }} | |
| - uses: actions/upload-artifact@v6 | |
| if: always() | |
| with: | |
| name: test-governance-artifacts | |
| path: tmp/test-governance | |
| - uses: actions/upload-artifact@v6 | |
| if: always() | |
| with: | |
| name: test-governance-summary | |
| if-no-files-found: error | |
| path: | | |
| tmp/test-governance/quality-gate-report.json | |
| tmp/test-governance/quality-gate-report.md | |
| tmp/test-governance/quality-gate.latest.log | |
| repo-tooling-gate: | |
| if: ${{ github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.scope == 'ci') }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| ref: ${{ env.QUALITY_GATE_TARGET_BRANCH }} | |
| fetch-depth: 0 | |
| - name: Resolve quality gate target SHA | |
| run: echo "QUALITY_GATE_TARGET_SHA=$(git rev-parse HEAD)" >> "$GITHUB_ENV" | |
| - uses: pnpm/action-setup@v5 | |
| with: | |
| version: 11.5.0 | |
| - uses: actions/setup-node@v5 | |
| with: | |
| node-version: 24 | |
| cache: pnpm | |
| cache-dependency-path: web/pnpm-lock.yaml | |
| - run: pnpm --dir web install --frozen-lockfile | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: ./.github/actions/quality-gate | |
| env: | |
| GITHUB_REF_NAME: ${{ env.QUALITY_GATE_TARGET_BRANCH }} | |
| GITHUB_SHA: ${{ env.QUALITY_GATE_TARGET_SHA }} | |
| with: | |
| scope: repo-tooling | |
| report_type: ${{ env.QUALITY_GATE_REPORT_TYPE }} | |
| environment: ${{ github.event_name == 'schedule' && env.QUALITY_GATE_SCHEDULED_ENVIRONMENT || inputs.environment }} | |
| publish_issue: "false" | |
| start_postgres: "false" | |
| - uses: actions/upload-artifact@v6 | |
| if: always() | |
| with: | |
| name: test-governance-repo-tooling | |
| path: tmp/test-governance | |
| repo-frontend-gate: | |
| if: ${{ github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.scope == 'ci') }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 35 | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| ref: ${{ env.QUALITY_GATE_TARGET_BRANCH }} | |
| - name: Resolve quality gate target SHA | |
| run: echo "QUALITY_GATE_TARGET_SHA=$(git rev-parse HEAD)" >> "$GITHUB_ENV" | |
| - uses: pnpm/action-setup@v5 | |
| with: | |
| version: 11.5.0 | |
| - uses: actions/setup-node@v5 | |
| with: | |
| node-version: 24 | |
| cache: pnpm | |
| cache-dependency-path: web/pnpm-lock.yaml | |
| - run: pnpm --dir web install --frozen-lockfile | |
| - uses: ./.github/actions/quality-gate | |
| env: | |
| GITHUB_REF_NAME: ${{ env.QUALITY_GATE_TARGET_BRANCH }} | |
| GITHUB_SHA: ${{ env.QUALITY_GATE_TARGET_SHA }} | |
| with: | |
| scope: repo-frontend | |
| report_type: ${{ env.QUALITY_GATE_REPORT_TYPE }} | |
| environment: ${{ github.event_name == 'schedule' && env.QUALITY_GATE_SCHEDULED_ENVIRONMENT || inputs.environment }} | |
| publish_issue: "false" | |
| start_postgres: "false" | |
| - uses: actions/upload-artifact@v6 | |
| if: always() | |
| with: | |
| name: test-governance-repo-frontend | |
| path: tmp/test-governance | |
| repo-frontend-react-doctor-gate: | |
| if: ${{ github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.scope == 'ci') }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| ref: ${{ env.QUALITY_GATE_TARGET_BRANCH }} | |
| fetch-depth: 0 | |
| - name: Resolve quality gate target SHA | |
| run: echo "QUALITY_GATE_TARGET_SHA=$(git rev-parse HEAD)" >> "$GITHUB_ENV" | |
| - name: Resolve React Doctor base and candidate | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| REACT_DOCTOR_MANUAL_BASE: ${{ inputs.react_doctor_base }} | |
| run: | | |
| set -euo pipefail | |
| candidate_sha="${QUALITY_GATE_TARGET_SHA}" | |
| if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then | |
| base_sha="${REACT_DOCTOR_DIFF_BASE:-${REACT_DOCTOR_MANUAL_BASE:-}}" | |
| if [[ -z "${base_sha}" ]]; then | |
| echo "React Doctor manual runs require inputs.react_doctor_base (protected baseline SHA)" >&2 | |
| exit 1 | |
| fi | |
| base_source="workflow_dispatch.react_doctor_base" | |
| else | |
| previous_successful_run="$( | |
| gh api --method GET \ | |
| -H "Accept: application/vnd.github+json" \ | |
| -f "branch=${QUALITY_GATE_TARGET_BRANCH}" \ | |
| -f "status=success" \ | |
| -f "per_page=50" \ | |
| "repos/${GITHUB_REPOSITORY}/actions/workflows/quality-gate.yml/runs" \ | |
| | jq -r --arg candidate "${candidate_sha}" --arg run_id "${GITHUB_RUN_ID}" ' | |
| [ | |
| .workflow_runs[] | |
| | select((.id | tostring) != $run_id) | |
| | select(.head_sha != $candidate) | |
| | [.head_sha, (.id | tostring)] | |
| ] | |
| | .[0] | |
| | if . then @tsv else empty end | |
| ' | |
| )" | |
| if [[ -z "${previous_successful_run}" ]]; then | |
| echo "React Doctor scheduled run has no previous successful quality-gate candidate baseline" >&2 | |
| exit 1 | |
| fi | |
| base_sha="${previous_successful_run%%$'\t'*}" | |
| previous_run_id="${previous_successful_run#*$'\t'}" | |
| base_source="previous-successful-quality-gate-run:${previous_run_id}" | |
| fi | |
| git rev-parse --verify "${base_sha}^{commit}" >/dev/null | |
| git rev-parse --verify "${candidate_sha}^{commit}" >/dev/null | |
| { | |
| echo "REACT_DOCTOR_DIFF_BASE=${base_sha}" | |
| echo "REACT_DOCTOR_CANDIDATE_SHA=${candidate_sha}" | |
| echo "REACT_DOCTOR_BASE_SOURCE=${base_source}" | |
| echo "REACT_DOCTOR_CANDIDATE_SOURCE=quality-gate-target-sha" | |
| } >> "$GITHUB_ENV" | |
| - uses: pnpm/action-setup@v5 | |
| with: | |
| version: 11.5.0 | |
| - uses: actions/setup-node@v5 | |
| with: | |
| node-version: 24 | |
| cache: pnpm | |
| cache-dependency-path: web/pnpm-lock.yaml | |
| - run: pnpm --dir web install --frozen-lockfile | |
| - uses: ./.github/actions/quality-gate | |
| env: | |
| GITHUB_REF_NAME: ${{ env.QUALITY_GATE_TARGET_BRANCH }} | |
| GITHUB_SHA: ${{ env.QUALITY_GATE_TARGET_SHA }} | |
| with: | |
| scope: repo-frontend-react-doctor | |
| report_type: ${{ env.QUALITY_GATE_REPORT_TYPE }} | |
| environment: ${{ github.event_name == 'schedule' && env.QUALITY_GATE_SCHEDULED_ENVIRONMENT || inputs.environment }} | |
| publish_issue: "false" | |
| start_postgres: "false" | |
| - uses: actions/upload-artifact@v6 | |
| if: always() | |
| with: | |
| name: test-governance-repo-frontend-react-doctor | |
| path: tmp/test-governance | |
| repo-backend-gate: | |
| if: ${{ github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.scope == 'ci') }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 45 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| scope: | |
| - repo-backend-static | |
| - repo-backend-fmt | |
| - repo-backend-image-llm-vision | |
| - repo-backend-official-i18n-seed | |
| - repo-backend-clippy-core-libs | |
| - repo-backend-clippy-runtime-storage | |
| - repo-backend-clippy-apps | |
| - repo-backend-test-core-libs | |
| - repo-backend-test-runtime-storage-fast | |
| - repo-backend-test-storage-postgres-1-of-4 | |
| - repo-backend-test-storage-postgres-2-of-4 | |
| - repo-backend-test-storage-postgres-3-of-4 | |
| - repo-backend-test-storage-postgres-4-of-4 | |
| - repo-backend-test-control-plane | |
| - repo-backend-test-api-server-1-of-4 | |
| - repo-backend-test-api-server-2-of-4 | |
| - repo-backend-test-api-server-3-of-4 | |
| - repo-backend-test-api-server-4-of-4 | |
| - repo-backend-test-plugin-runner | |
| - repo-backend-check-core-libs | |
| - repo-backend-check-runtime-storage | |
| - repo-backend-check-apps | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| ref: ${{ env.QUALITY_GATE_TARGET_BRANCH }} | |
| - name: Resolve quality gate target SHA | |
| run: echo "QUALITY_GATE_TARGET_SHA=$(git rev-parse HEAD)" >> "$GITHUB_ENV" | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: taiki-e/install-action@nextest | |
| if: ${{ startsWith(matrix.scope, 'repo-backend-test-api-server-') || startsWith(matrix.scope, 'repo-backend-test-storage-postgres-') }} | |
| - name: Resolve release-seeded Rust cache architecture | |
| id: release_seed_arch | |
| if: ${{ matrix.scope != 'repo-backend-static' && matrix.scope != 'repo-backend-fmt' }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| case "${RUNNER_ARCH:-X64}" in | |
| ARM64) cache_arch=arm64 ;; | |
| *) cache_arch=amd64 ;; | |
| esac | |
| echo "cache_arch=$cache_arch" >> "$GITHUB_OUTPUT" | |
| - name: Restore release-seeded api-server Rust cache | |
| id: release_seed_api | |
| uses: actions/cache/restore@v5 | |
| with: | |
| path: | | |
| tmp/container-cache/api-server/${{ steps.release_seed_arch.outputs.cache_arch }}/cargo-registry | |
| tmp/container-cache/api-server/${{ steps.release_seed_arch.outputs.cache_arch }}/cargo-git | |
| tmp/container-cache/api-server/${{ steps.release_seed_arch.outputs.cache_arch }}/target | |
| key: rust-release-seeded-api-server-v2-${{ runner.os }}-${{ steps.release_seed_arch.outputs.cache_arch }}-rust-1-slim-bookworm-release-${{ hashFiles('api/Cargo.lock', 'api/**/Cargo.toml') }} | |
| restore-keys: | | |
| rust-release-seeded-api-server-v2-${{ runner.os }}-${{ steps.release_seed_arch.outputs.cache_arch }}-rust-1-slim-bookworm-release-${{ hashFiles('api/Cargo.lock') }}- | |
| rust-release-seeded-api-server-v2-${{ runner.os }}-${{ steps.release_seed_arch.outputs.cache_arch }}-rust-1-slim-bookworm-release- | |
| - name: Import release-seeded api-server Rust cache | |
| if: ${{ steps.release_seed_api.outputs.cache-hit != '' }} | |
| shell: bash | |
| env: | |
| RUST_RELEASE_SEEDED_CACHE_ARCH: ${{ steps.release_seed_arch.outputs.cache_arch }} | |
| CARGO_TARGET_DIR: tmp/quality-gate-cache/rust-backend/${{ matrix.scope }}/target | |
| run: | | |
| set -euo pipefail | |
| cargo_home="${CARGO_HOME:-$HOME/.cargo}" | |
| mkdir -p "$cargo_home/registry" "$cargo_home/git" "$CARGO_TARGET_DIR" | |
| rsync -a "tmp/container-cache/api-server/$RUST_RELEASE_SEEDED_CACHE_ARCH/cargo-registry/" "$cargo_home/registry/" | |
| rsync -a "tmp/container-cache/api-server/$RUST_RELEASE_SEEDED_CACHE_ARCH/cargo-git/" "$cargo_home/git/" | |
| rsync -a "tmp/container-cache/api-server/$RUST_RELEASE_SEEDED_CACHE_ARCH/target/" "$CARGO_TARGET_DIR/" | |
| - name: Restore Rust backend quality gate cache | |
| if: ${{ matrix.scope != 'repo-backend-static' && matrix.scope != 'repo-backend-fmt' }} | |
| uses: actions/cache@v5 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| tmp/quality-gate-cache/rust-backend/${{ matrix.scope }}/target | |
| key: rust-quality-gate-backend-v2-${{ runner.os }}-${{ matrix.scope }}-${{ hashFiles('api/Cargo.lock', 'api/**/Cargo.toml') }} | |
| restore-keys: | | |
| rust-quality-gate-backend-v2-${{ runner.os }}-${{ matrix.scope }}-${{ hashFiles('api/Cargo.lock') }}- | |
| rust-quality-gate-backend-v2-${{ runner.os }}-${{ matrix.scope }}- | |
| rust-quality-gate-backend-v2-${{ runner.os }}- | |
| - uses: ./.github/actions/quality-gate | |
| env: | |
| CARGO_TARGET_DIR: ../tmp/quality-gate-cache/rust-backend/${{ matrix.scope }}/target | |
| GITHUB_REF_NAME: ${{ env.QUALITY_GATE_TARGET_BRANCH }} | |
| GITHUB_SHA: ${{ env.QUALITY_GATE_TARGET_SHA }} | |
| with: | |
| scope: ${{ matrix.scope }} | |
| report_type: ${{ env.QUALITY_GATE_REPORT_TYPE }} | |
| environment: ${{ github.event_name == 'schedule' && env.QUALITY_GATE_SCHEDULED_ENVIRONMENT || inputs.environment }} | |
| publish_issue: "false" | |
| start_postgres: ${{ startsWith(matrix.scope, 'repo-backend-test-') }} | |
| - uses: actions/upload-artifact@v6 | |
| if: always() | |
| with: | |
| name: test-governance-${{ matrix.scope }} | |
| path: tmp/test-governance | |
| backend-consistency-gate: | |
| if: ${{ github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.scope == 'ci') }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 35 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| group: | |
| - control-runtime | |
| - storage | |
| - api | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| ref: ${{ env.QUALITY_GATE_TARGET_BRANCH }} | |
| - name: Resolve quality gate target SHA | |
| run: echo "QUALITY_GATE_TARGET_SHA=$(git rev-parse HEAD)" >> "$GITHUB_ENV" | |
| - uses: dtolnay/rust-toolchain@stable | |
| - name: Resolve release-seeded Rust cache architecture | |
| id: release_seed_arch | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| case "${RUNNER_ARCH:-X64}" in | |
| ARM64) cache_arch=arm64 ;; | |
| *) cache_arch=amd64 ;; | |
| esac | |
| echo "cache_arch=$cache_arch" >> "$GITHUB_OUTPUT" | |
| - name: Restore release-seeded api-server Rust cache | |
| id: release_seed_api | |
| uses: actions/cache/restore@v5 | |
| with: | |
| path: | | |
| tmp/container-cache/api-server/${{ steps.release_seed_arch.outputs.cache_arch }}/cargo-registry | |
| tmp/container-cache/api-server/${{ steps.release_seed_arch.outputs.cache_arch }}/cargo-git | |
| tmp/container-cache/api-server/${{ steps.release_seed_arch.outputs.cache_arch }}/target | |
| key: rust-release-seeded-api-server-v2-${{ runner.os }}-${{ steps.release_seed_arch.outputs.cache_arch }}-rust-1-slim-bookworm-release-${{ hashFiles('api/Cargo.lock', 'api/**/Cargo.toml') }} | |
| restore-keys: | | |
| rust-release-seeded-api-server-v2-${{ runner.os }}-${{ steps.release_seed_arch.outputs.cache_arch }}-rust-1-slim-bookworm-release-${{ hashFiles('api/Cargo.lock') }}- | |
| rust-release-seeded-api-server-v2-${{ runner.os }}-${{ steps.release_seed_arch.outputs.cache_arch }}-rust-1-slim-bookworm-release- | |
| - name: Import release-seeded api-server Rust cache | |
| if: ${{ steps.release_seed_api.outputs.cache-hit != '' }} | |
| shell: bash | |
| env: | |
| RUST_RELEASE_SEEDED_CACHE_ARCH: ${{ steps.release_seed_arch.outputs.cache_arch }} | |
| CARGO_TARGET_DIR: tmp/quality-gate-cache/rust-backend-consistency/${{ matrix.group }}/target | |
| run: | | |
| set -euo pipefail | |
| cargo_home="${CARGO_HOME:-$HOME/.cargo}" | |
| mkdir -p "$cargo_home/registry" "$cargo_home/git" "$CARGO_TARGET_DIR" | |
| rsync -a "tmp/container-cache/api-server/$RUST_RELEASE_SEEDED_CACHE_ARCH/cargo-registry/" "$cargo_home/registry/" | |
| rsync -a "tmp/container-cache/api-server/$RUST_RELEASE_SEEDED_CACHE_ARCH/cargo-git/" "$cargo_home/git/" | |
| rsync -a "tmp/container-cache/api-server/$RUST_RELEASE_SEEDED_CACHE_ARCH/target/" "$CARGO_TARGET_DIR/" | |
| - name: Restore Rust backend consistency quality gate cache | |
| uses: actions/cache@v5 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| tmp/quality-gate-cache/rust-backend-consistency/${{ matrix.group }}/target | |
| key: rust-quality-gate-backend-consistency-v2-${{ runner.os }}-${{ matrix.group }}-${{ hashFiles('api/Cargo.lock', 'api/**/Cargo.toml') }} | |
| restore-keys: | | |
| rust-quality-gate-backend-consistency-v2-${{ runner.os }}-${{ matrix.group }}-${{ hashFiles('api/Cargo.lock') }}- | |
| rust-quality-gate-backend-consistency-v2-${{ runner.os }}-${{ matrix.group }}- | |
| rust-quality-gate-backend-consistency-v2-${{ runner.os }}- | |
| - uses: ./.github/actions/quality-gate | |
| env: | |
| CARGO_TARGET_DIR: ../tmp/quality-gate-cache/rust-backend-consistency/${{ matrix.group }}/target | |
| GITHUB_REF_NAME: ${{ env.QUALITY_GATE_TARGET_BRANCH }} | |
| GITHUB_SHA: ${{ env.QUALITY_GATE_TARGET_SHA }} | |
| with: | |
| scope: backend-consistency-${{ matrix.group }} | |
| report_type: ${{ env.QUALITY_GATE_REPORT_TYPE }} | |
| environment: ${{ github.event_name == 'schedule' && env.QUALITY_GATE_SCHEDULED_ENVIRONMENT || inputs.environment }} | |
| publish_issue: "false" | |
| - uses: actions/upload-artifact@v6 | |
| if: always() | |
| with: | |
| name: test-governance-backend-consistency-${{ matrix.group }} | |
| path: tmp/test-governance | |
| coverage-frontend-gate: | |
| if: ${{ github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.scope == 'ci') }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 35 | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| ref: ${{ env.QUALITY_GATE_TARGET_BRANCH }} | |
| - name: Resolve quality gate target SHA | |
| run: echo "QUALITY_GATE_TARGET_SHA=$(git rev-parse HEAD)" >> "$GITHUB_ENV" | |
| - uses: pnpm/action-setup@v5 | |
| with: | |
| version: 11.5.0 | |
| - uses: actions/setup-node@v5 | |
| with: | |
| node-version: 24 | |
| cache: pnpm | |
| cache-dependency-path: web/pnpm-lock.yaml | |
| - run: pnpm --dir web install --frozen-lockfile | |
| - uses: ./.github/actions/quality-gate | |
| env: | |
| GITHUB_REF_NAME: ${{ env.QUALITY_GATE_TARGET_BRANCH }} | |
| GITHUB_SHA: ${{ env.QUALITY_GATE_TARGET_SHA }} | |
| with: | |
| scope: coverage-frontend | |
| report_type: ${{ env.QUALITY_GATE_REPORT_TYPE }} | |
| environment: ${{ github.event_name == 'schedule' && env.QUALITY_GATE_SCHEDULED_ENVIRONMENT || inputs.environment }} | |
| publish_issue: "false" | |
| start_postgres: "false" | |
| - uses: actions/upload-artifact@v6 | |
| if: always() | |
| with: | |
| name: test-governance-coverage-frontend | |
| path: tmp/test-governance | |
| coverage-backend-gate: | |
| if: ${{ github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.scope == 'ci') }} | |
| needs: resolve-quality-gate-target | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 55 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| scope: | |
| - coverage-backend-control-plane | |
| - coverage-backend-orchestration-runtime | |
| - coverage-backend-plugin-runner | |
| - coverage-backend-storage-postgres | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| ref: ${{ needs.resolve-quality-gate-target.outputs.target_sha }} | |
| - name: Resolve quality gate target SHA | |
| run: echo "QUALITY_GATE_TARGET_SHA=${{ needs.resolve-quality-gate-target.outputs.target_sha }}" >> "$GITHUB_ENV" | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: taiki-e/install-action@cargo-llvm-cov | |
| - name: Resolve release-seeded Rust cache architecture | |
| id: release_seed_arch | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| case "${RUNNER_ARCH:-X64}" in | |
| ARM64) cache_arch=arm64 ;; | |
| *) cache_arch=amd64 ;; | |
| esac | |
| echo "cache_arch=$cache_arch" >> "$GITHUB_OUTPUT" | |
| - name: Restore release-seeded api-server Rust cache | |
| id: release_seed_api | |
| uses: actions/cache/restore@v5 | |
| with: | |
| path: | | |
| tmp/container-cache/api-server/${{ steps.release_seed_arch.outputs.cache_arch }}/cargo-registry | |
| tmp/container-cache/api-server/${{ steps.release_seed_arch.outputs.cache_arch }}/cargo-git | |
| tmp/container-cache/api-server/${{ steps.release_seed_arch.outputs.cache_arch }}/target | |
| key: rust-release-seeded-api-server-v2-${{ runner.os }}-${{ steps.release_seed_arch.outputs.cache_arch }}-rust-1-slim-bookworm-release-${{ hashFiles('api/Cargo.lock', 'api/**/Cargo.toml') }} | |
| restore-keys: | | |
| rust-release-seeded-api-server-v2-${{ runner.os }}-${{ steps.release_seed_arch.outputs.cache_arch }}-rust-1-slim-bookworm-release-${{ hashFiles('api/Cargo.lock') }}- | |
| rust-release-seeded-api-server-v2-${{ runner.os }}-${{ steps.release_seed_arch.outputs.cache_arch }}-rust-1-slim-bookworm-release- | |
| - name: Import release-seeded api-server Rust cache | |
| if: ${{ steps.release_seed_api.outputs.cache-hit != '' }} | |
| shell: bash | |
| env: | |
| RUST_RELEASE_SEEDED_CACHE_ARCH: ${{ steps.release_seed_arch.outputs.cache_arch }} | |
| CARGO_TARGET_DIR: tmp/quality-gate-cache/rust-coverage/${{ matrix.scope }}/target | |
| run: | | |
| set -euo pipefail | |
| cargo_home="${CARGO_HOME:-$HOME/.cargo}" | |
| mkdir -p "$cargo_home/registry" "$cargo_home/git" "$CARGO_TARGET_DIR" | |
| rsync -a "tmp/container-cache/api-server/$RUST_RELEASE_SEEDED_CACHE_ARCH/cargo-registry/" "$cargo_home/registry/" | |
| rsync -a "tmp/container-cache/api-server/$RUST_RELEASE_SEEDED_CACHE_ARCH/cargo-git/" "$cargo_home/git/" | |
| rsync -a "tmp/container-cache/api-server/$RUST_RELEASE_SEEDED_CACHE_ARCH/target/" "$CARGO_TARGET_DIR/" | |
| - name: Restore Rust coverage quality gate cache | |
| uses: actions/cache@v5 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| tmp/quality-gate-cache/rust-coverage/${{ matrix.scope }}/target | |
| key: rust-quality-gate-coverage-v2-${{ runner.os }}-${{ matrix.scope }}-${{ hashFiles('api/Cargo.lock', 'api/**/Cargo.toml') }} | |
| restore-keys: | | |
| rust-quality-gate-coverage-v2-${{ runner.os }}-${{ matrix.scope }}-${{ hashFiles('api/Cargo.lock') }}- | |
| rust-quality-gate-coverage-v2-${{ runner.os }}-${{ matrix.scope }}- | |
| rust-quality-gate-coverage-v2-${{ runner.os }}- | |
| - uses: ./.github/actions/quality-gate | |
| env: | |
| CARGO_TARGET_DIR: ../tmp/quality-gate-cache/rust-coverage/${{ matrix.scope }}/target | |
| GITHUB_REF_NAME: ${{ env.QUALITY_GATE_TARGET_BRANCH }} | |
| GITHUB_SHA: ${{ env.QUALITY_GATE_TARGET_SHA }} | |
| with: | |
| scope: ${{ matrix.scope }} | |
| report_type: ${{ env.QUALITY_GATE_REPORT_TYPE }} | |
| environment: ${{ github.event_name == 'schedule' && env.QUALITY_GATE_SCHEDULED_ENVIRONMENT || inputs.environment }} | |
| publish_issue: "false" | |
| - name: Record immutable coverage target SHA | |
| if: always() | |
| run: echo "$QUALITY_GATE_TARGET_SHA" > tmp/test-governance/target-sha.txt | |
| - uses: actions/upload-artifact@v6 | |
| if: always() | |
| with: | |
| name: test-governance-${{ matrix.scope }} | |
| path: tmp/test-governance | |
| coverage-backend-api-server-sharded: | |
| if: ${{ github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.scope == 'ci') }} | |
| needs: resolve-quality-gate-target | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| shard: [1, 2, 3, 4] | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| ref: ${{ needs.resolve-quality-gate-target.outputs.target_sha }} | |
| - name: Resolve quality gate target SHA | |
| run: echo "QUALITY_GATE_TARGET_SHA=${{ needs.resolve-quality-gate-target.outputs.target_sha }}" >> "$GITHUB_ENV" | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: taiki-e/install-action@cargo-llvm-cov | |
| - uses: taiki-e/install-action@nextest | |
| - uses: actions/cache@v5 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| tmp/quality-gate-cache/rust-coverage/api-server-shadow/target | |
| key: rust-quality-gate-coverage-v2-${{ runner.os }}-api-server-shadow-${{ hashFiles('api/Cargo.lock', 'api/**/Cargo.toml') }} | |
| restore-keys: | | |
| rust-quality-gate-coverage-v2-${{ runner.os }}-api-server-shadow-${{ hashFiles('api/Cargo.lock') }}- | |
| rust-quality-gate-coverage-v2-${{ runner.os }}-api-server-shadow- | |
| - uses: ./.github/actions/quality-gate | |
| env: | |
| CARGO_TARGET_DIR: ../tmp/quality-gate-cache/rust-coverage/api-server-shadow/target | |
| GITHUB_REF_NAME: ${{ env.QUALITY_GATE_TARGET_BRANCH }} | |
| QUALITY_GATE_TARGET_SHA: ${{ env.QUALITY_GATE_TARGET_SHA }} | |
| with: | |
| scope: coverage-backend-api-server-sharded-${{ matrix.shard }}-of-4 | |
| report_type: ${{ env.QUALITY_GATE_REPORT_TYPE }} | |
| environment: ${{ github.event_name == 'schedule' && env.QUALITY_GATE_SCHEDULED_ENVIRONMENT || inputs.environment }} | |
| publish_issue: "false" | |
| - uses: actions/upload-artifact@v6 | |
| if: always() | |
| with: | |
| name: coverage-shadow-api-server-profraw-${{ matrix.shard }} | |
| path: tmp/test-governance/coverage-shadow/api-server/shard-${{ matrix.shard }} | |
| coverage-backend-api-server-sharded-merge: | |
| if: ${{ always() && (github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.scope == 'ci')) }} | |
| needs: | |
| - resolve-quality-gate-target | |
| - coverage-backend-api-server-sharded | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| ref: ${{ needs.resolve-quality-gate-target.outputs.target_sha }} | |
| - name: Resolve quality gate target SHA | |
| run: echo "QUALITY_GATE_TARGET_SHA=${{ needs.resolve-quality-gate-target.outputs.target_sha }}" >> "$GITHUB_ENV" | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: taiki-e/install-action@cargo-llvm-cov | |
| - uses: taiki-e/install-action@nextest | |
| - uses: actions/cache/restore@v5 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| tmp/quality-gate-cache/rust-coverage/api-server-shadow/target | |
| key: rust-quality-gate-coverage-v2-${{ runner.os }}-api-server-shadow-${{ hashFiles('api/Cargo.lock', 'api/**/Cargo.toml') }} | |
| restore-keys: | | |
| rust-quality-gate-coverage-v2-${{ runner.os }}-api-server-shadow-${{ hashFiles('api/Cargo.lock') }}- | |
| rust-quality-gate-coverage-v2-${{ runner.os }}-api-server-shadow- | |
| - uses: actions/download-artifact@v6 | |
| with: | |
| pattern: coverage-shadow-api-server-profraw-* | |
| path: tmp/test-governance/coverage-shadow/api-server/downloaded | |
| merge-multiple: true | |
| - name: Merge and enforce sharded API coverage | |
| env: | |
| CARGO_TARGET_DIR: ../tmp/quality-gate-cache/rust-coverage/api-server-shadow/target | |
| QUALITY_GATE_TARGET_SHA: ${{ env.QUALITY_GATE_TARGET_SHA }} | |
| run: node scripts/node/coverage-shadow.js merge api-server 4 | |
| - uses: actions/upload-artifact@v6 | |
| if: always() | |
| with: | |
| name: coverage-shadow-api-server-equivalence | |
| path: | | |
| tmp/test-governance/coverage-shadow/api-server/api-server-merged.json | |
| tmp/test-governance/coverage-shadow/api-server/equivalence.json | |
| container-images-gate: | |
| if: ${{ github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && (inputs.scope == 'ci' || inputs.scope == 'container-images')) }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 45 | |
| permissions: | |
| contents: read | |
| packages: read | |
| issues: write | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| ref: ${{ env.QUALITY_GATE_TARGET_BRANCH }} | |
| - name: Resolve quality gate target SHA | |
| run: echo "QUALITY_GATE_TARGET_SHA=$(git rev-parse HEAD)" >> "$GITHUB_ENV" | |
| - uses: actions/setup-node@v5 | |
| with: | |
| node-version: 24 | |
| - name: Prepare Trivy report directory | |
| run: mkdir -p tmp/test-governance | |
| - name: Generate web HIGH Trivy warning report | |
| uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 | |
| env: | |
| TRIVY_USERNAME: ${{ github.actor }} | |
| TRIVY_PASSWORD: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| image-ref: ghcr.io/${{ github.repository_owner }}/1flowbase-web:latest | |
| version: v0.70.0 | |
| scanners: vuln | |
| severity: HIGH | |
| format: json | |
| output: tmp/test-governance/trivy-web-high.json | |
| exit-code: "0" | |
| - name: Generate web CRITICAL Trivy gate report | |
| uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 | |
| env: | |
| TRIVY_USERNAME: ${{ github.actor }} | |
| TRIVY_PASSWORD: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| image-ref: ghcr.io/${{ github.repository_owner }}/1flowbase-web:latest | |
| version: v0.70.0 | |
| scanners: vuln | |
| severity: CRITICAL | |
| format: json | |
| output: tmp/test-governance/trivy-web-critical.json | |
| exit-code: "0" | |
| - name: Generate api-server HIGH Trivy warning report | |
| uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 | |
| env: | |
| TRIVY_USERNAME: ${{ github.actor }} | |
| TRIVY_PASSWORD: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| image-ref: ghcr.io/${{ github.repository_owner }}/1flowbase-api-server:latest | |
| version: v0.70.0 | |
| scanners: vuln | |
| severity: HIGH | |
| format: json | |
| output: tmp/test-governance/trivy-api-server-high.json | |
| exit-code: "0" | |
| - name: Generate api-server CRITICAL Trivy gate report | |
| uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 | |
| env: | |
| TRIVY_USERNAME: ${{ github.actor }} | |
| TRIVY_PASSWORD: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| image-ref: ghcr.io/${{ github.repository_owner }}/1flowbase-api-server:latest | |
| version: v0.70.0 | |
| scanners: vuln | |
| severity: CRITICAL | |
| format: json | |
| output: tmp/test-governance/trivy-api-server-critical.json | |
| exit-code: "0" | |
| - name: Generate plugin-runner HIGH Trivy warning report | |
| uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 | |
| env: | |
| TRIVY_USERNAME: ${{ github.actor }} | |
| TRIVY_PASSWORD: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| image-ref: ghcr.io/${{ github.repository_owner }}/1flowbase-plugin-runner:latest | |
| version: v0.70.0 | |
| scanners: vuln | |
| severity: HIGH | |
| format: json | |
| output: tmp/test-governance/trivy-plugin-runner-high.json | |
| exit-code: "0" | |
| - name: Generate plugin-runner CRITICAL Trivy gate report | |
| uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 | |
| env: | |
| TRIVY_USERNAME: ${{ github.actor }} | |
| TRIVY_PASSWORD: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| image-ref: ghcr.io/${{ github.repository_owner }}/1flowbase-plugin-runner:latest | |
| version: v0.70.0 | |
| scanners: vuln | |
| severity: CRITICAL | |
| format: json | |
| output: tmp/test-governance/trivy-plugin-runner-critical.json | |
| exit-code: "0" | |
| - uses: ./.github/actions/quality-gate | |
| env: | |
| GITHUB_REF_NAME: ${{ env.QUALITY_GATE_TARGET_BRANCH }} | |
| GITHUB_SHA: ${{ env.QUALITY_GATE_TARGET_SHA }} | |
| with: | |
| scope: container-images | |
| report_type: ${{ env.QUALITY_GATE_REPORT_TYPE }} | |
| environment: ${{ github.event_name == 'schedule' && env.QUALITY_GATE_SCHEDULED_ENVIRONMENT || inputs.environment || 'container-images' }} | |
| publish_issue: "false" | |
| start_postgres: "false" | |
| github_token: ${{ secrets.GITHUB_TOKEN }} | |
| - uses: actions/upload-artifact@v6 | |
| if: always() | |
| with: | |
| name: test-governance-container-images | |
| path: tmp/test-governance | |
| ai-gateway-protocol-conformance: | |
| if: ${{ github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.scope == 'ci') }} | |
| uses: ./.github/workflows/ai-gateway-concurrency.yml | |
| with: | |
| target_ref: ${{ github.event_name == 'workflow_dispatch' && inputs.target_branch || 'latest' }} | |
| aggregate: | |
| if: ${{ always() && (github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.scope == 'ci')) }} | |
| needs: | |
| - repo-tooling-gate | |
| - repo-frontend-gate | |
| - repo-frontend-react-doctor-gate | |
| - repo-backend-gate | |
| - backend-consistency-gate | |
| - coverage-frontend-gate | |
| - coverage-backend-gate | |
| - coverage-backend-api-server-sharded-merge | |
| - container-images-gate | |
| - ai-gateway-protocol-conformance | |
| - foundation-contract-gate | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| ref: ${{ env.QUALITY_GATE_TARGET_BRANCH }} | |
| - name: Resolve quality gate target SHA | |
| run: echo "QUALITY_GATE_TARGET_SHA=$(git rev-parse HEAD)" >> "$GITHUB_ENV" | |
| - uses: actions/download-artifact@v6 | |
| with: | |
| pattern: test-governance-* | |
| path: tmp/test-governance/parallel | |
| merge-multiple: false | |
| - run: node scripts/node/cli/github-quality-gate-aggregate.js | |
| env: | |
| GITHUB_REF_NAME: ${{ env.QUALITY_GATE_TARGET_BRANCH }} | |
| GITHUB_SHA: ${{ env.QUALITY_GATE_TARGET_SHA }} | |
| INPUT_ARTIFACT_ROOT: tmp/test-governance/parallel | |
| INPUT_REPORT_TYPE: ${{ env.QUALITY_GATE_REPORT_TYPE }} | |
| INPUT_ENVIRONMENT: ${{ github.event_name == 'schedule' && env.QUALITY_GATE_SCHEDULED_ENVIRONMENT || inputs.environment }} | |
| INPUT_EXPECTED_SCOPES: 'repo-tooling,repo-frontend,repo-frontend-react-doctor,repo-backend-static,repo-backend-fmt,repo-backend-image-llm-vision,repo-backend-official-i18n-seed,repo-backend-clippy-core-libs,repo-backend-clippy-runtime-storage,repo-backend-clippy-apps,repo-backend-test-core-libs,repo-backend-test-runtime-storage-fast,repo-backend-test-storage-postgres-1-of-4,repo-backend-test-storage-postgres-2-of-4,repo-backend-test-storage-postgres-3-of-4,repo-backend-test-storage-postgres-4-of-4,repo-backend-test-control-plane,repo-backend-test-api-server-1-of-4,repo-backend-test-api-server-2-of-4,repo-backend-test-api-server-3-of-4,repo-backend-test-api-server-4-of-4,repo-backend-test-plugin-runner,repo-backend-check-core-libs,repo-backend-check-runtime-storage,repo-backend-check-apps,backend-consistency-control-runtime,backend-consistency-storage,backend-consistency-api,coverage-frontend,coverage-backend-control-plane,coverage-backend-orchestration-runtime,coverage-backend-plugin-runner,coverage-backend-storage-postgres,container-images,ai-gateway-protocol-conformance,foundation-contracts' | |
| INPUT_PUBLISH_ISSUE: "true" | |
| INPUT_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - uses: actions/upload-artifact@v6 | |
| if: always() | |
| with: | |
| name: test-governance-artifacts | |
| path: tmp/test-governance |