CI
.github/workflows/staging-orchestrator.yml runs on PRs to main and manual dispatch. It calls scripts/orchestrator/detect-affected.mjs --pr and map-affected-to-workflows.mjs, using the target mapping under scripts/orchestrator, to select reusable jobs.
| Selected surface | Reusable workflow |
|---|---|
| Next.js apps | staging-w-app-nextjs.yml, matrix of affected targets and local / vercel deployment targets |
| Web Docs | staging-w-tool-web-docs-client.yml |
| Storybook | staging-w-tool-storybook.yml |
The orchestrator also runs all-monorepo validation independently of affected target selection. ci-setup-node installs the pnpm version from root package.json, installs the exact Node release from .nvmrc, restores caches and uses pnpm install --frozen-lockfile. The root engines.node range declares Node 24 as the supported major but does not replace that exact CI pin. No workflow declares a separate Node version. ci-validate-all-monorepo and ci-validate-monorepo-package centralize validation. Testing owns the test strategy.
GitHub-hosted runner baseline
Kartuli-owned Ubuntu jobs use the explicit GitHub-hosted runner label ubuntu-26.04. Do not replace it with ubuntu-latest: that alias moves between Ubuntu releases and can change the CI environment without a repository review. The versioned label deliberately selects the supported OS line, not a particular weekly runner-image build. The exact application runtime remains Node 24.13.1 from .nvmrc, installed by ci-setup-node; the Node release preinstalled on the image is not the repository runtime contract.
The workflow inventory is grouped by the compatibility surface each job exercises:
| Surface | Owning workflows and jobs | Runner-sensitive behavior |
|---|---|---|
| Lightweight GitHub automation | labels-*.yml, notification-pr.yml, both notification-ci-failure.yml jobs | JavaScript Actions plus Bash, curl and jq |
| Detection and monorepo validation | staging-orchestrator.yml detect-affected and validate-all-monorepo | Checkout/history, Node/pnpm/Turbo setup, caches, frozen install, full validation and Storybook Chromium tests |
| Next.js staging | staging-w-app-nextjs.yml | Game Client and Backoffice validation/build, local servers, Vercel preview action, Lighthouse and Playwright |
| Storybook staging | staging-w-tool-storybook.yml | Chromium setup before browser-mode Vitest, static build, preview and Playwright E2E |
| Web Docs staging | staging-w-tool-web-docs-client.yml | Documentation validation, VitePress build/preview and Playwright E2E |
| Application production | production-w-app-game-client.yml, production-w-app-backoffice-client.yml | Core package validation, Vercel deploy, Playwright smoke and notification; separate informational Lighthouse job |
| Web Docs production | production-w-tool-web-docs-client.yml build and deploy | VitePress build, Pages artifact/deploy actions, propagation polling and deployed Playwright smoke |
The commented diagram-commit job in staging-orchestrator.yml is not active CI. If it is restored, it must retain its explicit Graphviz installation before pnpm run diagrams:all; dot is a system dependency and is not implied by the runner label.
Treat an Ubuntu-version change as a CI migration. Confirm the candidate is a supported GitHub-hosted image, update the real workflows rather than adding a permanent duplicate compatibility workflow, and exercise the shared setup plus pnpm run validate:all. Also run both Next.js builds and local E2E, Storybook browser tests/build/preview E2E, Web Docs build/preview E2E, Lighthouse and the documented Graphviz path. Use branch workflow runs to cover checkout/cache Actions and available Vercel preview paths. If a concrete incompatibility requires staying on the previous image, keep that image explicit, record the failing command/run and track the upgrade separately.
Pull-request execution flow
detect-affectedchecks out full history, installs dependencies and asks Turbo for affectedbuildtasks against a freshly fetchedorigin/main.- The mapper reads a JSON array on stdin and maps full workspace names through
workflow-targets.json. It writes Next.js, Web Docs and Storybook matrices plus a job summary. - Each nonempty bucket calls its reusable workflow. Next.js targets run both a local-build/server path and a Vercel-preview path; each runs informational Lighthouse reporting and its target Playwright suite. Game Client audits
/en/explore/alphabet; Backoffice audits/en. Lighthouse updates the existing per-target PR comment but does not write a staging Actions summary or block E2E. validate-all-monoreporuns regardless of the affected buckets. It validates documentation and navigation through the Web Docs workspace test, executes root lint, installs Chromium, then runs typecheck, workspace lint, V8 coverage and Storybook browser tests in parallel. It does not call Turbotest:all; Web Docs tests are invoked explicitly before the parallel tasks.
The package-level validation action runs only on manual dispatch inside the reusable staging workflows; normal orchestrated PR runs rely on the independent all-monorepo job plus each target's build/E2E path. Manual Next.js dispatches can optionally receive a PR number to exercise the same stable per-target comment updater when the affected-workspace graph does not select that app. The Web Docs build also runs source validation and navigation tests before rendering, then checks the built index. Its Playwright suite checks rendered delivery separately.
Reproducing affected selection
From the repository root with network access to refresh origin/main:
pnpm run orchestrator:detect-affected:pr
pnpm run orchestrator:detect-affected:pr | \
node scripts/orchestrator/map-affected-to-workflows.mjsThe first command prints a JSON array of workspaces with a real build task in Turbo's affected graph. The second prints the mapped object. The mapper accepts no command-line arguments and loads only its colocated workflow-targets.json. An affected workspace can be valid yet unmapped; inspect the unmapped result before assuming a missing job is a Turbo failure.
Failure diagnosis
Start with the first failing job/step and determine whether it is detection, setup/install, static validation, build/server readiness, deployment, Lighthouse reporting or Playwright. A later artifact/comment can exist even when another parallel task failed. A failed informational Lighthouse step should leave a readable failure state and .lighthouseci/ diagnostics while E2E continues. For cache-related surprises, inspect the Turbo dry run and task inputs; for a missing target job, inspect workspace scripts/dependency edges and the mapper config.
CI uses Node 24.13.1 from .nvmrc, pnpm 10.30.2 from root packageManager and the frozen lockfile. Reproduce with those versions before changing code to accommodate a different local runtime. Browser or DNS failures are environment failures until a code/config cause is demonstrated. See Node.js and pnpm for the distinction between the exact tested release and the supported Node 24 major.
Concurrency cancels earlier runs for the same PR. The automatic diagram commit job is commented out. App staging jobs can post preview comments and send notifications; workflows explicitly scope permissions.
External Actions are supply-chain dependencies and follow the immutable-reference policy in GitHub. Local composite Actions and reusable workflows use repository-relative paths instead.
This page records current YAML behavior. Branch-required checks, app installation permissions and GitHub environment approvals require manual verification. Production uses explicit app path filters documented in Deployment, not this staging affected-workspace selection; production workflow deduplication remains a separate concern.