Skip to content

chore(build): migrate core-web from yarn 1 to pnpm#35429

Draft
oidacra wants to merge 12 commits intomainfrom
worktree-poc-pnpm-migration
Draft

chore(build): migrate core-web from yarn 1 to pnpm#35429
oidacra wants to merge 12 commits intomainfrom
worktree-poc-pnpm-migration

Conversation

@oidacra
Copy link
Copy Markdown
Member

@oidacra oidacra commented Apr 22, 2026

Summary

Replaces Yarn Classic 1.22.22 with pnpm 10.17.1 as the package manager for core-web. The Dockerfile of the dotCMS image is untouched — the relevant bottleneck is the Maven stage (frontend-maven-plugin) that runs yarn install + nx run-many build, which is now driven by pnpm via exec-maven-plugin.

This PR is draft: please review the migration approach before we promote it to ready.

Local image generated successfully

CleanShot 2026-04-22 at 17 00 44@2x

Why

  • Faster installs: warm cache ~36% faster (28s vs 44s in local worktree). Cold installs comparable with GH Actions cache.
  • Smaller footprint: node_modules drops from 3.1 GB to 1.9 GB on disk; pnpm's shared store deduplicates across projects and branches on CI runners.
  • Stricter hygiene: pnpm rejects phantom dependencies that yarn 1 silently hoisted — this PR declares all of them explicitly.
  • OSS contributor ergonomics: no migration to Yarn PnP-style SDKs; pnpm install is familiar and first-class in Nx/Angular tooling.

What changed

Area Change
Package manager packageManager -> pnpm@10.17.1; resolutions -> pnpm.overrides; added pnpm.onlyBuiltDependencies (native postinstall allowlist) and pnpm.ignoredOptionalDependencies: [canvas]
Lockfile / RC yarn.lock + .yarnrc removed; pnpm-lock.yaml generated via pnpm import; .npmrc with the dotCMS registry, fetch-timeout, auto-install-peers
Phantom deps declared prosemirror-{model,state,transform,view}, tippy.js, @tiptap/extension-heading, prismjs, @material/{base,dom,mwc-base,mwc-icon,mwc-list,mwc-ripple,ripple}
Maven nodejs-parent/pom.xml: install-node-and-npm + corepack activation of pnpm; core-web/pom.xml: all 7+2 yarn goals -> exec-maven-plugin calling ${node.install.dir}/pnpm directly
CI maven-job/action.yml: yarn cache steps -> pnpm/action-setup@v4 + pnpm store cache keyed on core-web/pnpm-lock.yaml; deploy-javascript-sdk/action.yml: yarn install -> pnpm install --frozen-lockfile, npx -> pnpm exec
Project configs libs/dotcms-webcomponents/project.json: yarn stencil -> pnpm exec stencil; apps/dotcms-ui-e2e/playwright.config.ts: yarn nx run ... serve -> pnpm exec nx run ... serve
Docs core-web/CLAUDE.md, .github/copilot-instructions.md, .github/instructions/frontend.instructions.md
Husky Removed: core-web/.husky/pre-commit (~540 lines of shell) and core-web/prepare.js. The hook duplicated CI checks (lint, format, build) on every commit and added 15-30s of local friction. CI continues to enforce these. docs/core/GIT_WORKFLOWS.md updated with a short list of optional local commands

Local verification

pnpm install --frozen-lockfile                                           15.8s  (yarn baseline: 44.2s)
pnpm exec nx run-many -t build --exclude='tag:skip:build'                15/15 projects SUCCESS
./mvnw -DskipTests install -pl :dotcms-core-web --am                     BUILD SUCCESS in 1m13s
  -Dmaven.build.cache.enabled=false                                      (from fully clean state)

Test plan

  • CI passes on this PR (PR workflow, merge queue validation).
  • Reviewer clones fresh and runs cd core-web && pnpm install; confirms no surprises with the custom registry.
  • ./mvnw clean install -DskipTests succeeds from a clean working tree.
  • deploy-javascript-sdk dry-run (or the next SDK release) completes with the new pnpm install --frozen-lockfile step.
  • Review the package.json phantom-dep additions and confirm each version matches what yarn had pinned.
  • Confirm the husky removal is acceptable as a follow-up to the migration (no longer gating commits locally).

