feat(ci): no-growth gates for legacy public surfaces (SD-3176)#3357
Merged
Conversation
Phase 1 of SD-3175. Freeze the legacy public compatibility surface while the path-as-contract facade is built. Pure additive CI; no runtime, package, or types change. Two snapshot scripts under tests/consumer-typecheck/: - snapshot-super-editor-package-exports.mjs reads packages/super-editor/package.json#exports keys (21 today) and locks them. New subpath in the exports map fails CI. - snapshot-superdoc-legacy-exports.mjs runs against the packed-and- installed fixture and enumerates resolved named exports through the four legacy superdoc subpaths via the TypeScript compiler API (resolves `export *` chains). Locks 203 names for super-editor + 1 each for converter / docx-zipper / file-zipper. When an entry has both types.import and types.require, both .d.ts and .d.cts must enumerate the same names (guards against ensure-types.cjs regressing the CJS shim). Snapshots in tests/consumer-typecheck/snapshots/ plus a README that documents when to regenerate vs reject, and explicitly notes the gate's known limit: it does not enumerate files reachable through existing wildcard export-map keys (./* etc.), since wildcard removal belongs to a later phase of SD-3175. CI step "Legacy public no-growth gates (SD-3176)" wired into ci-superdoc, release-superdoc, and release-stable, placed after the matrix step so the fixture is fresh. Empirically verified: - both gates pass clean (exit 0) - adding a fake export-map key fails Snapshot A (exit 1) - adding a fake resolved export fails Snapshot B (exit 1) - diverging the .d.cts from .d.ts fails the parity check (exit 1)
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase 1 of SD-3175. Freeze the legacy public compatibility surface while the path-as-contract facade is being built.
Pure additive CI. No runtime, package, or types change. Customers' imports today work identically tomorrow.
What the gates lock
Two snapshot scripts under
tests/consumer-typecheck/:snapshot-super-editor-package-exports.mjsreadspackages/super-editor/package.json#exportskeys (21 today) and locks them. New subpath in the exports map fails CI.snapshot-superdoc-legacy-exports.mjsruns against the packed-and-installed fixture. Uses the TypeScript compiler API to enumerate resolved named exports through the four legacysuperdoc/*subpaths (resolvesexport *chains). Locks 203 names forsuperdoc/super-editor+ 1 each forsuperdoc/converter/superdoc/docx-zipper/superdoc/file-zipper. When an entry advertises bothtypes.importandtypes.require, both declaration files must enumerate the same names (guards againstensure-types.cjsregressing the CJS shim).CI step
Legacy public no-growth gates (SD-3176)wired into PR CI plus both release lanes, placed after the matrix step so the fixture is fresh.When the gate fails
Default response: reject the change. These paths are legacy compatibility surface per
docs/architecture/package-boundaries.mdDecision 1; they are not supposed to grow. Thetests/consumer-typecheck/snapshots/README.mddocuments when regeneration is justified (rare; requires linking the PR to SD-3175 or a child for reviewer sign-off).Known limit (called out in the README)
This phase does not enumerate every file reachable through existing wildcard export-map keys (e.g.
"./*","./converter/internal/*"). Snapshot A locks the key set; Snapshot B locks the resolvedsuperdoc/super-editornamed export surface. A new file added under an existing wildcard that a consumer reaches via deep import (@superdoc/super-editor/something-new) passes both gates. Wildcard removal or shrinkage belongs to the later compat/major phases of SD-3175.Verified
./fake-test-entryexport-map key (exit 1)superdoc/super-editor(exit 1)super-editor.d.ctsonly (exit 1)Related