# Per ADR-0028 (CI/CD migration from Gitea Actions to GitLab CE).
# Thin YAML — orchestration lives in package.json scripts (ci:check,
# ci:catalogue-drift, ci:audit, ci:commits, ci:perf, ci:gzip-budgets)
# and Nx targets. Any change to gate behaviour belongs in those
# scripts, not in this file — see ADR-0015 §"Thin pipeline YAML…"
# (principle preserved by ADR-0028 at the migration boundary).
#
# Phase 2 of ADR-0028: ships alongside .gitea/workflows/ci.yml. Both
# pipelines must remain in parity until cutover (Phase 3), at which
# point the Gitea workflow gets deleted.

include:
  # GitLab built-in scanners — replace the manual Trivy + gitleaks
  # install in .gitea/workflows/ci.yml. Both add their own jobs to
  # the pipeline; their default stage is `test`, which is mapped in
  # `stages:` below.
  - template: Jobs/SAST.gitlab-ci.yml
  - template: Jobs/Secret-Detection.gitlab-ci.yml

stages:
  - check
  - test
  - commits
  - perf
  - a11y

workflow:
  rules:
    # MR pipelines — covers GitLab MR review flow once it lands.
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    # Direct pushes — covers post-merge runs on main today, and Phase 2
    # parity testing on feature branches mirrored from Gitea. To be
    # tightened to `$CI_COMMIT_BRANCH == "main"` at the Phase 3 cutover
    # once GitLab is the source of truth.
    - if: $CI_PIPELINE_SOURCE == "push"

# Shared shape for jobs that need Node + pnpm. Hidden (`.` prefix) so
# GitLab does not try to execute it. Inheriting jobs `extends: .node-job`.
.node-job:
  image: node:24-bookworm
  cache:
    key:
      files:
        - pnpm-lock.yaml
    paths:
      - .pnpm-store/
  before_script:
    - corepack enable
    - corepack prepare pnpm@10.33.4 --activate
    - pnpm config set store-dir "$CI_PROJECT_DIR/.pnpm-store"

check:
  extends: .node-job
  stage: check
  # `nx affected` needs a base SHA to diff against. Mirrors the
  # equivalent step in .gitea/workflows/ci.yml — same logic, GitLab
  # variable names. Replaces nrwl/nx-set-shas (GitHub-only).
  script:
    - |
      if [ "$CI_PIPELINE_SOURCE" = "merge_request_event" ]; then
        git fetch origin "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" --depth=100
        export NX_BASE=$(git merge-base HEAD "origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME")
      else
        export NX_BASE="HEAD~1"
      fi
      export NX_HEAD="HEAD"
    - pnpm install --frozen-lockfile
    - pnpm ci:check
    # Catalogue-vs-code drift gate per ADR-0025 §"Confirmation". The
    # script's own unit tests run first — if they fail the gate itself
    # is broken and the actual catalogue check would be noise.
    - pnpm ci:catalogue-drift:test
    - pnpm ci:catalogue-drift

audit:
  extends: .node-job
  stage: test
  # npm-advisory check against pnpm-lock.yaml. Trivy's dependency-vuln
  # role from the Gitea workflow is now covered by the SAST include
  # (which includes Dependency Scanning analyzers); `pnpm audit` stays
  # in-pipeline as defense in depth against the npm advisory DB
  # specifically.
  script:
    - pnpm install --frozen-lockfile
    - pnpm ci:audit

commits:
  extends: .node-job
  stage: commits
  # MRs opened by Renovate (apf-portal-bot) carry commit messages from
  # a vetted Conventional-Commits template — running commitlint on
  # them is tautological. Per ADR-0017 amendment.
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event" && $GITLAB_USER_LOGIN != "apf-portal-bot"
  variables:
    # Default `GIT_DEPTH: 20` is too shallow to diff against
    # origin/main on long-running branches. Full clone so commitlint
    # can walk all the way back.
    GIT_DEPTH: 0
  script:
    - git fetch origin main
    - pnpm install --frozen-lockfile
    - COMMIT_LINT_FROM=origin/main pnpm ci:commits

perf:
  extends: .node-job
  stage: perf
  # Lighthouse CI drives a real Chrome instance. Playwright's image is
  # the canonical "Node + browsers" CI image and is already on our
  # roadmap for the ADR-0016 axe-core e2e — single image covers both
  # uses once the a11y suite lands.
  image: mcr.microsoft.com/playwright:v1.55.0-jammy
  # Skip on Renovate MRs (same rationale as commits + the perf signal
  # on a dep bump is essentially zero). Push events on `main` still
  # run perf — we catch regressions immediately post-merge, not
  # pre-merge. Per ADR-0017 amendment.
  rules:
    - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "main"
    - if: $CI_PIPELINE_SOURCE == "merge_request_event" && $GITLAB_USER_LOGIN != "apf-portal-bot"
  script:
    - pnpm install --frozen-lockfile
    - pnpm ci:perf
  artifacts:
    when: always
    paths:
      - .lighthouseci/
    expire_in: 30 days

a11y:
  extends: .node-job
  stage: a11y
  # Placeholder until the e2e a11y suite (axe-core via Playwright, per
  # ADR-0016) is wired with the first real screens. The job exists so
  # branch protection can require it from day one — currently no-ops
  # with a clear message.
  script:
    - echo "a11y gate placeholder - axe-core via Playwright wires up with the first real screens (ADR-0016)."

# Place SAST + Secret Detection in the `test` stage to mirror the
# Gitea workflow's grouping (where Trivy + gitleaks + audit all
# lived in the `scan` job). Override does not change behaviour —
# only stage placement. The included templates set sensible defaults
# (run on default branch + MRs, full repo on default branch / diff
# on MRs); revisited in Phase 3 if pipeline duration becomes a pain.
sast:
  stage: test

secret_detection:
  stage: test
