name: frontend-quality-gates on: push: branches: [develop] tags: ["v*"] pull_request: workflow_dispatch: inputs: stage: description: Highest promotion tier to evaluate required: true default: merge type: choice options: - merge - release - production - field - documentation env: NODE_VERSION: "24" jobs: merge_gate: name: ${{ matrix.gate }} / ${{ matrix.name }} if: ${{ gitea.event_name != 'workflow_dispatch' || inputs.stage != 'documentation' }} runs-on: ubuntu-latest strategy: fail-fast: false matrix: include: - { gate: FE-GATE-001, name: manifest-lockfile, browser: false } - { gate: FE-GATE-002, name: lint, browser: false } - { gate: FE-GATE-003, name: typecheck, browser: false } - { gate: FE-GATE-004, name: runtime-schema, browser: false } - { gate: FE-GATE-005, name: unit, browser: false } - { gate: FE-GATE-006, name: component, browser: false } - { gate: FE-GATE-007, name: integration, browser: false } - { gate: FE-GATE-008, name: e2e, browser: true } - { gate: FE-GATE-009, name: accessibility, browser: true } - { gate: FE-GATE-010, name: architecture, browser: false } - { gate: FE-GATE-011, name: build, browser: false } - { gate: FE-GATE-013, name: security, browser: false } - { gate: FE-GATE-020, name: sample-removal, browser: false } steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} - name: Frozen install run: | corepack enable corepack pnpm install --frozen-lockfile - name: Install Chromium if: ${{ matrix.browser }} run: corepack pnpm exec playwright install --with-deps chromium - name: Run blocking gate run: corepack pnpm ci:gate -- ${{ matrix.gate }} - name: Upload gate evidence if: always() uses: actions/upload-artifact@v4 with: name: ${{ matrix.gate }}-${{ gitea.run_id }} path: artifacts/ if-no-files-found: warn release_gate: name: ${{ matrix.gate }} / ${{ matrix.name }} needs: merge_gate if: ${{ startsWith(gitea.ref, 'refs/tags/v') || (gitea.event_name == 'workflow_dispatch' && (inputs.stage == 'release' || inputs.stage == 'production' || inputs.stage == 'field')) }} runs-on: ubuntu-latest env: HOSTING_BASE_URL: ${{ vars.HOSTING_BASE_URL }} strategy: fail-fast: false matrix: include: - { gate: FE-GATE-012, name: bundle, browser: false } - { gate: FE-GATE-014, name: config-compatibility, browser: false } - { gate: FE-GATE-015, name: release-coherence, browser: false } - { gate: FE-GATE-019, name: hosting-header, browser: false } - { gate: FE-GATE-026, name: lab-performance, browser: true } steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} - name: Frozen install run: | corepack enable corepack pnpm install --frozen-lockfile - name: Install Chromium if: ${{ matrix.browser }} run: corepack pnpm exec playwright install --with-deps chromium - name: Run blocking gate run: corepack pnpm ci:gate -- ${{ matrix.gate }} - name: Upload gate evidence if: always() uses: actions/upload-artifact@v4 with: name: ${{ matrix.gate }}-${{ gitea.run_id }} path: artifacts/ if-no-files-found: warn production_gate: name: ${{ matrix.gate }} / ${{ matrix.name }} needs: release_gate if: ${{ gitea.event_name == 'workflow_dispatch' && (inputs.stage == 'production' || inputs.stage == 'field') }} runs-on: ubuntu-latest strategy: fail-fast: false matrix: include: - { gate: FE-GATE-016, name: rollback-drill } - { gate: FE-GATE-021, name: runbook-boot-config } - { gate: FE-GATE-022, name: runbook-chunk-mismatch } - { gate: FE-GATE-023, name: runbook-api-degradation } - { gate: FE-GATE-024, name: runbook-telemetry } - { gate: FE-GATE-025, name: runbook-release-rollback } steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} - name: Frozen install run: | corepack enable corepack pnpm install --frozen-lockfile - name: Run blocking gate run: corepack pnpm ci:gate -- ${{ matrix.gate }} - name: Upload gate evidence if: always() uses: actions/upload-artifact@v4 with: name: ${{ matrix.gate }}-${{ gitea.run_id }} path: artifacts/ if-no-files-found: warn field_gate: name: FE-GATE-018 / field-web-vitals needs: production_gate if: ${{ gitea.event_name == 'workflow_dispatch' && inputs.stage == 'field' }} runs-on: ubuntu-latest env: FIELD_WEB_VITALS_INPUT: ${{ vars.FIELD_WEB_VITALS_INPUT }} MIN_ELIGIBLE_SAMPLES: ${{ vars.MIN_ELIGIBLE_SAMPLES }} steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} - name: Frozen install run: | corepack enable corepack pnpm install --frozen-lockfile - name: Run blocking gate run: corepack pnpm ci:gate -- FE-GATE-018 - name: Upload gate evidence if: always() uses: actions/upload-artifact@v4 with: name: FE-GATE-018-${{ gitea.run_id }} path: artifacts/ if-no-files-found: warn documentation_gate: name: FE-GATE-017 / diagram-review if: ${{ gitea.event_name == 'workflow_dispatch' && inputs.stage == 'documentation' }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} - name: Frozen install run: | corepack enable corepack pnpm install --frozen-lockfile - name: Run documentation gate run: corepack pnpm ci:gate -- FE-GATE-017 - name: Upload gate evidence if: always() uses: actions/upload-artifact@v4 with: name: FE-GATE-017-${{ gitea.run_id }} path: artifacts/ if-no-files-found: warn