name: Frontend checks on: pull_request: branches: [main, dev] # The merge queue builds main plus the queued pull requests on a temporary # branch and only counts checks that ran on the merge_group event. merge_group: push: branches: [main] workflow_dispatch: {} permissions: contents: read jobs: build-and-test: name: Build and test # Org reusable workflow (Node 24): format check, lint, build, unit tests. uses: Sea-Haven-Industries/.github/.github/workflows/ci-typescript-frontend.yaml@af0f002e14a08cdbfd879c1183bfe7eb2604bce9 # v1.0.8 with: node-version: "24" governance: # Repo-owned guarantee that every frontend quality gate runs from this # repository, independent of (and in addition to) the reusable workflow. # `npm run verify` is the single command that chains: format check, lint # (--max-warnings=0), type-check + build, unit tests, then the governance # checks in scripts/governance-check.mjs (godfile ratchet, changed-file # maintainability gate, Terraform fmt/validate, Terraform import-plan # guard, HCP run guard, CloudFront verify, GitHub workflow shell, and G13 # app/Terraform isolation). Runs on PRs to main or dev; push is main only. # If the reusable workflow is later confirmed to run every gate, this job # can be slimmed to `npm run governance`. # # GOVERNANCE_BASE points the changed-file gate at the right diff: # PR -> the PR target branch (origin/) # merge group -> the group's own base (github.event.merge_group.base_sha) # push-> the previous commit on the branch (github.event.before) # manual -> main, for exact-head recovery runs runs-on: ubuntu-latest steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 - name: Resolve governance comparison ref id: governance-ref shell: bash env: EVENT_NAME: ${{ github.event_name }} EVENT_BEFORE: ${{ github.event.before }} PR_BASE_SHA: ${{ github.event.pull_request.base.sha }} MERGE_GROUP_BASE_SHA: ${{ github.event.merge_group.base_sha }} run: | set -euo pipefail if [[ "${EVENT_NAME}" == "pull_request" ]]; then base="${PR_BASE_SHA}" elif [[ "${EVENT_NAME}" == "merge_group" && -n "${MERGE_GROUP_BASE_SHA}" ]]; then base="${MERGE_GROUP_BASE_SHA}" elif [[ "${EVENT_NAME}" == "push" && -n "${EVENT_BEFORE}" && ! "${EVENT_BEFORE}" =~ ^0+$ ]]; then base="${EVENT_BEFORE}" else base="origin/main" fi printf 'base=%s\n' "${base}" >> "${GITHUB_OUTPUT}" - name: Set up Terraform # Same minor as the HCP workspace (1.16.x) so fmt/validate see what # the remote run will see. uses: hashicorp/setup-terraform@dfe3c3f87815947d99a8997f908cb6525fc44e9e # v4.0.1 with: terraform_version: "1.16.0" terraform_wrapper: false - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: "24" cache: npm - name: Install actionlint env: ACTIONLINT_VERSION: "1.7.12" ACTIONLINT_SHA256: 8aca8db96f1b94770f1b0d72b6dddcb1ebb8123cb3712530b08cc387b349a3d8 run: | set -euo pipefail curl -fsSL -o actionlint.tar.gz \ "https://github.com/rhysd/actionlint/releases/download/v${ACTIONLINT_VERSION}/actionlint_${ACTIONLINT_VERSION}_linux_amd64.tar.gz" echo "${ACTIONLINT_SHA256} actionlint.tar.gz" | sha256sum -c - tar -xzf actionlint.tar.gz actionlint sudo mv actionlint /usr/local/bin/actionlint - run: npm ci - run: npm run verify env: GOVERNANCE_BASE: ${{ steps.governance-ref.outputs.base }} visual-regression: name: Visual regression runs-on: ubuntu-latest container: mcr.microsoft.com/playwright:v1.61.1-noble steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: "24" cache: npm - run: npm ci - run: npm run test:e2e:visual - name: Upload visual diff artifacts if: failure() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: visual-regression-diffs path: | test-results/visual playwright-report-visual if-no-files-found: ignore retention-days: 14