docs(ci): add a GitLab CI/CD page

Merged
KA
3d ago
+267-5

The docs had no GitLab page. docs/ci.mdx told GitLab users to copy the GitHub Actions workflow, and the only GitLab-specific instruction sat in one sentence of docs/filters.mdx.

  • New docs/ci/gitlab.mdx:
    • a web job that runs for merge requests and the default branch, with the browsers cached inside the project (PLAYWRIGHT_BROWSERS_PATH) and reports: junit for the merge request widget. The rules sit on the job, not in workflow:, so the same job works as .gitlab-ci.yml or as a file a pipeline includes
    • adding the job to an existing pipeline with include: - local:
    • the model key as a masked and hidden CI/CD variable, set in the UI or with glab variable set --masked --hidden --raw, with GitLab's rules on masking, protected variables, and pipelines from forks
    • the identity verification GitLab.com asks of a new account before hosted runners take its jobs
    • --changed-since in merge request pipelines, skipped in merge trains, with GIT_DEPTH: 0
    • sharding with parallel and CI_NODE_INDEX/CI_NODE_TOTAL
    • iOS and Android jobs on self-managed runners. GitLab's hosted macOS runners don't support testmanagerd, which XCUITest needs, and its hosted Linux runners don't list KVM. Each job names its device through E2E_DEVICE, so a device left over from a timed-out job on the same machine is never driven.
  • GitLab logo (docs/images/integrations/gitlab.svg, the full-color tanuki from GitLab's source, so no dark-mode invert), a card on docs/ci.mdx, and the nav entry in docs/docs.json.
  • docs/filters.mdx links to the new section instead of carrying the GitLab command.

Issue

ENG-1135

Verified

Ran it locally: yes, and on GitLab.com hosted runners for the web job.

  • The web job ran in the e2e-gitlab-ci playground (Next.js, npm, node:24). In each pipeline GitLab's test report showed 5 of 5 passed, 0 skipped, so the two agent tests ran with the masked, hidden AI_GATEWAY_API_KEY variable.

    MRSetupPipeline
    !1the job as .gitlab-ci.ymlpassed, 2m02s; passed again on main after merge
    !2an existing .gitlab-ci.yml with a build job, the e2e job in .gitlab/e2e.gitlab-ci.yml through include: - local:passed, 1m53s
    !3committed replay cacheboth agent.act steps replayed: 2 model calls instead of 7, the two agent.assert checks

    The first pipelines failed before any job started, until the account's identity was verified.

  • The web job's script in a node:26 container (Debian 13), against a copy of examples/with-vite, with PLAYWRIGHT_BROWSERS_PATH under the project:

    Chrome Headless Shell 156.0.8078.4 (playwright chromium-headless-shell v1248) downloaded to /builds/proj/.cache/ms-playwright/chromium_headless_shell-1248
       ✓  web  tests/deterministic.e2e.ts > shows the greeting form 643ms
       ✓  web  tests/deterministic.e2e.ts > asks for a name when the field is empty 160ms
       ✓  web  tests/deterministic.e2e.ts > greets the name you type 200ms
     Test Files  1 passed (1)
          JUnit  .e2e/junit.xml
    

    The first try failed with APP_UNREACHABLE: in the container Vite bound localhost to ::1 only. The page now says to make the app's command listen on 127.0.0.1.

  • The --changed-since script picks CI_MERGE_REQUEST_TARGET_BRANCH_SHA, then CI_MERGE_REQUEST_DIFF_BASE_SHA, and leaves the flag out off merge requests and in merge trains, under sh and bash. e2e list --changed-since <sha> accepts a commit hash.

  • Every YAML block on the page parses.

  • The iOS and Android jobs did not run: they need a self-managed Mac and a Linux runner with KVM.