Skip to content

Add @rushstack/heft-zod-schema-plugin and pilot it on rush-lib's experiments.json#5788

Draft
Copilot wants to merge 5 commits intomainfrom
copilot/replace-json-schema-with-zod
Draft

Add @rushstack/heft-zod-schema-plugin and pilot it on rush-lib's experiments.json#5788
Copilot wants to merge 5 commits intomainfrom
copilot/replace-json-schema-with-zod

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 19, 2026

Pivot the original experiments.json pilot into a dedicated home, @rushstack/rush-schemas, that owns the zod source-of-truth for Rush configuration schemas and emits both the runtime validators and the *.schema.json artifacts via @rushstack/heft-zod-schema-plugin.

Scope

  • Scaffold libraries/rush-schemas (package.json / Heft / rig / eslint / tsconfig); register in rush.json
  • Wire @rushstack/heft-zod-schema-plugin into the new project's heft.json
  • Move experiments.zod.ts from rush-lib to rush-schemas; rush-lib re-exports IExperimentsJson
  • Drop the rush-lib pilot wiring (zod-schemas task in libraries/rush-lib/config/heft.json); rush-lib returns to a vanilla TS+lint pipeline
  • Port cobuild.zod.ts (small required-fields case; z.infer for @beta interface)
  • Port repo-state.zod.ts (small internal state-file case; z.infer for @internal interface)
  • Port build-cache.zod.ts (discriminated-union case; surfaces pitfalls of provider-specific oneOf schemas)
  • Document per-schema decisions in libraries/rush-schemas/README.md
  • Build + test: rush build --to @rushstack/rush-schemas, rush build --to @microsoft/rush-lib, rush-lib tests (627/627 passing), heft-zod-schema-plugin tests (9/9 passing)
  • parallel_validation (Code Review feedback addressed; CodeQL timed out)

Per-schema authoring decisions

Schema Strategy Why
experiments Hand-authored interface + bidirectional drift assertion Public @beta API; per-property TSDoc must be preserved verbatim
cobuild Omit<z.infer<typeof cobuildSchema>, '$schema'> Public @beta but tiny; collapsing to z.infer keeps a single source of truth
repo-state Omit<z.infer<typeof repoStateSchema>, '$schema'> @internal state file; z.infer is the pragmatic choice
build-cache No type alias, no drift check Schema's discriminated unions describe runtime extension points, not the TS shape

Notable trade-offs surfaced by the four ports

  1. experiments — the consolidation made several pre-existing inconsistencies between the schema descriptions and the interface TSDoc visible side-by-side; harmonized them in this PR.
  2. build-cache — the JSON Schema is more restrictive than the runtime TypeScript shape by design (cloud cache providers extend the config object at runtime via plugins). Validators and types are not reconcilable structurally; this is the central pitfall of porting oneOf-style schemas, and the schemas package has to acknowledge it rather than try to pretend otherwise.
  3. API reportcommon/reviews/api/rush-lib.api.md now records IExperimentsJson as a re-export rather than an inline declaration. The interface structure is unchanged for downstream consumers; this is the documented trade-off of moving the type into a separate package.

Out of scope

  • Migrating runtime validation in rush-lib to consume the generated *.schema.json artifacts. The legacy hand-authored ones in libraries/rush-lib/src/schemas/ remain authoritative; the new package's output is for review/diff during this pilot.
  • Porting the remaining ~15 rush-lib schemas. The four ports here are intentionally chosen for structural diversity (flat boolean flags / required strings / internal state / discriminated oneOf) before committing the whole repo to a pattern.
  • custom-tips.schema.json (already generated from a TS source-of-truth) and change-file.schema.json / changelog.schema.json (also consumed by @microsoft/rush and external changelog tooling).

Copilot AI and others added 2 commits April 19, 2026 03:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Needs triage

Development

Successfully merging this pull request may close these issues.

2 participants