Notes / follow-ups

  • Devs who have been working in hidden-path worktrees (e.g. .claude/worktrees/…) should be aware of an upstream @nx/rollup@22.5.4 bug where its internal postcss filter uses picomatch(..., {dot:false}) and rejects CSS files under hidden-dir paths. It does not affect normal clones at paths like ~/Work/core/core-web. Worth reporting upstream as a separate issue.
  • Because the prepare hook was removed, pnpm-lock.yaml changes must be staged manually (CI will still fail on drift via --frozen-lockfile).

Replaces Yarn Classic 1.22.22 with pnpm 10.17.1 as the package manager
for core-web. Local benchmarks: ~36% faster installs on warm cache
(28s vs 44s) and ~38% smaller node_modules (1.9 GB vs 3.1 GB); shared
pnpm store deduplicates across projects on dev machines and CI runners.

Package / lockfile
- core-web/package.json: packageManager -> pnpm@10.17.1;
  resolutions -> pnpm.overrides; add pnpm.onlyBuiltDependencies (native
  postinstall allowlist) and pnpm.ignoredOptionalDependencies: [canvas]
  (matches yarn's implicit skip when the native build fails).
- core-web/.yarnrc + yarn.lock removed.
- core-web/.npmrc added: registry=https://dotcms-npm.b-cdn.net,
  fetch-timeout, auto-install-peers, engine-strict.
- core-web/pnpm-lock.yaml generated via pnpm import.

Phantom dependencies declared explicitly (yarn 1 hoisted them; pnpm
does not): prosemirror-model, prosemirror-state, prosemirror-transform,
prosemirror-view, tippy.js, @tiptap/extension-heading, prismjs, and
@material/{base,dom,mwc-base,mwc-icon,mwc-list,mwc-ripple,ripple}.

Maven
- nodejs-parent/pom.xml: frontend-maven-plugin goal changed to
  install-node-and-npm; two exec-maven-plugin executions via the
  bundled corepack activate pnpm and install its shim into
  installs/node.
- core-web/pom.xml: the 7 default + 2 format-profile yarn goals are now
  exec-maven-plugin executions that invoke ${node.install.dir}/pnpm
  directly; yarn.install.cmd -> pnpm.install.args.

CI
- .github/actions/core-cicd/maven-job/action.yml: yarn cache steps
  replaced with pnpm/action-setup@v4 + pnpm store cache keyed on
  core-web/pnpm-lock.yaml.
- .github/actions/core-cicd/deployment/deploy-javascript-sdk/action.yml:
  yarn install -> pnpm install --frozen-lockfile; npx -> pnpm exec.

Project-level yarn invocations
- libs/dotcms-webcomponents/project.json: yarn stencil build ->
  pnpm exec stencil build.
- apps/dotcms-ui-e2e/playwright.config.ts: yarn nx run ... serve ->
  pnpm exec nx run ... serve.

Husky removed
- Deleted core-web/.husky/pre-commit (~540 lines of shell) and
  core-web/prepare.js. Dropped the prepare script and husky devDep from
  package.json. The hook duplicated CI checks (lint, format, build) on
  every commit, added 15-30s of local friction, and was hard to keep in
  sync with the toolchain. CI continues to enforce these checks.
- docs/core/GIT_WORKFLOWS.md: replaced the pre-commit section with a
  short list of optional local commands.

Docs sweep (yarn -> pnpm): core-web/CLAUDE.md,
.github/copilot-instructions.md,
.github/instructions/frontend.instructions.md.

Verification (local, worktree)
- pnpm install --frozen-lockfile: 15.8s (vs yarn 44.2s on same repo).
- pnpm exec nx run-many -t build --exclude='tag:skip:build': 15/15
  projects built successfully.
- ./mvnw -DskipTests install -pl :dotcms-core-web --am
  -Dmaven.build.cache.enabled=false from a clean state (no
  node_modules, no installs/, no caches): BUILD SUCCESS in 1m13s.
@github-actions
Copy link
Copy Markdown
Contributor

❌ Issue Linking Required

This PR could not be linked to an issue. All PRs must be linked to an issue for tracking purposes.

How to fix this:

Option 1: Add keyword to PR body (Recommended - auto-removes this comment)
Edit this PR description and add one of these lines:

  • This PR fixes #123 or Fixes: #123

  • This PR closes #123 or Closes: #123

  • This PR resolves #123 or Resolves: #123

  • Other supported keywords: fix, fixed, close, closed, resolve, resolved
    Option 2: Link via GitHub UI (Note: won't clear the failed check)

  1. Go to the PR → Development section (right sidebar)

  2. Click "Link issue" and select an existing issue

  3. Push a new commit or re-run the workflow to clear the failed check
    Option 3: Use branch naming
    Create a new branch with one of these patterns:

  • 123-feature-description (number at start)

  • issue-123-feature-description (issue-number at start)

  • feature-issue-123 (issue-number anywhere)

Why is this required?

Issue linking ensures proper tracking, documentation, and helps maintain project history. It connects your code changes to the problem they solve.---

This comment was automatically generated by the issue linking workflow

@github-actions github-actions Bot added Area : CI/CD PR changes GitHub Actions/workflows Area : Documentation PR changes documentation files Area : Frontend PR changes Angular/TypeScript frontend code labels Apr 22, 2026
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 22, 2026

Claude finished @oidacra's task in 4m 16s —— View job


PR Review: pnpm migration

  • Read changed files
  • Review Maven/build config changes
  • Review CI action changes
  • Review package.json / .npmrc
  • Review husky removal
  • Review security findings from Semgrep
  • Write final review

Security: direct dependencies below CVE fix versions

Three direct dependencies in package.json are below the versions that fix flagged CVEs. These are not introduced by the migration (they existed before), but the lockfile regeneration makes this a good time to close them.

rollup@4.14.0 (devDependencies)

  • CVE-2024-47068 (XSS): fix at ≥4.22.4
  • CVE-2026-27606 (path traversal → arbitrary file write): fix at ≥4.59.0
  • The path traversal is exploitable via rollup --input, which is used in the Stencil webcomponents build. Direct upgrade needed: "rollup": "4.59.0".
  • Fix this →

webpack@5.64.0 (devDependencies)

  • CVE-2023-28154 (improper access control): fix at ≥5.76.0
  • Direct upgrade needed: "webpack": "5.76.0" or latest 5.x.
  • Fix this →

next@14.0.4 (dependencies)

Also worth adding to pnpm.overrides: vite and axios are at their fix versions as direct deps, but the lockfile has transitive instances at older versions (Semgrep hits at pnpm-lock.yaml:7313/7316 and 14027/14067). Adding them to pnpm.overrides would force those transitive resolutions up:

"pnpm": {
  "overrides": {
    ...
    "axios": ">=1.15.0",
    "vite": ">=7.3.2"
  }
}

Misleading comment in nodejs-parent/pom.xml:43-46

dotcms-ui-e2e was migrated to pnpm in this PR (apps/dotcms-ui-e2e/pom.xml now uses exec-maven-plugin calling ${node.install.dir}/pnpm). The comment should name only the remaining yarn consumers (e.g., dotcms-postman, dotcms-e2e-node) to avoid confusion about what still needs yarn.


Corepack prepare is not covered by the node binary cache

In nodejs-parent/pom.xml, corepack prepare pnpm@${pnpm.version} --activate downloads the pnpm binary from the corepack registry into ~/.local/share/pnpm (or the platform equivalent). This path is not part of the installs/ directory that restore-cache-node caches in maven-job/action.yml.

On any CI run that restores a warm installs/ cache but has a cold corepack data dir (e.g., a fresh runner), pnpm is re-downloaded. This partially undermines the node binary cache speedup. Options:

  • Cache ~/.local/share/pnpm (or $PNPM_HOME) alongside installs/
  • Or skip corepack prepare if the shim already resolves to the right binary

This is a performance concern, not a correctness issue, but worth addressing for CI cost.


Minor: commandlineArgs vs <arguments> inconsistency in core-web/pom.xml

The build-test execution uses a flat string:

<commandlineArgs>exec nx run-many -t build --exclude=tag:skip:build --verbose ${nx.build.options}</commandlineArgs>

All other executions use the <arguments> list form. commandlineArgs splits on spaces, which breaks if any arg contains spaces. ${nx.build.options} is currently --prod or empty so it's safe today, but the inconsistency is a latent hazard if that property ever contains a space-separated value.


Confirmed clean

  • .npmrc registry, strict-peer-dependencies, fetch-timeout are all correctly migrated from yarn 1 semantics.
  • pnpm.overrides correctly replaces resolutions.
  • pnpm.onlyBuiltDependencies allowlist covers known native-build packages.
  • pnpm/action-setup@v4 + version sync check in maven-job/action.yml is solid.
  • deploy-javascript-sdk/action.yml migration (pnpm install --frozen-lockfile, pnpm exec nx) is correct.
  • Husky removal is defensible — CI enforces the same checks.
  • playwright.config.ts change from yarn nxpnpm exec nx is correct.
  • Cache key for node binary now hashes nodejs-parent/pom.xml to bust yarn-era layout. Good.

oidacra added 3 commits April 22, 2026 16:58
The action runs from the repo root where there is no package.json, so
it cannot resolve the pnpm version from `packageManager`. Passing
package_json_file tells it to look at core-web/package.json, where the
field lives.

Failure observed on PR #35429 / Initial Artifact Build:
  Error: No pnpm version is specified.
The Node Binary Cache key was `node-binary-${hashFiles(core-web/.nvmrc)}`,
so runs on this branch restored an installs/ directory produced by the
previous yarn-era pipeline (install-node-and-yarn). That layout has
node but does not populate node_modules/corepack/ the way
install-node-and-npm does, and the plugin sees 'Node v22.15.0 is
already installed' and skips re-downloading. The follow-up
exec-maven-plugin step then fails with:

  Cannot find module '.../installs/node/node_modules/corepack/dist/corepack.js'

Include nodejs-parent/pom.xml in the cache key so the pnpm-era layout
doesn't share a slot with the yarn-era one.
Medium
- core-web/pom.xml: lint-test and unit-test executions now use the
  ${git.origin.branch} property instead of hardcoded --base=origin/main,
  so the is_pr profile and any future branch config applies.
- maven-job/action.yml: save-cache-pnpm now has the same requires-node
  guard as restore-cache-pnpm, avoiding an empty path when a job runs
  with requires-node=false and generate-artifacts=true.

Low
- deploy-javascript-sdk/action.yml: removed the standalone
  'Enable Corepack' step; pnpm/action-setup@v4 handles pnpm activation
  on its own, so the explicit corepack enable was redundant and could
  introduce a different pnpm version from the system corepack.
- .npmrc: dropped auto-install-peers=true. Phantom deps are declared
  explicitly in package.json now, so the pnpm default (strict) gives us
  tighter hygiene. Added a comment explaining why
  strict-peer-dependencies=false is still needed (pre-existing conflicts
  like codelyzer, ng-mocks, ngx-markdown).

Info
- apps/dotcms-ui-e2e/CLAUDE.md: yarn nx e2e -> pnpm nx e2e.
- nodejs-parent/pom.xml: clarified via comment that
  frontend-maven-plugin normalises the Node tarball layout on both
  Linux and macOS to ${node.install.dir}/node_modules/corepack, so the
  direct node-driven corepack.js path works cross-platform (confirmed
  by the earlier CI error message itself referencing the same path).
@semgrep-code-dotcms-test
Copy link
Copy Markdown

Legal Risk

The following dependencies were released under a license that
has been flagged by your organization for consideration.

Recommendation

While merging is not directly blocked, it's best to pause and consider what it means to use this license before continuing. If you are unsure, reach out to your security team or Semgrep admin to address this issue.

GPL-2.0

MPL-2.0

@semgrep-code-dotcms-test
Copy link
Copy Markdown

Semgrep found 2 ssc-4759c514-b537-20ef-d52f-ebb0a5c388fa findings:

Risk: Affected versions of axios are vulnerable to Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Request/Response Splitting') / Inconsistent Interpretation of HTTP Requests ('HTTP Request/Response Smuggling') / Server-Side Request Forgery (SSRF). Axios can be used as a gadget for header injection: if another dependency enables prototype pollution, polluted properties can be merged into Axios request headers and written without CRLF sanitization, allowing request smuggling/SSRF that can reach internal services such as AWS IMDSv2 and potentially lead to credential theft or broader compromise.

Fix: Upgrade this library to at least version 1.15.0 at core/core-web/pnpm-lock.yaml:7316.

Reference(s): GHSA-fvcv-3m26-pcqx, CVE-2026-40175

If this is a critical or high severity finding, please also link this issue in the #security channel in Slack.

Semgrep found 2 ssc-5ea2c631-7cef-a4e0-e641-d179af079827 findings:

Risk: Affected versions of axios are vulnerable to Server-Side Request Forgery (SSRF) / Unintended Proxy or Intermediary ('Confused Deputy'). Axios does not normalize hostnames before applying NO_PROXY, so requests to loopback or internal hosts such as localhost. or [::1] can be sent through a configured proxy instead of bypassing it. If an attacker can influence request URLs, they may force local/internal Axios traffic through an attacker-controlled proxy, undermining SSRF protections and exposing sensitive responses.

Manual Review Advice: A vulnerability from this advisory is reachable if you have NO_PROXY configured in your environment

Fix: Upgrade this library to at least version 1.15.0 at core/core-web/pnpm-lock.yaml:7316.

Reference(s): GHSA-3p68-rc4w-qgx5, CVE-2025-62718

If this is a critical or high severity finding, please also link this issue in the #security channel in Slack.

Semgrep found 1 ssc-6efe528b-deef-ace9-810a-467438938c20 finding:

Risk: Affected versions of next are vulnerable to Allocation of Resources Without Limits or Throttling. A specially crafted HTTP request to a Next.js App Router Server Function endpoint can trigger excessive CPU consumption during React Server Components deserialization, leading to denial of service.

Fix: Upgrade this library to at least version 15.5.15 at core/core-web/pnpm-lock.yaml:11218.

Reference(s): GHSA-q4gf-8mx6-v5v3

If this is a critical or high severity finding, please also link this issue in the #security channel in Slack.

Semgrep found 2 ssc-1289c362-ab31-4c96-bd5e-5e444f4fb067 findings:

Risk: Affected versions of vite are vulnerable to Exposure of Sensitive Information to an Unauthorized Actor / Missing Authentication for Critical Function. This occurs because the Vite Dev Server WebSocket improperly exposes the fetchModule method, allowing unauthenticated remote attackers to bypass filesystem restrictions and read arbitrary files from the host machine

Manual Review Advice: A vulnerability from this advisory is reachable if you enable vite dev server using --host flag and websocket is not disabled

Fix: Upgrade this library to at least version 7.3.2 at core/core-web/pnpm-lock.yaml:14067.

Reference(s): GHSA-p9ff-h696-f583, CVE-2026-39363

If this is a critical or high severity finding, please also link this issue in the #security channel in Slack.

Semgrep found 2 ssc-81d0f8fa-e5f9-414f-a539-fa38f9590a35 findings:

Risk: Affected versions of vite are vulnerable to Improper Access Control / Incorrect Behavior Order. Vite's dev server can bypass server.fs.deny protections: if the server is exposed to the network and a denied file is within an allowed directory, an attacker can retrieve sensitive files such as .env or certificate files by requesting them with query parameters like ?raw, ?import&raw, or ?import&url&inline.

Manual Review Advice: A vulnerability from this advisory is reachable if you enable vite dev server using --host flag and have sensitive data in deny list

Fix: Upgrade this library to at least version 7.3.2 at core/core-web/pnpm-lock.yaml:14067.

Reference(s): GHSA-v2wj-q39q-566r, CVE-2026-39364

If this is a critical or high severity finding, please also link this issue in the #security channel in Slack.

Semgrep found 2 ssc-c1e42c77-a3f9-4dae-adc7-2b52e247269b findings:

Risk: Affected versions of @angular/compiler and @angular/core are vulnerable to Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting'). Angular's runtime/compiler can be vulnerable to XSS when a security-sensitive attribute (e.g., href, src, action, xlink:href, etc.) is both data-bound and marked for internationalization using i18n-<attribute>, which can bypass Angular's built-in sanitization. If untrusted/user-controlled input is bound into one of these attributes while i18n-* is present (e.g., <a href="{{maliciousUrl}}" i18n-href>), an attacker can inject a javascript:/malicious URL and execute script in the context of the application's origin (cookie/session theft, data exfiltration, and unauthorized actions).

Manual Review Advice: A vulnerability from this advisory is reachable if you enable internationalization for the sensitive attribute by adding i18n- while it receives untrusted data

Fix: Upgrade this library to at least version 21.2.4 at core/core-web/pnpm-lock.yaml:1064.

Reference(s): GHSA-g93w-mfhg-p222, CVE-2026-32635

If this is a critical or high severity finding, please also link this issue in the #security channel in Slack.

Semgrep found 1 ssc-c313d835-7f7c-4f67-a6e2-ac5038d1fb9d finding:

Risk: Affected versions of storybook are vulnerable to Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') / Improper Neutralization of Special Elements in Output Used by a Downstream Component ('Injection') / Missing Origin Validation in WebSockets. Storybook's dev server WebSocket endpoint does not validate the Origin of incoming connections, enabling WebSocket hijacking. If a developer visits a malicious website while a local Storybook dev server is running (or if the dev server is publicly exposed), an attacker can open an unauthorized WebSocket connection and invoke the "create/save story" handlers to write attacker-controlled content into story files, leading to persistent XSS and potentially remote code execution and supply-chain compromise if the injected changes are committed and propagated.

Manual Review Advice: A vulnerability from this advisory is reachable if you visit a malicious website while your local Storybook dev server is running

Fix: Upgrade this library to at least version 10.2.10 at core/core-web/pnpm-lock.yaml:13236.

Reference(s): GHSA-mjf5-7g4m-gx5w, CVE-2026-27148

If this is a critical or high severity finding, please also link this issue in the #security channel in Slack.

Semgrep found 1 ssc-6193c409-cebc-449c-8a55-f95fa9d0e4f0 finding:

Risk: Affected versions of rollup are vulnerable to Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal'). Rollup is vulnerable to arbitrary file write via path traversal: chunk/asset names derived from user-controlled inputs (e.g., CLI named inputs, manual chunk aliases, or malicious plugins) are insufficiently sanitized, allowing ../ sequences to survive and be passed into path.resolve when computing output paths. This lets an attacker escape the configured output directory and overwrite arbitrary files on the host filesystem that the build process can write to, potentially leading to persistent RCE by clobbering shell/profile or other executable/config files.

Manual Review Advice: A vulnerability from this advisory is reachable if you are running rollup --input

Fix: Upgrade this library to at least version 4.59.0 at core/core-web/pnpm-lock.yaml:12710.

Reference(s): GHSA-mw96-cpmx-2vgc, CVE-2026-27606

If this is a critical or high severity finding, please also link this issue in the #security channel in Slack.

Semgrep found 1 ssc-d1b4e9e7-4dae-4218-8bb1-046e9a0b7e60 finding:

Risk: Affected versions of next are vulnerable to Deserialization of Untrusted Data / Uncontrolled Resource Consumption. A flaw in React Server Components' deserialization allows an attacker to send a specially crafted HTTP request to any App Router Server Function endpoint in Next.js, triggering excessive CPU usage, out-of-memory conditions, or a server crash and resulting in a denial of service.

Fix: Upgrade this library to at least version 15.0.8 at core/core-web/pnpm-lock.yaml:11218.

Reference(s): GHSA-h25m-26qc-wcjf, CVE-2026-23864

If this is a critical or high severity finding, please also link this issue in the #security channel in Slack.

Semgrep found 1 ssc-b94a740c-3b13-43fd-9f2d-4d8bb0fe0b69 finding:

Risk: Affected versions of next are vulnerable to Dependency on Vulnerable Third-Party Component / Deserialization of Untrusted Data / Uncontrolled Resource Consumption. An attacker can send a specially crafted HTTP request to any Server Function endpoint (as used by Next.js' App Router) that, when deserialized by the React Server Components runtime, enters an infinite loop—hanging the server process, exhausting CPU, and resulting in a denial-of-service.

Fix: Upgrade this library to at least version 14.2.35 at core/core-web/pnpm-lock.yaml:11218.

Reference(s): GHSA-5j59-xgg2-r9c4, CVE-2025-67779

If this is a critical or high severity finding, please also link this issue in the #security channel in Slack.

Semgrep found 1 ssc-74b4cbd5-76e9-40fe-adb6-38be9f569d24 finding:

Risk: Affected versions of next are vulnerable to Dependency on Vulnerable Third-Party Component / Deserialization of Untrusted Data / Uncontrolled Resource Consumption. A flaw in Next.js's App Router deserialization allows an attacker to send a specially crafted HTTP request body that, when parsed by the server, triggers excessive CPU work or an infinite loop. By targeting any App Router endpoint with this malicious payload, the server process can hang and become unresponsive, resulting in a denial-of-service.

Fix: Upgrade this library to at least version 14.2.34 at core/core-web/pnpm-lock.yaml:11218.

Reference(s): GHSA-mwv6-3258-q52c

If this is a critical or high severity finding, please also link this issue in the #security channel in Slack.

Semgrep found 1 ssc-cee3e6d5-d7c8-4c35-9815-076aa1ebfd49 finding:

Risk: Affected versions of rollup are vulnerable to Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting').

Manual Review Advice: A vulnerability from this advisory is reachable if you use Rollup to bundle JavaScript with import.meta.url and the output format is set to cjs, umd, or iife formats, while allowing users to inject scriptless HTML elements with unsanitized name attributes

Fix: Upgrade this library to at least version 4.22.4 at core/core-web/pnpm-lock.yaml:12710.

Reference(s): GHSA-gcx4-mw62-g8wm, CVE-2024-47068

If this is a critical or high severity finding, please also link this issue in the #security channel in Slack.

Semgrep found 1 ssc-37ae9e0a-cbf0-4910-8f73-04f2275899a6 finding:

Risk: webpack 5.x before 5.76.0 is vulnerable to Improper Access Control due to ImportParserPlugin.js mishandling the magic comment feature. Due to this, webpack does not avoid cross-realm object access and an attacker who controls a property of an untrusted object can obtain access to the real global object.

Manual Review Advice: A vulnerability from this advisory is reachable if you host an application utilizing webpack and an attacker can control a property of an untrusted object

Fix: Upgrade this library to at least version 5.76.0 at core/core-web/pnpm-lock.yaml:14340.

Reference(s): GHSA-hc6q-2mpp-qw7j, CVE-2023-28154

If this is a critical or high severity finding, please also link this issue in the #security channel in Slack.

oidacra added 8 commits April 22, 2026 17:21
pnpm's corepack shim installs at installs/node/pnpm as a symlink to
node_modules/corepack/dist/pnpm.js. That script starts with:

  #!/usr/bin/env node

On GitHub-hosted runners the default PATH has Node 20, which gets
picked up first and fails the engines.node >=22 check in package.json
with ERR_PNPM_UNSUPPORTED_ENGINE. Prepend ${node.install.dir} to PATH
in exec-maven-plugin so the installed Node 22 is used instead.

Observed on PR #35429 / Initial Artifact Build:
  Expected version: >=v22.15.0
  Got: v20.20.2
`nx format:check` (the format-test Maven execution) fails on the
generated pnpm-lock.yaml because prettier's YAML formatting differs
from pnpm's output. Ignore it the same way yarn-error.log.json /
package-lock.json are already ignored.

Observed on PR #35429 CI:
  > nx format:check
  pnpm-lock.yaml
  Command execution failed. Process exited with an error: 1
dotcms-postman, core-web/apps/dotcms-ui-e2e and e2e/dotcms-e2e-node
still use frontend-maven-plugin's yarn goal. They were explicitly
out-of-scope for the core-web → pnpm migration but broke because
nodejs-parent stopped installing yarn.

Add install-node-and-yarn as a second execution alongside
install-node-and-npm. Both share the same installed Node 22, yarn lands
at installs/node/yarn/dist/bin/yarn, and pnpm at installs/node/pnpm
via corepack. The three modules continue to work without change.

Observed on PR #35429 after core-web install succeeded:
  Failed to execute goal frontend-maven-plugin:1.12.1:yarn (install)
    on project dotcms-postman:
    Cannot run program ".../installs/node/yarn/dist/bin/yarn"
dotcms-ui-e2e reuses core-web's node_modules via
workingDirectory=../../ (the e2e.frontend.dir property). After the
core-web migration, that directory has pnpm-lock.yaml instead of
yarn.lock, so the old yarn goal failed with 'info No lockfile found'
and the frozen-lockfile constraint broke the build.

Replace the four frontend-maven-plugin yarn executions (install,
install-playwright, run node script, run post node script) with
exec-maven-plugin executions that invoke ${node.install.dir}/pnpm
directly, mirroring core-web's setup. PATH is prepended with
installs/node so the pnpm shim's Node 22 is used instead of the
runner's default Node 20.

Observed on PR #35429 after core-web build succeeded:
  Failed to execute goal frontend-maven-plugin:1.12.1:yarn (install)
    on project dotcms-ui-e2e:
    Running 'yarn install --frozen-lockfile' in .../core-web
    info No lockfile found.
- e2e pom: install libasound2t64 in CI; drop --with-deps (Playwright 1.36
  maps it to libasound2, no longer in noble)
- bump @angular/* 21.2.1->21.2.4 (XSS GHSA-g93w-mfhg-p222)
- bump axios 1.13.6->1.15.0 (CRLF/SSRF CVE-2026-40175, CVE-2025-62718)
- bump vite 7.2.7->7.3.2, storybook 10.2.9->10.2.10
- maven-job: enforce pnpm version sync (package.json packageManager vs
  nodejs-parent/pom.xml pnpm.version) so cache key cannot drift from the
  pnpm Maven actually invokes
- deploy-javascript-sdk: add pnpm store cache (restore + save)
- e2e pom: replace bracketed conditional (sh: 1: [: missing ]) with a
  fault-tolerant single-quoted apt-get install of libasound2t64; on
  non-Linux or missing-package the install is skipped via || true,
  then pnpm exec playwright install runs unconditionally
- declare @jest/globals 30.2.0 in devDependencies (sdk-uve and other
  workspaces import it explicitly; pnpm strict layout did not hoist
  the transitive copy)
Under yarn the path was node_modules/gridstack/..., but pnpm nests via
node_modules/.pnpm/gridstack@8.4.0/node_modules/gridstack/.... The
existing negative-lookahead only matched the package name immediately
after node_modules/, so pnpm paths slipped through and Jest refused to
parse the ESM source ("Cannot use import statement outside a module").

Wrap the package alternates in (?:...) and prefix with .* so they match
anywhere after node_modules/, mirroring the pattern already used in
edit-ema/{ui,portlet} jest configs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI: Safe To Rollback Area : CI/CD PR changes GitHub Actions/workflows Area : Documentation PR changes documentation files Area : Frontend PR changes Angular/TypeScript frontend code

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant