From 5e36b547f2624c9430e80888efb470f9f5ea6c52 Mon Sep 17 00:00:00 2001 From: Caio Pizzol Date: Fri, 24 Apr 2026 15:02:18 -0300 Subject: [PATCH 1/4] ci: align release and CI triggers with package impact map Test broad, release narrow. CI gates compatibility (a core change should run dependent CI to catch breakage). Release gates artifact changes (a package should only publish when its own published artifact actually changes). - Shrink release-react, release-template-builder, release-esign and their .releaserc.cjs to own-path-only. These wrappers externalize superdoc in their Vite builds, so republishing on core changes produces near-identical tarballs; consumers pick up core via peerDependencies on their own install. - Expand release-mcp trigger paths and .releaserc.cjs to cover SDK, CLI, document-api, and core. MCP depends on SDK via workspace:* and imports engine/session code directly. Current trigger only watched apps/mcp/**, causing MCP to lag SDK releases. - Strip packages/ai/** from every workflow and .releaserc.cjs include list. @superdoc-dev/ai is being deprecated; npm-side deprecation is a separate operational step. - Add .github/package-impact-map.md as the source of truth for which paths should trigger CI and release per surface. Workflow changes derive from it. --- .github/package-impact-map.md | 64 +++++++++++++++++++ .github/workflows/ci-behavior.yml | 1 - .github/workflows/release-cli.yml | 1 - .github/workflows/release-esign.yml | 7 -- .github/workflows/release-mcp.yml | 12 ++++ .github/workflows/release-react.yml | 7 -- .github/workflows/release-sdk.yml | 1 - .github/workflows/release-superdoc.yml | 1 - .../workflows/release-template-builder.yml | 7 -- .github/workflows/release-vscode-ext.yml | 1 - .github/workflows/visual-test.yml | 1 - apps/cli/.releaserc.cjs | 1 - apps/mcp/.releaserc.cjs | 25 +++++++- apps/vscode-ext/.releaserc.cjs | 1 - packages/esign/.releaserc.cjs | 40 ++---------- packages/react/.releaserc.cjs | 40 ++---------- packages/sdk/.releaserc.cjs | 1 - packages/superdoc/.releaserc.cjs | 1 - packages/template-builder/.releaserc.cjs | 40 ++---------- 19 files changed, 121 insertions(+), 131 deletions(-) create mode 100644 .github/package-impact-map.md diff --git a/.github/package-impact-map.md b/.github/package-impact-map.md new file mode 100644 index 0000000000..500437e3ec --- /dev/null +++ b/.github/package-impact-map.md @@ -0,0 +1,64 @@ +# Package impact map + +Source of truth for which repo paths should trigger CI and release workflows for each published surface. + +## Principle + +**Test broad, release narrow.** + +- **CI gates compatibility.** A change to SuperDoc core should run the CI of every dependent package — that's how breakage in `@superdoc-dev/react` or `@superdoc-dev/sdk` gets caught before it ships. CI paths follow *compatibility* impact. +- **Release gates artifact changes.** A package should only publish a new version when its own published artifact actually changes. Release paths follow *artifact* impact. + +These two are not the same. React externalizes `superdoc` in its build, so a core change doesn't change the react tarball → CI broad, release narrow. CLI bundles core into platform binaries, so a core change does change the CLI tarball → both broad. + +## Surfaces + +| Surface | Purpose | Release impact | CI impact | +|---|---|---|---| +| `superdoc` | Main browser DOCX editor/runtime | core | core | +| `@superdoc-dev/react` | React wrapper around superdoc | `packages/react/**` only | react + core | +| `@superdoc-dev/template-builder` | React SDT/template authoring UI | `packages/template-builder/**` only | template-builder + core | +| `@superdoc-dev/esign` | React signing workflow | `packages/esign/**` only | esign + core | +| `@superdoc-dev/cli` | Native Document API CLI | cli + doc-api + core | same | +| `@superdoc-dev/sdk` | JS/Python SDK packaging CLI binaries | sdk + cli + doc-api + core | same | +| `@superdoc-dev/mcp` | MCP server over SDK/document engine | mcp + sdk + cli + doc-api + core | same | +| `superdoc-vscode-ext` | VS Code DOCX editor | vscode-ext + core | same | +| `@superdoc-dev/create` | Project scaffolder | `apps/create/**` only | own changes only | +| `@superdoc-dev/superdoc-yjs-collaboration` | Standalone Yjs server (no SuperDoc dep) | `packages/collaboration-yjs/**` only | own changes + collaboration examples | +| `@superdoc/docs` (private) | Documentation site | N/A (not published) | docs + public API / doc generation | +| demos, examples (private) | Compatibility samples | N/A (not published) | own paths + relevant upstream runtime | + +## Path expansions + +**core** expands to: +- `packages/superdoc/**` +- `packages/super-editor/**` +- `packages/layout-engine/**` +- `packages/word-layout/**` +- `packages/preset-geometry/**` +- `shared/**` +- `pnpm-workspace.yaml` + +**doc-api** is `packages/document-api/**`. + +**cli** is `apps/cli/**`. + +**sdk** is `packages/sdk/**`. + +**mcp**, **vscode-ext**, **create** are their respective `apps/*/**` or `packages/*/**` paths. + +## Why each classification + +- **React wrappers (`react`, `template-builder`, `esign`)** externalize `superdoc` in their Vite build (`rollupOptions.external`). A SuperDoc core change does not change the wrapper's published bundle — consumers receive the new core through their own `npm install` via `peerDependencies`. Release-on-core is pure version noise; CI-on-core remains necessary to catch breaking API changes. +- **CLI / SDK** bundle engine behavior into platform-specific native binaries (see `apps/cli/.releaserc.cjs` and `packages/sdk/.releaserc.cjs` — both use `patch-commit-filter.cjs` to expand release analysis into core paths). The published artifact genuinely changes when core changes. +- **MCP** depends on SDK via `workspace:*` and imports engine/session code directly. Its current release trigger (`apps/mcp/**` only) causes it to lag SDK releases. Expand to match SDK's release paths. +- **VS Code extension** packages SuperDoc into the extension VSIX. Treated like CLI/SDK. +- **collaboration-yjs** has no SuperDoc dependency. It's a standalone Yjs server. Release and CI both narrow. +- **create** is a scaffolder with no dependencies on SuperDoc runtime. Release and CI both narrow. +- **docs, demos, examples** are not published. They get CI on changes to anything they render to catch visual or behavior regressions. + +## Notes + +- `packages/ai/**` has been removed from all release and CI triggers. `@superdoc-dev/ai` is being deprecated; npm-side deprecation is a separate operational step. +- When SuperDoc core ships a breaking API change, React wrappers (`react`, `template-builder`, `esign`) must be manually updated and released. Their `peerDependencies` version bump is the signal; semantic-release won't auto-trigger on upstream changes. +- When editing a release or CI workflow, its `paths:` filter must match the corresponding row in this map. Workflow-lint rules should enforce this. diff --git a/.github/workflows/ci-behavior.yml b/.github/workflows/ci-behavior.yml index a631113816..eebcd81c08 100644 --- a/.github/workflows/ci-behavior.yml +++ b/.github/workflows/ci-behavior.yml @@ -10,7 +10,6 @@ on: - 'packages/superdoc/**' - 'packages/layout-engine/**' - 'packages/super-editor/**' - - 'packages/ai/**' - 'packages/word-layout/**' - 'packages/preset-geometry/**' - 'tests/behavior/**' diff --git a/.github/workflows/release-cli.yml b/.github/workflows/release-cli.yml index 7e59bd1144..c8a6afd527 100644 --- a/.github/workflows/release-cli.yml +++ b/.github/workflows/release-cli.yml @@ -14,7 +14,6 @@ on: - 'packages/superdoc/**' - 'packages/super-editor/**' - 'packages/layout-engine/**' - - 'packages/ai/**' - 'packages/word-layout/**' - 'packages/preset-geometry/**' - 'shared/**' diff --git a/.github/workflows/release-esign.yml b/.github/workflows/release-esign.yml index 8431abc0ae..62ab1dceed 100644 --- a/.github/workflows/release-esign.yml +++ b/.github/workflows/release-esign.yml @@ -8,13 +8,6 @@ on: - main paths: - 'packages/esign/**' - - 'packages/superdoc/**' - - 'packages/layout-engine/**' - - 'packages/super-editor/**' - - 'packages/ai/**' - - 'packages/word-layout/**' - - 'packages/preset-geometry/**' - - 'shared/**' - 'pnpm-workspace.yaml' - '!**/*.md' workflow_dispatch: diff --git a/.github/workflows/release-mcp.yml b/.github/workflows/release-mcp.yml index a8f5f281e7..e6b1c79459 100644 --- a/.github/workflows/release-mcp.yml +++ b/.github/workflows/release-mcp.yml @@ -7,7 +7,19 @@ on: branches: - main paths: + # MCP depends on SDK (workspace:*) and imports engine/session code directly. + # Keep in sync with apps/mcp/.releaserc.cjs include list and + # .github/package-impact-map.md. - 'apps/mcp/**' + - 'packages/sdk/**' + - 'apps/cli/**' + - 'packages/document-api/**' + - 'packages/superdoc/**' + - 'packages/super-editor/**' + - 'packages/layout-engine/**' + - 'packages/word-layout/**' + - 'packages/preset-geometry/**' + - 'shared/**' - 'pnpm-workspace.yaml' - '!**/*.md' workflow_dispatch: diff --git a/.github/workflows/release-react.yml b/.github/workflows/release-react.yml index 30bedd8fdf..7ddd304f8e 100644 --- a/.github/workflows/release-react.yml +++ b/.github/workflows/release-react.yml @@ -8,13 +8,6 @@ on: - main paths: - 'packages/react/**' - - 'packages/superdoc/**' - - 'packages/layout-engine/**' - - 'packages/super-editor/**' - - 'packages/ai/**' - - 'packages/word-layout/**' - - 'packages/preset-geometry/**' - - 'shared/**' - 'pnpm-workspace.yaml' - '!**/*.md' workflow_dispatch: diff --git a/.github/workflows/release-sdk.yml b/.github/workflows/release-sdk.yml index 103bf688de..119b7fda5f 100644 --- a/.github/workflows/release-sdk.yml +++ b/.github/workflows/release-sdk.yml @@ -15,7 +15,6 @@ on: - 'packages/superdoc/**' - 'packages/super-editor/**' - 'packages/layout-engine/**' - - 'packages/ai/**' - 'packages/word-layout/**' - 'packages/preset-geometry/**' - 'shared/**' diff --git a/.github/workflows/release-superdoc.yml b/.github/workflows/release-superdoc.yml index c3f781da39..9ba85fbaa9 100644 --- a/.github/workflows/release-superdoc.yml +++ b/.github/workflows/release-superdoc.yml @@ -11,7 +11,6 @@ on: - 'packages/superdoc/**' - 'packages/layout-engine/**' - 'packages/super-editor/**' - - 'packages/ai/**' - 'packages/word-layout/**' - 'packages/preset-geometry/**' - 'shared/**' diff --git a/.github/workflows/release-template-builder.yml b/.github/workflows/release-template-builder.yml index a4d4561ca7..0f95aa59ee 100644 --- a/.github/workflows/release-template-builder.yml +++ b/.github/workflows/release-template-builder.yml @@ -8,13 +8,6 @@ on: - main paths: - 'packages/template-builder/**' - - 'packages/superdoc/**' - - 'packages/layout-engine/**' - - 'packages/super-editor/**' - - 'packages/ai/**' - - 'packages/word-layout/**' - - 'packages/preset-geometry/**' - - 'shared/**' - 'pnpm-workspace.yaml' - '!**/*.md' workflow_dispatch: diff --git a/.github/workflows/release-vscode-ext.yml b/.github/workflows/release-vscode-ext.yml index 6e8baecaaa..8a149188ab 100644 --- a/.github/workflows/release-vscode-ext.yml +++ b/.github/workflows/release-vscode-ext.yml @@ -11,7 +11,6 @@ on: - 'packages/superdoc/**' - 'packages/layout-engine/**' - 'packages/super-editor/**' - - 'packages/ai/**' - 'packages/word-layout/**' - 'packages/preset-geometry/**' - 'shared/**' diff --git a/.github/workflows/visual-test.yml b/.github/workflows/visual-test.yml index 09c5378af6..bfe2a60a8e 100644 --- a/.github/workflows/visual-test.yml +++ b/.github/workflows/visual-test.yml @@ -11,7 +11,6 @@ on: - 'packages/superdoc/**' - 'packages/layout-engine/**' - 'packages/super-editor/**' - - 'packages/ai/**' - 'packages/word-layout/**' - 'packages/preset-geometry/**' - 'tests/visual/**' diff --git a/apps/cli/.releaserc.cjs b/apps/cli/.releaserc.cjs index 950fe38849..ca0b8e3cd2 100644 --- a/apps/cli/.releaserc.cjs +++ b/apps/cli/.releaserc.cjs @@ -13,7 +13,6 @@ require('../../scripts/semantic-release/patch-commit-filter.cjs')([ 'packages/superdoc', 'packages/super-editor', 'packages/layout-engine', - 'packages/ai', 'packages/word-layout', 'packages/preset-geometry', 'shared', diff --git a/apps/mcp/.releaserc.cjs b/apps/mcp/.releaserc.cjs index 5fd7f91913..a7d22596d6 100644 --- a/apps/mcp/.releaserc.cjs +++ b/apps/mcp/.releaserc.cjs @@ -1,4 +1,28 @@ /* eslint-env node */ +/* + * Commit filter: MCP depends on SDK (workspace:*) and imports engine/session + * code directly. Git log must include commits touching those paths so MCP + * picks up SDK/core fixes. This shared helper patches git-log-parser to + * expand path coverage. It REPLACES semantic-release-commit-filter — do not + * use both (the filter restricts to CWD, which undoes the expansion). + * + * Keep in sync with .github/workflows/release-mcp.yml paths and + * .github/package-impact-map.md. + */ +require('../../scripts/semantic-release/patch-commit-filter.cjs')([ + 'apps/mcp', + 'packages/sdk', + 'apps/cli', + 'packages/document-api', + 'packages/superdoc', + 'packages/super-editor', + 'packages/layout-engine', + 'packages/word-layout', + 'packages/preset-geometry', + 'shared', + 'pnpm-workspace.yaml', +]); + const branch = process.env.GITHUB_REF_NAME || process.env.CI_COMMIT_BRANCH; const branches = [ @@ -17,7 +41,6 @@ const config = { branches, tagFormat: 'mcp-v${version}', plugins: [ - 'semantic-release-commit-filter', '@semantic-release/commit-analyzer', notesPlugin, ['@semantic-release/npm'], diff --git a/apps/vscode-ext/.releaserc.cjs b/apps/vscode-ext/.releaserc.cjs index 214a88ceae..971762aea1 100644 --- a/apps/vscode-ext/.releaserc.cjs +++ b/apps/vscode-ext/.releaserc.cjs @@ -13,7 +13,6 @@ require('../../scripts/semantic-release/patch-commit-filter.cjs')([ 'packages/superdoc', 'packages/super-editor', 'packages/layout-engine', - 'packages/ai', 'packages/word-layout', 'packages/preset-geometry', 'shared', diff --git a/packages/esign/.releaserc.cjs b/packages/esign/.releaserc.cjs index f4a177a602..0f314e7cd9 100644 --- a/packages/esign/.releaserc.cjs +++ b/packages/esign/.releaserc.cjs @@ -1,24 +1,11 @@ /* eslint-env node */ /* - * Commit filter: esign depends on superdoc, so git log must include - * commits touching superdoc's sub-packages. This shared helper patches - * git-log-parser to expand path coverage. It REPLACES - * semantic-release-commit-filter — do not use both (the filter restricts - * to CWD, which undoes the expansion). - * - * Keep in sync with .github/workflows/release-esign.yml paths: trigger. + * Release narrow: esign externalizes `superdoc` in its build, so a core + * change does not alter the published esign tarball (consumers get the new + * core via their own peerDependencies install). Only commits touching + * packages/esign/** should trigger a release. See + * .github/package-impact-map.md. */ -require('../../scripts/semantic-release/patch-commit-filter.cjs')([ - 'packages/esign', - 'packages/superdoc', - 'packages/super-editor', - 'packages/layout-engine', - 'packages/ai', - 'packages/word-layout', - 'packages/preset-geometry', - 'shared', - 'pnpm-workspace.yaml', -]); const branch = process.env.GITHUB_REF_NAME || process.env.CI_COMMIT_BRANCH; @@ -40,21 +27,8 @@ const config = { branches, tagFormat: 'esign-v${version}', plugins: [ - [ - '@semantic-release/commit-analyzer', - { - // Cap at minor — esign depends on superdoc, so upstream breaking - // changes don't break esign's own public API. - // Prevents accidental major bumps from superdoc feat!/BREAKING CHANGE commits. - releaseRules: [ - { breaking: true, release: 'minor' }, - { type: 'feat', release: 'minor' }, - { type: 'fix', release: 'patch' }, - { type: 'perf', release: 'patch' }, - { type: 'revert', release: 'patch' }, - ], - }, - ], + 'semantic-release-commit-filter', + '@semantic-release/commit-analyzer', notesPlugin, ['@semantic-release/npm', { npmPublish: true }], ], diff --git a/packages/react/.releaserc.cjs b/packages/react/.releaserc.cjs index 2a427aab25..11be8b01a1 100644 --- a/packages/react/.releaserc.cjs +++ b/packages/react/.releaserc.cjs @@ -1,24 +1,11 @@ /* eslint-env node */ /* - * Commit filter: react wraps superdoc, so git log must include - * commits touching superdoc's sub-packages. This shared helper patches - * git-log-parser to expand path coverage. It REPLACES - * semantic-release-commit-filter — do not use both (the filter restricts - * to CWD, which undoes the expansion). - * - * Keep in sync with .github/workflows/release-react.yml paths: trigger. + * Release narrow: react externalizes `superdoc` in its build, so a core + * change does not alter the published react tarball (consumers get the new + * core via their own peerDependencies install). Only commits touching + * packages/react/** should trigger a react release. See + * .github/package-impact-map.md. */ -require('../../scripts/semantic-release/patch-commit-filter.cjs')([ - 'packages/react', - 'packages/superdoc', - 'packages/super-editor', - 'packages/layout-engine', - 'packages/ai', - 'packages/word-layout', - 'packages/preset-geometry', - 'shared', - 'pnpm-workspace.yaml', -]); const branch = process.env.GITHUB_REF_NAME || process.env.CI_COMMIT_BRANCH; @@ -40,21 +27,8 @@ const config = { branches, tagFormat: 'react-v${version}', plugins: [ - [ - '@semantic-release/commit-analyzer', - { - // Cap at minor — react wraps superdoc, so upstream breaking - // changes don't break react's own public API. - // Prevents accidental major bumps from superdoc feat!/BREAKING CHANGE commits. - releaseRules: [ - { breaking: true, release: 'minor' }, - { type: 'feat', release: 'minor' }, - { type: 'fix', release: 'patch' }, - { type: 'perf', release: 'patch' }, - { type: 'revert', release: 'patch' }, - ], - }, - ], + 'semantic-release-commit-filter', + '@semantic-release/commit-analyzer', notesPlugin, ['semantic-release-pnpm', { npmPublish: false }], '../../scripts/publish-react.cjs', diff --git a/packages/sdk/.releaserc.cjs b/packages/sdk/.releaserc.cjs index bf9c50fca5..ea2f22e2f1 100644 --- a/packages/sdk/.releaserc.cjs +++ b/packages/sdk/.releaserc.cjs @@ -13,7 +13,6 @@ require('../../scripts/semantic-release/patch-commit-filter.cjs')([ 'packages/superdoc', 'packages/super-editor', 'packages/layout-engine', - 'packages/ai', 'packages/word-layout', 'packages/preset-geometry', 'shared', diff --git a/packages/superdoc/.releaserc.cjs b/packages/superdoc/.releaserc.cjs index 3d2f9de69b..e0d55b3570 100644 --- a/packages/superdoc/.releaserc.cjs +++ b/packages/superdoc/.releaserc.cjs @@ -10,7 +10,6 @@ const SUPERDOC_PACKAGES = [ 'packages/superdoc', 'packages/super-editor', 'packages/layout-engine', - 'packages/ai', 'packages/word-layout', 'packages/preset-geometry', 'shared', diff --git a/packages/template-builder/.releaserc.cjs b/packages/template-builder/.releaserc.cjs index 1b624a4de0..8104a5a966 100644 --- a/packages/template-builder/.releaserc.cjs +++ b/packages/template-builder/.releaserc.cjs @@ -1,24 +1,11 @@ /* eslint-env node */ /* - * Commit filter: template-builder depends on superdoc, so git log must include - * commits touching superdoc's sub-packages. This shared helper patches - * git-log-parser to expand path coverage. It REPLACES - * semantic-release-commit-filter — do not use both (the filter restricts - * to CWD, which undoes the expansion). - * - * Keep in sync with .github/workflows/release-template-builder.yml paths: trigger. + * Release narrow: template-builder externalizes `superdoc` in its build, so a + * core change does not alter the published template-builder tarball + * (consumers get the new core via their own peerDependencies install). Only + * commits touching packages/template-builder/** should trigger a release. + * See .github/package-impact-map.md. */ -require('../../scripts/semantic-release/patch-commit-filter.cjs')([ - 'packages/template-builder', - 'packages/superdoc', - 'packages/super-editor', - 'packages/layout-engine', - 'packages/ai', - 'packages/word-layout', - 'packages/preset-geometry', - 'shared', - 'pnpm-workspace.yaml', -]); const branch = process.env.GITHUB_REF_NAME || process.env.CI_COMMIT_BRANCH; @@ -40,21 +27,8 @@ const config = { branches, tagFormat: 'template-builder-v${version}', plugins: [ - [ - '@semantic-release/commit-analyzer', - { - // Cap at minor — template-builder depends on superdoc, so upstream breaking - // changes don't break template-builder's own public API. - // Prevents accidental major bumps from superdoc feat!/BREAKING CHANGE commits. - releaseRules: [ - { breaking: true, release: 'minor' }, - { type: 'feat', release: 'minor' }, - { type: 'fix', release: 'patch' }, - { type: 'perf', release: 'patch' }, - { type: 'revert', release: 'patch' }, - ], - }, - ], + 'semantic-release-commit-filter', + '@semantic-release/commit-analyzer', notesPlugin, ['@semantic-release/npm', { npmPublish: true }], ], From ae3e897d946f665319f47851a74ff68a6783e75d Mon Sep 17 00:00:00 2001 From: Caio Pizzol Date: Fri, 24 Apr 2026 15:19:34 -0300 Subject: [PATCH 2/4] ci(react): keep release broad - superdoc is a regular dep, not peer React declares superdoc in dependencies (">=1.0.0") rather than peerDependencies, unlike template-builder and esign. That means existing consumers with pinned lockfiles won't pick up a new core version until react republishes. Shrinking release-react to own paths would strand them on old core fixes. Revert release-react to broad core paths and restore the minor-cap release rules. The impact-map rationale now distinguishes react from the peer-dep wrappers and calls out the future peer-dep migration as the prerequisite for going narrow. No breaking change to consumers; migration to peerDependencies is tracked as a separate decision. --- .github/package-impact-map.md | 10 +++++--- .github/workflows/release-react.yml | 10 ++++++++ packages/react/.releaserc.cjs | 39 +++++++++++++++++++++++------ 3 files changed, 48 insertions(+), 11 deletions(-) diff --git a/.github/package-impact-map.md b/.github/package-impact-map.md index 500437e3ec..2eb36d2eaf 100644 --- a/.github/package-impact-map.md +++ b/.github/package-impact-map.md @@ -9,14 +9,14 @@ Source of truth for which repo paths should trigger CI and release workflows for - **CI gates compatibility.** A change to SuperDoc core should run the CI of every dependent package — that's how breakage in `@superdoc-dev/react` or `@superdoc-dev/sdk` gets caught before it ships. CI paths follow *compatibility* impact. - **Release gates artifact changes.** A package should only publish a new version when its own published artifact actually changes. Release paths follow *artifact* impact. -These two are not the same. React externalizes `superdoc` in its build, so a core change doesn't change the react tarball → CI broad, release narrow. CLI bundles core into platform binaries, so a core change does change the CLI tarball → both broad. +These two are not the same. `template-builder` and `esign` externalize `superdoc` in their builds and declare it as a `peerDependency`, so a core change doesn't change their tarballs → CI broad, release narrow. CLI bundles core into platform binaries, so a core change does change the CLI tarball → both broad. ## Surfaces | Surface | Purpose | Release impact | CI impact | |---|---|---|---| | `superdoc` | Main browser DOCX editor/runtime | core | core | -| `@superdoc-dev/react` | React wrapper around superdoc | `packages/react/**` only | react + core | +| `@superdoc-dev/react` | React wrapper around superdoc | react + core (see note below) | react + core | | `@superdoc-dev/template-builder` | React SDT/template authoring UI | `packages/template-builder/**` only | template-builder + core | | `@superdoc-dev/esign` | React signing workflow | `packages/esign/**` only | esign + core | | `@superdoc-dev/cli` | Native Document API CLI | cli + doc-api + core | same | @@ -49,7 +49,8 @@ These two are not the same. React externalizes `superdoc` in its build, so a cor ## Why each classification -- **React wrappers (`react`, `template-builder`, `esign`)** externalize `superdoc` in their Vite build (`rollupOptions.external`). A SuperDoc core change does not change the wrapper's published bundle — consumers receive the new core through their own `npm install` via `peerDependencies`. Release-on-core is pure version noise; CI-on-core remains necessary to catch breaking API changes. +- **`template-builder` and `esign`** externalize `superdoc` in their Vite build (`rollupOptions.external`) and declare it as a `peerDependency`. A SuperDoc core change does not change the wrapper's published bundle — consumers receive the new core through their own `npm install`. Release-on-core is pure version noise; CI-on-core remains necessary to catch breaking API changes. +- **`react`** externalizes `superdoc` in its Vite build the same way, but declares `superdoc` in `dependencies` (not `peerDependencies`). Existing consumers with lockfiles pinned to a specific react version won't pick up a new core version until react republishes, so release-on-core is correct *today*. Once react migrates `superdoc` to `peerDependencies` (a breaking change for consumers, tracked separately), it can move to release-narrow like the other wrappers. - **CLI / SDK** bundle engine behavior into platform-specific native binaries (see `apps/cli/.releaserc.cjs` and `packages/sdk/.releaserc.cjs` — both use `patch-commit-filter.cjs` to expand release analysis into core paths). The published artifact genuinely changes when core changes. - **MCP** depends on SDK via `workspace:*` and imports engine/session code directly. Its current release trigger (`apps/mcp/**` only) causes it to lag SDK releases. Expand to match SDK's release paths. - **VS Code extension** packages SuperDoc into the extension VSIX. Treated like CLI/SDK. @@ -60,5 +61,6 @@ These two are not the same. React externalizes `superdoc` in its build, so a cor ## Notes - `packages/ai/**` has been removed from all release and CI triggers. `@superdoc-dev/ai` is being deprecated; npm-side deprecation is a separate operational step. -- When SuperDoc core ships a breaking API change, React wrappers (`react`, `template-builder`, `esign`) must be manually updated and released. Their `peerDependencies` version bump is the signal; semantic-release won't auto-trigger on upstream changes. +- When SuperDoc core ships a breaking API change, `template-builder` and `esign` must be manually updated and released. Their `peerDependencies` version bump is the signal; semantic-release won't auto-trigger on upstream changes for them. +- `@superdoc-dev/react` currently declares `superdoc` in `dependencies`, not `peerDependencies`. A migration to peer-dep would unlock release-narrow here, but is a breaking change for consumers and is tracked as a separate decision. - When editing a release or CI workflow, its `paths:` filter must match the corresponding row in this map. Workflow-lint rules should enforce this. diff --git a/.github/workflows/release-react.yml b/.github/workflows/release-react.yml index 7ddd304f8e..6f541c507e 100644 --- a/.github/workflows/release-react.yml +++ b/.github/workflows/release-react.yml @@ -7,7 +7,17 @@ on: branches: - main paths: + # React declares `superdoc` in dependencies (not peerDependencies), so + # existing consumers with lockfiles won't pick up a new core version + # until react republishes. Keep release broad until the peer-dep + # migration lands (tracked separately). See .github/package-impact-map.md. - 'packages/react/**' + - 'packages/superdoc/**' + - 'packages/layout-engine/**' + - 'packages/super-editor/**' + - 'packages/word-layout/**' + - 'packages/preset-geometry/**' + - 'shared/**' - 'pnpm-workspace.yaml' - '!**/*.md' workflow_dispatch: diff --git a/packages/react/.releaserc.cjs b/packages/react/.releaserc.cjs index 11be8b01a1..3571721b49 100644 --- a/packages/react/.releaserc.cjs +++ b/packages/react/.releaserc.cjs @@ -1,11 +1,23 @@ /* eslint-env node */ /* - * Release narrow: react externalizes `superdoc` in its build, so a core - * change does not alter the published react tarball (consumers get the new - * core via their own peerDependencies install). Only commits touching - * packages/react/** should trigger a react release. See - * .github/package-impact-map.md. + * Commit filter: react declares `superdoc` in dependencies (not + * peerDependencies), so existing consumers with lockfiles won't pick up a + * new core version until react republishes. Expand commit analysis into + * core paths so semantic-release triggers a react release on core changes. + * + * When react migrates `superdoc` to peerDependencies, narrow this to + * packages/react only. See .github/package-impact-map.md. */ +require('../../scripts/semantic-release/patch-commit-filter.cjs')([ + 'packages/react', + 'packages/superdoc', + 'packages/super-editor', + 'packages/layout-engine', + 'packages/word-layout', + 'packages/preset-geometry', + 'shared', + 'pnpm-workspace.yaml', +]); const branch = process.env.GITHUB_REF_NAME || process.env.CI_COMMIT_BRANCH; @@ -27,8 +39,21 @@ const config = { branches, tagFormat: 'react-v${version}', plugins: [ - 'semantic-release-commit-filter', - '@semantic-release/commit-analyzer', + [ + '@semantic-release/commit-analyzer', + { + // Cap at minor — react declares superdoc in dependencies, so + // upstream breaking changes don't break react's own public API. + // Prevents accidental major bumps from superdoc feat!/BREAKING CHANGE commits. + releaseRules: [ + { breaking: true, release: 'minor' }, + { type: 'feat', release: 'minor' }, + { type: 'fix', release: 'patch' }, + { type: 'perf', release: 'patch' }, + { type: 'revert', release: 'patch' }, + ], + }, + ], notesPlugin, ['semantic-release-pnpm', { npmPublish: false }], '../../scripts/publish-react.cjs', From 1ab178cd9d702fd97b4ff7a933cb8d8f456f6004 Mon Sep 17 00:00:00 2001 From: Caio Pizzol Date: Fri, 24 Apr 2026 15:24:28 -0300 Subject: [PATCH 3/4] chore(react): dual-list superdoc as dep and peer for singleton signal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add superdoc to peerDependencies while keeping it in dependencies. Preserves auto-install for every consumer regardless of package manager (no breaking change) and signals the singleton contract that template-builder and esign already express via peer-dep. This is a semantic cleanup, not a release-policy change. release-react stays broad because existing consumers still pick up core versions via the dependencies pin. Removing superdoc from dependencies would unlock release-narrow but is a breaking change tracked separately. Verified with pnpm install --frozen-lockfile — no lockfile changes. --- .github/package-impact-map.md | 4 ++-- packages/react/package.json | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/package-impact-map.md b/.github/package-impact-map.md index 2eb36d2eaf..303c8f330b 100644 --- a/.github/package-impact-map.md +++ b/.github/package-impact-map.md @@ -50,7 +50,7 @@ These two are not the same. `template-builder` and `esign` externalize `superdoc ## Why each classification - **`template-builder` and `esign`** externalize `superdoc` in their Vite build (`rollupOptions.external`) and declare it as a `peerDependency`. A SuperDoc core change does not change the wrapper's published bundle — consumers receive the new core through their own `npm install`. Release-on-core is pure version noise; CI-on-core remains necessary to catch breaking API changes. -- **`react`** externalizes `superdoc` in its Vite build the same way, but declares `superdoc` in `dependencies` (not `peerDependencies`). Existing consumers with lockfiles pinned to a specific react version won't pick up a new core version until react republishes, so release-on-core is correct *today*. Once react migrates `superdoc` to `peerDependencies` (a breaking change for consumers, tracked separately), it can move to release-narrow like the other wrappers. +- **`react`** externalizes `superdoc` in its Vite build the same way, and declares `superdoc` in **both** `dependencies` and `peerDependencies`. The `dependencies` entry preserves auto-install for every consumer (zero-break regardless of package manager); the `peerDependencies` entry signals the singleton contract and aligns the manifest with template-builder/esign. Because the `dependencies` entry still pins via lockfiles, existing consumers only pick up a new core version when react republishes, so release-on-core stays correct *today*. The unlock for release-narrow is to remove `superdoc` from `dependencies` entirely — that is a breaking change and tracked as a separate decision. - **CLI / SDK** bundle engine behavior into platform-specific native binaries (see `apps/cli/.releaserc.cjs` and `packages/sdk/.releaserc.cjs` — both use `patch-commit-filter.cjs` to expand release analysis into core paths). The published artifact genuinely changes when core changes. - **MCP** depends on SDK via `workspace:*` and imports engine/session code directly. Its current release trigger (`apps/mcp/**` only) causes it to lag SDK releases. Expand to match SDK's release paths. - **VS Code extension** packages SuperDoc into the extension VSIX. Treated like CLI/SDK. @@ -62,5 +62,5 @@ These two are not the same. `template-builder` and `esign` externalize `superdoc - `packages/ai/**` has been removed from all release and CI triggers. `@superdoc-dev/ai` is being deprecated; npm-side deprecation is a separate operational step. - When SuperDoc core ships a breaking API change, `template-builder` and `esign` must be manually updated and released. Their `peerDependencies` version bump is the signal; semantic-release won't auto-trigger on upstream changes for them. -- `@superdoc-dev/react` currently declares `superdoc` in `dependencies`, not `peerDependencies`. A migration to peer-dep would unlock release-narrow here, but is a breaking change for consumers and is tracked as a separate decision. +- `@superdoc-dev/react` declares `superdoc` in both `dependencies` and `peerDependencies` to preserve zero-break install semantics while still signaling the singleton contract. Removing `superdoc` from `dependencies` is the unlock for release-narrow and is tracked as a separate decision. - When editing a release or CI workflow, its `paths:` filter must match the corresponding row in this map. Workflow-lint rules should enforce this. diff --git a/packages/react/package.json b/packages/react/package.json index b1263315ef..0c141cc074 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -40,7 +40,8 @@ }, "peerDependencies": { "react": ">=16.8.0", - "react-dom": ">=16.8.0" + "react-dom": ">=16.8.0", + "superdoc": ">=1.0.0" }, "devDependencies": { "@testing-library/react": "catalog:", From 71a4e40ed668a80204b1a808e1fc0c51de76f996 Mon Sep 17 00:00:00 2001 From: Caio Pizzol Date: Fri, 24 Apr 2026 15:26:39 -0300 Subject: [PATCH 4/4] ci: ignore packages/ai/** in ci-superdoc paths-ignore Review found ci-superdoc uses paths-ignore and did not list packages/ai/**, so an AI-only PR still triggered the full SuperDoc CI despite ai being deprecated. Add it to paths-ignore to match the impact-map claim that ai is removed from all release and CI triggers. --- .github/workflows/ci-superdoc.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci-superdoc.yml b/.github/workflows/ci-superdoc.yml index 208916f66e..ea3d8f2992 100644 --- a/.github/workflows/ci-superdoc.yml +++ b/.github/workflows/ci-superdoc.yml @@ -16,6 +16,7 @@ on: - 'packages/sdk/**' - 'packages/template-builder/**' - 'packages/esign/**' + - 'packages/ai/**' - 'evals/**' - '**/*.md' merge_group: