Skip to content

ci(preview-release): migrate workflow to pnpm ahead of FEC-924#3240

Merged
misama-ct merged 1 commit into
mainfrom
ci/preview-release-pnpm-precursor
May 13, 2026
Merged

ci(preview-release): migrate workflow to pnpm ahead of FEC-924#3240
misama-ct merged 1 commit into
mainfrom
ci/preview-release-pnpm-precursor

Conversation

@misama-ct
Copy link
Copy Markdown
Contributor

@misama-ct misama-ct commented May 13, 2026

Summary

Replaces the yarn-based steps in .github/workflows/preview-release-on-comment.yml with the pnpm equivalents that the FEC-924 migration branch (#3239) needs to publish a [preview_deployment] snapshot.

Why this lands ahead of the full migration

GitHub resolves uses: ./.github/workflows/... references against the calling workflow's commit. For issue_comment events that's always the default branch (main), regardless of which PR triggered the comment. The [preview_deployment] comment on #3239 therefore runs main's version of this file — currently the yarn version — against the pnpm-only PR branch's code, and fails immediately at yarn config get cacheFolder.

This precursor swaps just that one workflow so #3239 can publish a snapshot for canary validation by merchant-center-application-kit before the full migration merges.

Scope

  • Only .github/workflows/preview-release-on-comment.yml is changed.
  • No code, no lockfile, no package.json change.
  • No artifacts published as a result of this PR landing.

What changes in the workflow

  • Add Install pnpm step (pnpm/action-setup@v4).
  • Add package-manager-cache: false to actions/setup-node@v6 — v6's auto-cache combined with registry-url picks the runner's pre-installed yarn 1 over pnpm and aborts before any of the workflow's own steps run.
  • Swap Get yarn cache for Get pnpm store; update the actions/cache@v5 key and path accordingly.
  • Swap yarn install --immutablepnpm install --frozen-lockfile; yarn buildpnpm build; yarn generate-readmespnpm generate-readmes; yarn changeset version/publishpnpm changeset version/publish.

Side effects

Between this PR merging and #3239 merging, [preview_deployment] will only work on pnpm-based PRs. There are currently no other open developer PRs that rely on [preview_deployment].

main.yml and publish-release.yml are untouched — they remain yarn-based and keep working until the full migration lands.

Refs

Replaces the yarn-based steps in preview-release-on-comment.yml with
the pnpm equivalents that the FEC-924 migration branch (#3239) needs
to publish a snapshot via the [preview_deployment] PR comment.

Why this lands ahead of the full migration:
GitHub resolves `uses: ./.github/workflows/...` references against the
calling workflow's commit. For issue_comment events that's always the
default branch (main), regardless of which PR triggered the comment.
So the [preview_deployment] comment on PR #3239 runs main's version of
this file — currently the yarn version — against the pnpm-only PR
branch's code, and fails immediately.

This is a CI-only precursor; no published artifacts change. main's
other workflows (main.yml, publish-release.yml) remain yarn-based and
keep working until the full migration lands.

Temporary side effect: between this PR merging and PR #3239 merging,
[preview_deployment] only works for pnpm-based PRs. There are no
other open developer PRs that rely on it.

Includes the setup-node@v6 fix: package-manager-cache: false. v6's
built-in auto-cache combined with registry-url picks the runner's
pre-installed yarn 1 instead of pnpm and aborts before any of the
workflow's own steps run. We manage the pnpm store cache explicitly
via actions/cache@v5 below the setup-node step.
@misama-ct misama-ct requested a review from a team as a code owner May 13, 2026 11:41
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 13, 2026

⚠️ No Changeset found

Latest commit: 68f53de

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel
Copy link
Copy Markdown

vercel Bot commented May 13, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
ui-kit Ready Ready Preview, Comment May 13, 2026 11:42am

Request Review

@misama-ct misama-ct merged commit aac8c6b into main May 13, 2026
9 checks passed
@misama-ct misama-ct deleted the ci/preview-release-pnpm-precursor branch May 13, 2026 11:47
misama-ct added a commit that referenced this pull request May 13, 2026
GitHub Actions
- main.yml + publish-release.yml: `pnpm/action-setup@v4` + `pnpm store`
  cache + `pnpm install --frozen-lockfile`. `yarn` invocations replaced
  with `pnpm` / `pnpm --filter` equivalents.
- setup-node@v6 gets `package-manager-cache: false`: v6's built-in
  auto-cache combined with `registry-url` picks up the runner's
  pre-installed yarn 1 instead of pnpm and aborts before any of the
  workflow's own steps run. We manage the pnpm store cache explicitly
  via actions/cache@v5 below.
- Explicit `pnpm exec puppeteer browsers install chrome` step before
  VRT: pnpm's side-effects cache silently skips puppeteer's postinstall
  on cache restore, leaving the Chrome binary missing on the runner.
  Yarn's eager postinstall masked this.
- preview-release-on-comment.yml is untouched here — that file was
  landed as a precursor (#3240) so the [preview_deployment] PR comment
  could publish a snapshot for the mc-app-kit canary against this PR
  before merge. Including the precursor's content here would have
  produced an empty diff.

Vercel preview build
- vercel.json: installCommand / buildCommand overridden to use pnpm
  via Corepack (ENABLE_EXPERIMENTAL_COREPACK=1) since Vercel's default
  installer doesn't auto-pick pnpm from the packageManager field.

Refs: FEC-924
misama-ct added a commit that referenced this pull request May 18, 2026
* chore: bulk text replace yarn → pnpm in docs and tooling

Mechanical s/yarn/pnpm/g across non-code surfaces:

- 87 *.md / *.mdx files: AGENTS, CLAUDE, CONTRIBUTING, Storybook
  welcome pages, Percy README, ~75 per-package READMEs, generator
  templates.
- README generators (generators/readme + generators/package-json):
  the autogenerated header `<!-- created by the yarn generate-readme
  script -->` and the install instruction blocks (`yarn add` →
  `pnpm add`).
- Tool configs that invoke the package manager by name:
  jest-puppeteer (visual-testing-app:preview server command),
  lint-staged (prettier --write trigger), svgr (icon-generation
  header comment), and the three jest project configs.

No code change, no behaviour change. Split out so the rest of the
migration commits stay focused on real configuration / logic.

* refactor: replace yarn tooling with pnpm at the workspace level

The core of the migration. Swaps every yarn-specific surface for its
pnpm equivalent in a single atomic change:

Lockfile & package-manager pin
- yarn.lock removed; pnpm-lock.yaml generated against current deps.
- packageManager: yarn@3.8.7 → pnpm@10.33.4. engines.yarn dropped.
- workspace:* protocol used for local @commercetools-local/generator-*
  references (was bare *).

Workspace configuration
- .yarnrc.yml + .yarn/ (plugins, yarn 3.8.7 release) deleted.
- pnpm-workspace.yaml + .npmrc (shamefully-hoist=true, deliberate per
  FEC-924 "Resolved decisions") added.
- pnpm.onlyBuiltDependencies allowlist for postinstall scripts that
  need to run under pnpm's strict allow-list (@percy/core, @swc/core,
  core-js, esbuild, puppeteer, unrs-resolver).

Resolutions / overrides
- 37 yarn `resolutions` entries → pnpm.overrides, ported verbatim.
- yarn-specific `package@range` syntax preserved (path-to-regexp@^1.7.0,
  picomatch@^2.0.4, etc.) — pnpm supports the same format.
- Adds immutable@^4.3.8 override (CVE-2026-29063, was transitive on
  yarn too).

Workspace constraints
- constraints.pro (Prolog rules) replaced by
  scripts/check-workspace-constraints.js — same checks (license,
  repository, publishConfig.access) in a tool that doesn't require
  yarn-specific Prolog tooling.

Scripts (root package.json)
- yarn workspace … → pnpm --filter … run …
- manypkg run / exec → pnpm --filter … run … / pnpm -r exec …
- changeset:version-and-format swaps to `pnpm install --no-frozen-lockfile`.
- postinstall lifecycle hook wired to ./scripts/postinstall.sh (was
  previously the deleted yarn-plugin-postinstall fork).

Per-workspace package.json
- design-system gains explicit `prettier`, `rcfile`, `yaml`
  devDependencies. yarn's flat hoisting masked these transitively;
  pnpm's strict isolation requires them declared on the workspace
  that actually imports them.
- storybook package.json trivially adjusted.

Shell scripts & git hooks
- scripts/build.sh, build_watch.sh, postinstall.sh, print_release_version.sh
  use `pnpm` / `pnpm --filter` invocations.
- .husky/commit-msg + pre-commit reflect the same.

Phantom-import fix
- packages/components/dropdowns/dropdown-menu/src/dropdown-menu.stories.tsx:
  deep import `@commercetools-uikit/constraints/src` → top-level
  `@commercetools-uikit/constraints`. Surfaced by pnpm's stricter
  isolation, unrelated to the lockfile flip.

Refs: FEC-924

* ci: migrate GitHub Actions workflows and Vercel preview to pnpm

GitHub Actions
- main.yml + publish-release.yml: `pnpm/action-setup@v4` + `pnpm store`
  cache + `pnpm install --frozen-lockfile`. `yarn` invocations replaced
  with `pnpm` / `pnpm --filter` equivalents.
- setup-node@v6 gets `package-manager-cache: false`: v6's built-in
  auto-cache combined with `registry-url` picks up the runner's
  pre-installed yarn 1 instead of pnpm and aborts before any of the
  workflow's own steps run. We manage the pnpm store cache explicitly
  via actions/cache@v5 below.
- Explicit `pnpm exec puppeteer browsers install chrome` step before
  VRT: pnpm's side-effects cache silently skips puppeteer's postinstall
  on cache restore, leaving the Chrome binary missing on the runner.
  Yarn's eager postinstall masked this.
- preview-release-on-comment.yml is untouched here — that file was
  landed as a precursor (#3240) so the [preview_deployment] PR comment
  could publish a snapshot for the mc-app-kit canary against this PR
  before merge. Including the precursor's content here would have
  produced an empty diff.

Vercel preview build
- vercel.json: installCommand / buildCommand overridden to use pnpm
  via Corepack (ENABLE_EXPERIMENTAL_COREPACK=1) since Vercel's default
  installer doesn't auto-pick pnpm from the packageManager field.

Refs: FEC-924

* feat(ci): gate phantom-dep regressions via publint

Adds a CI gate that catches the class of regression FEC-924 risk #4
worries about: shamefully-hoist=true (which this PR ships, intentionally)
can let a publishable package import a dep it never declares. Works
locally, breaks for consumers on strict pnpm.

publint lints the *packed* tarball, so it detects the regression at
exactly the layer that matters — what consumers receive from npm.

- scripts/check-publint.js: iterates every non-private workspace
  package, runs `pnpm exec publint --pack pnpm` per package, fails CI
  on any non-zero aggregate exit. publint's defaults exit non-zero
  only on Errors (missing files referenced from package.json,
  unresolved imports, malformed exports). Warnings and Suggestions
  are logged but don't fail — pre-existing per-package findings
  (about pkg.exports / pkg.type / .esm.js handling / repository.url
  formatting) are unchanged between yarn-built main and pnpm-built
  migration, so they're out of scope.
- main.yml: adds a `Running publint check` step after typecheck. The
  step depends on `pnpm build` having run, since publint packs the
  built artifacts.

Pre-flight validation: pulled the published 20.5.0 tarball of every
non-private package from npm registry, packed every package locally
on this branch with pnpm, diffed normalised publint output. 97/97
identical — no migration-introduced findings.

Wired script + package.json entries (lint:publint, publint devDep)
already landed in the prior workspace-tooling commit.

Refs: FEC-924

* chore: regenerate icons

Re-runs `pnpm generate-icons` so the generated source files in
packages/components/icons + checkbox-input/src/icons +
rich-text-utils/src/rich-text-body/icons reflect the new generator
output under pnpm — primarily updates the header comment
(`yarn generate-icons` → `pnpm generate-icons`) plus minor
formatting normalisation from `prettier --write` on the resulting
files.

Mechanical output, no code change.

* chore(changeset): pnpm migration

Anchor changeset so the Changesets fixed-version group bumps every
published @commercetools-uikit/* + @commercetools-frontend/* package
in lockstep on next release. Triggers a minor bump in the 20.x line
per FEC-924's release decision.

Message reads "internal: package manager migrated from Yarn 3 to
pnpm; no consumer-facing changes." per the ticket.

* refactor: migrate patch-package to native pnpm patch

patch-package and pnpm don't play well together. patch-package writes
to the top-level node_modules/<pkg>/ path; under pnpm's strict layout
that location is a symlink into the .pnpm/<pkg>@<ver>/node_modules/<pkg>/
store directory, but patch-package doesn't follow the symlink to patch
the canonical file. The patch silently fails to apply, and the
postinstall step reports success regardless.

Concrete impact on this branch (before this commit): the lone patch
in patches/ — typescript-react-function-component-props-handler+1.1.1
— never took effect under pnpm. That patch adds an Array.isArray guard
before reading .params.length inside react-docgen's prop-extraction
pipeline; without it, `pnpm generate-readmes` throws
`TypeError: Cannot read properties of undefined (reading 'length')`
on certain components.

Native pnpm patch writes the patched file directly into the .pnpm
store via `pnpm.patchedDependencies` in root package.json. The patch
is now correctly applied at install time.

Mechanics:
- `pnpm patch typescript-react-function-component-props-handler@1.1.1`
  → applied the same Array.isArray fix
- `pnpm patch-commit` wrote patches/typescript-react-function-component-props-handler@1.1.1.patch
  (note `@` separator vs patch-package's `+`) and the
  patchedDependencies entry in root package.json
- Deleted patches/typescript-react-function-component-props-handler+1.1.1.patch
- Removed `patch-package` from devDependencies
- Removed `pnpm patch-package` invocation from scripts/postinstall.sh
- Reinstalled to regenerate pnpm-lock.yaml (patch-package + transitive
  deps removed, patch hash recorded against the patched package)

Verification: `pnpm generate-readmes` now runs to completion. Stale
README content in 10 packages exists as a separate concern — fixed in
the generator/tooling here; regenerating the actual README outputs is
a separate maintenance task.

Resolves FEC-924 follow-up: "patch-package → native pnpm patch".
Side-effect: also resolves "broken pnpm generate-readmes" since the
generator's underlying bug is what the patch was written to fix.

* chore(changeset): list all packages explicitly in pnpm migration entry

So every package's CHANGELOG.md carries the migration description
instead of "Updated dependencies []". Matches the 20.3.1 trusted-publishing
precedent. Same end-state versions via the fixed group.

* fix(constraints): port missing dep/devDep dedupe rule from constraints.pro

The original constraints.pro had a fourth rule preventing the same package
from appearing in both dependencies and devDependencies of a workspace. The
JS replacement omitted it. No current workspace violates it, but the gate
existed for a reason — restore it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant