Skip to content
Guides and policiesView source on GitHub ↗

Continuous integration

Forge separates repository quality, workflow validation, and security analysis so each required result has one stable purpose.

Required checks

Repository rulesets should require these check names on main:

  • Project — aggregate repository, package, template, and generator quality;
  • CodeQL — aggregate JavaScript/TypeScript and GitHub Actions analysis.

Project runs on every pull request. Individual jobs remain visible for diagnosis, but only the aggregate needs to be named in branch protection. If a job is added to or removed from a required workflow, update its aggregate needs list in the same pull request.

Change routing

The Classify changes job compares the complete pull-request or push range and emits only reviewed boolean outputs. Changed filenames are passed to the typed classifier as NUL-delimited data; filenames never become workflow commands or shell expressions. The classifier selects these job groups:

Change classSelected validation
Documentation onlyFormat, Markdown lint, spelling, and documentation links and commands
Content modelRepository/package checks and supported-runtime compatibility
Create ForgeRepository/package checks, compatibility, and packed generator end-to-end
Default templatePackage build/pack, every template check, and packed generator end-to-end
Project websiteWebsite static, runtime, coverage/build, browser, and Lighthouse checks
Area dependencyThe affected area above plus dependency auditing
Shared or ambiguousEvery repository, package, template, website, compatibility, and generator check

Documentation inside the bundled default template follows the template route, because it becomes part of generated projects. Root manifests and lockfiles, .github/**, shared scripts/**, root tooling, mixed unclassified paths, and an empty or unavailable comparison deliberately select the full suite. A newly introduced path is therefore expensive until its ownership is reviewed and added to the classifier. Security analysis remains independent and broad. Website manifests and lockfiles stay on the website route because its static job applies the standalone audit policy; they do not also run the root workspace audit. Package-only changes do not select website browser or Lighthouse work.

Every job remains in the Project aggregate’s needs graph. The aggregate uses always() so jobs intentionally skipped by routing cannot leave the required check pending. It accepts only success and skipped; any selected failure or cancellation fails Project. The build retains its static-check dependency and runs only when package work is selected and every prerequisite succeeded or was intentionally skipped.

For a documentation-only pull request, expect Classify changes, Format, Lint Markdown, Spellcheck, Documentation links and commands, and Project to run. Package, compatibility, template, browser, Lighthouse, and generator jobs should appear as skipped. This provides a quick review checklist for the lightweight route without weakening the required aggregate.

Automation aggregates workflow syntax and workflow-security validation, but it runs only when workflow files change. Do not configure it as a globally required status check: unrelated pull requests would wait for a path-filtered workflow that never started. Treat it as a conditional review signal for automation changes. The repository workflow watches both .github/** and the generated template’s workflow source under templates/default/.github/**.

The generated template uses the same Project and conditional Automation results. Generated repositories should require Project and CodeQL after enabling GitHub Actions, while reviewing Automation whenever it appears.

Runtime and evidence strategy

The minimum Node 22 release and the latest Node 22, 24, and 26 releases each run package type checks, tests, and builds. The standalone template uses the same matrix, with one clean install per runtime. The project website is a deployed application rather than a published compatibility surface, so it installs from website/package-lock.json and runs its types, unit tests, build, and generated-output validation once on the primary Node 26 runtime. The packed generator compatibility suite runs on the four supported Linux runtimes and on the current macOS runner with Node 26. Each lane records its operating system, architecture, Node, npm, and Git versions before exercising the installed generator executable.

Formatting, Markdown, spelling, package inspection, coverage, Lighthouse, isolation, and the complete generated-project acceptance suite run once on the primary Node 26 runtime because repeating them does not add compatibility evidence. The blocking Playwright suite runs once in each of Chromium, Firefox, and WebKit using the browser revisions associated with the committed Playwright version.

The Project aggregate depends on all required jobs. A failure retains its specific job name while preventing the aggregate from succeeding. Its log also records the classifier’s selected groups so unexpected routing can be audited without opening every skipped job.

Coverage and Lighthouse uploads run even when their producer fails and treat a missing report directory as an error. Lighthouse uploads explicitly include the hidden .lighthouseci directory. Browser evidence is uploaded on failure, when Playwright retains its report and trace directories. Artifacts are retained for seven days.

Dependency audits

The root Dependency audit job applies audit-ci.jsonc to the root lockfile and npm workspaces. The standalone template owns a separate lockfile and templates/default/audit-ci.jsonc, so its static-quality job enforces that policy independently.

Both policies reject high and critical vulnerabilities. An exception must name the exact GitHub Security Advisory ID, explain why the affected path is safe for Forge’s use, include an expiry date, and link upstream tracking when available. Do not allowlist package names or severity classes. Expired entries must be removed or re-evaluated in a dedicated pull request.

Run the repository audit locally with:

npm run audit

Run the template policy from templates/default with the same command. Run the website policy from the repository root with npm run website:quality:static, or use npm run website:quality for its complete standalone gate. Dependabot treats /website as an independent npm ecosystem and submits reviewable lockfile updates without regenerating owned website source.

Negative verification

When changing aggregate or artifact behavior, use a temporary review branch to prove the failure path. An intentionally invalid workflow must make Automation fail. A Lighthouse run that omits .lighthouseci must make its upload contract fail. Remove the deliberate defect before merging and link both workflow runs in the tracking issue.