Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 3 additions & 8 deletions .github/renovate.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,9 @@
"dependencyDashboardApproval": true
},
{
"description": "web/pnpm-workspace.yaml pins these EXACTLY, to deduplicate the ProseMirror core that @tiptap/pm and y-prosemirror both depend on: when pnpm resolves them to different patches, tsc fails with a wall of 'not assignable' errors between two structurally identical Node types. That is the whole reason. Surfaced on the dashboard rather than automerged because a bump has to be checked for re-duplication, not because any version is suspect.",
"matchPackageNames": [
"prosemirror-model",
"prosemirror-state",
"prosemirror-view"
],
"automerge": false,
"dependencyDashboardApproval": true
"description": "@tiptap/y-tiptap is published from ueberdosis/y-tiptap, a DIFFERENT repo from ueberdosis/tiptap, so Renovate's monorepo preset does not group it with @tiptap/* and it would otherwise get its own PR. It has to move in the same PR: it is the Yjs binding that @tiptap/extension-collaboration and -collaboration-caret peer-depend on, and the module src/features/comments/anchor.ts imports ySyncPluginKey from. Resolve two copies and the key becomes 'y-sync$' in one and 'y-sync$1' in the other, at which point getState() silently returns undefined and comment anchors stop resolving. Nothing throws.",
"groupName": "tiptap",
"matchPackageNames": ["@tiptap/y-tiptap"]
},
{
"description": "Security floors in web/pnpm-workspace.yaml overrides. Raising them is welcome, but they exist because a parent hard-pins a vulnerable version, so a bump here needs a human to confirm the parent still resolves.",
Expand Down
13 changes: 13 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,19 @@ jobs:
cache-dependency-path: web/pnpm-lock.yaml
- run: pnpm install --frozen-lockfile
working-directory: web
# The editor breaks quietly when pnpm resolves two copies of the
# ProseMirror core: @tiptap/pm and @tiptap/y-tiptap get structurally
# identical but distinct Node classes, and @tiptap/y-tiptap gets two
# ySyncPluginKey objects — 'y-sync$' and 'y-sync$1' — at which point
# getState() returns undefined and every comment anchor resolves to null.
# web/pnpm-workspace.yaml used to prevent this by pinning prosemirror-*
# exactly, which also held them BELOW the ranges @tiptap/pm declares.
# This is the replacement, and it is not redundant with the jobs below:
# a duplicated tree passes tsc, eslint and the full vitest suite.
# It matters most for lockFileMaintenance, which runs pnpm update and
# automerges itself once green.
- run: pnpm dedupe --check
working-directory: web
- run: pnpm tsc --noEmit
working-directory: web
- run: pnpm lint
Expand Down
12 changes: 8 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,14 @@ Renovate groups each into a single PR; do the same by hand:
| pnpm | `packageManager` in `web/` and `e2e/package.json`, `pnpm/action-setup` `version:` |
| Node | `node:…-alpine` in `Dockerfile`, `node-version:` in `ci.yml` |

Left out of automation on purpose: the exact `prosemirror-*` pins in
`web/pnpm-workspace.yaml` (they deduplicate the editor core — see the comment
there for what breaks), the security floors in the same file's `overrides`, and
`@playwright/test`, which ships the browser the e2e suite runs against.
Left out of automation on purpose: the security floors in
`web/pnpm-workspace.yaml`'s `overrides`, and `@playwright/test`, which ships the
browser the e2e suite runs against.

`@tiptap/y-tiptap` is grouped with the `@tiptap/*` packages in `renovate.json`
even though it is published from a different upstream repo. It is the Yjs
binding the collaboration extensions peer-depend on and the one `ySyncPluginKey`
comes from, so it has to be tested against the tiptap version it will ship with.

`cargo deny check` gates every PR. When an advisory has no reachable fix, add it
to `deny.toml` with the dependency path and the upstream event that would let us
Expand Down
69 changes: 33 additions & 36 deletions web/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 0 additions & 20 deletions web/pnpm-workspace.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,26 +27,6 @@ overrides:
# patched release regardless of what mermaid or excalidraw ask for.
dompurify@<3.4.13: "^3.4.13"

# Deduplication, not security. @tiptap/pm and y-prosemirror both declare wide
# `^1.x` ranges on the ProseMirror core, and pnpm is free to resolve them to
# different patches. When it does, the editor is handed two structurally
# identical but nominally distinct `Node` types and tsc fails with a wall of
# "not assignable" errors.
#
# Pinned EXACTLY to the versions main resolved, not to the newest release.
# Dedupe is the goal; upgrading this stack is a separate, deliberate change.
#
# These pins were introduced in a5c7042, which blamed prosemirror-view 1.42
# for a history-restore failure. That diagnosis was wrong and ccf5dbd
# retracts it: the actual defect was ReplaceWithMarkdown broadcasting only
# its insertion, so peers appended the restored text instead of replacing.
# Nothing is known to be wrong with prosemirror-view 1.42 — do not treat
# these versions as a quarantine. Lifting them is an ordinary upgrade that
# wants a CI run, not a re-investigation.
prosemirror-model: "1.25.7"
prosemirror-state: "1.4.4"
prosemirror-view: "1.41.8"

# pnpm >= 10 blocks dependency lifecycle scripts unless they are approved here.
# esbuild is the only package in this tree whose install script is required.
allowBuilds:
Expand Down