Changed package manager from yarn to pnpm#529
Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (33)
WalkthroughThis PR migrates the repository from Yarn to pnpm. It updates GitHub Actions test jobs to install/setup pnpm, configure Node with pnpm caching, run pnpm install --frozen-lockfile, and execute pnpm test:ci per theme. The root package.json adds packageManager: "pnpm@11.5.1" and pnpm-workspace.yaml is added/updated. Theme package.json files gain packageManager, gulp zipper tasks exclude pnpm artifacts, and README/AGENTS.md/README docs replace Yarn commands with pnpm equivalents. Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 Biome (2.4.16)gulpfile.jsFile contains syntax errors that prevent linting: Line 135: Illegal use of reserved keyword Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
.github/workflows/alto.yml (1)
13-26: ⚡ Quick winConsider restricting test job permissions.
The test jobs use default (broad) permissions. Since these jobs only check out code and run tests, consider adding explicit read-only permissions for defense in depth:
jobs: test: name: Test runs-on: ubuntu-latest permissions: contents: read if: github.event_name == 'push' || (github.event_name == 'pull_request' && !startsWith(github.head_ref, 'renovate/'))🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/alto.yml around lines 13 - 26, The test job named "test" is using default broad workflow permissions; add explicit read-only permissions to harden the job by adding a permissions block under the "test" job (permissions: contents: read) so the job only has read access to repository contents while still checking out code and running tests.Source: Linters/SAST tools
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/alto.yml:
- Line 19: The pinned revision for the pnpm action is invalid: replace the
broken reference "pnpm/action-setup@ac6db6d3c1f721f886538a378a2d73e85697340a"
with a valid commit SHA or a stable published tag (for example a recent release
like "pnpm/action-setup@v2" or a verified commit SHA from the pnpm/action-setup
repository) so the workflow step resolves successfully; update the uses entry in
the workflow to the corrected ref.
In `@packages/london/README.md`:
- Line 14: Replace the incorrect phrase "Edition styles" with "London styles"
(or simply "Styles") in the README text that currently reads "Edition styles are
compiled using Gulp/PostCSS..." so the theme name matches the package; locate
that exact string ("Edition styles are compiled using Gulp/PostCSS to polyfill
future CSS spec.") and update it to "London styles are compiled using
Gulp/PostCSS to polyfill future CSS spec." or "Styles are compiled using
Gulp/PostCSS to polyfill future CSS spec." depending on preferred wording.
In `@packages/solo/README.md`:
- Line 14: Change the phrase "Edition styles" to "Solo styles" (or simply
"Styles") in the README text that currently reads "Edition styles are compiled
using Gulp/PostCSS..."; update the sentence to read "Solo styles are compiled
using Gulp/PostCSS..." so the theme name is correct in the documentation.
---
Nitpick comments:
In @.github/workflows/alto.yml:
- Around line 13-26: The test job named "test" is using default broad workflow
permissions; add explicit read-only permissions to harden the job by adding a
permissions block under the "test" job (permissions: contents: read) so the job
only has read access to repository contents while still checking out code and
running tests.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: c56014c0-19c1-4dde-96a4-9257c868d615
⛔ Files ignored due to path filters (2)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yamlyarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (69)
.github/workflows/alto.yml.github/workflows/bulletin.yml.github/workflows/dawn.yml.github/workflows/digest.yml.github/workflows/dope.yml.github/workflows/ease.yml.github/workflows/edge.yml.github/workflows/edition.yml.github/workflows/episode.yml.github/workflows/headline.yml.github/workflows/journal.yml.github/workflows/london.yml.github/workflows/ruby.yml.github/workflows/shared-theme-assets.yml.github/workflows/solo.yml.github/workflows/taste.yml.github/workflows/wave.ymlAGENTS.mdREADME.mdgulpfile.jspackage.jsonpackages/alto/README.mdpackages/alto/gulpfile.jspackages/alto/package.jsonpackages/bulletin/README.mdpackages/bulletin/gulpfile.jspackages/bulletin/package.jsonpackages/dawn/README.mdpackages/dawn/gulpfile.jspackages/dawn/package.jsonpackages/digest/README.mdpackages/digest/gulpfile.jspackages/digest/package.jsonpackages/dope/README.mdpackages/dope/gulpfile.jspackages/dope/package.jsonpackages/ease/README.mdpackages/ease/gulpfile.jspackages/ease/package.jsonpackages/edge/README.mdpackages/edge/gulpfile.jspackages/edge/package.jsonpackages/edition/README.mdpackages/edition/gulpfile.jspackages/edition/package.jsonpackages/episode/gulpfile.jspackages/episode/package.jsonpackages/headline/README.mdpackages/headline/gulpfile.jspackages/headline/package.jsonpackages/journal/README.mdpackages/journal/gulpfile.jspackages/journal/package.jsonpackages/london/README.mdpackages/london/gulpfile.jspackages/london/package.jsonpackages/ruby/README.mdpackages/ruby/gulpfile.jspackages/ruby/package.jsonpackages/solo/README.mdpackages/solo/gulpfile.jspackages/solo/package.jsonpackages/taste/gulpfile.jspackages/taste/package.jsonpackages/theme-translations/README.mdpackages/wave/README.mdpackages/wave/gulpfile.jspackages/wave/package.jsonpnpm-workspace.yaml
CodeRabbit review feedback on #529. The `pnpm/action-setup` digest copied from the sibling standalone theme repos (`ac6db6d`) no longer exists in `pnpm/action-setup` — GitHub returns 422 for it, so every workflow would have failed to resolve the action. Replaced with `0e279bb`, the verified digest behind the current `v6`/`v6.0.8` tag. Note the sibling theme repos still carry the dead pin and need the same fix. Also corrected a pre-existing copy-paste in the theme READMEs: London, Headline, Journal, Solo, and Wave described their styles as "Edition styles". CodeRabbit flagged London and Solo; the same fix is applied to all affected themes since this PR already touches those lines.
Standardises the Themes monorepo on pnpm, matching the standalone theme repos (Casper, Ease-Help, Edition-Changelog, ...) that already migrated, so contributors and CI agree on a single pinned package manager and lockfile format. The previous setup relied on unpinned yarn classic. - Pin pnpm via the root `packageManager` field so corepack and CI agree on a version, and mirror the pin into every theme package so the subtree-pushed standalone repos (e.g. `TryGhost/Alto`) are migrated too - Declare the workspace in `pnpm-workspace.yaml` with `linkWorkspacePackages: true` to mirror yarn workspaces behaviour: `@tryghost/shared-theme-assets@2.7.1` keeps resolving to the local `packages/_shared`, while `@tryghost/theme-translations@^0.0.9` keeps installing from the registry (verified identical to the yarn layout) - Classify the only flagged build script: `dtrace-provider` (optional bunyan bindings via gscan) is denied since themes never need it built - Add `glob` as an explicit root devDependency: the root gulpfile requires it but only resolved it through yarn hoisting, which pnpm's isolated `node_modules` correctly refuses - Swap all 17 workflows to digest-pinned `pnpm/action-setup` + `setup-node` with pnpm store caching and `--frozen-lockfile` installs; job structure, gating, and digests are otherwise untouched - Exclude `pnpm-debug.log`/`pnpm-lock.yaml` instead of `yarn-error.log` in every zip task, update README/AGENTS docs, and regenerate the lockfile as `pnpm-lock.yaml` (yarn.lock dropped) Remove the unused `concurrently` devDependency while here — nothing in the repo references it and it only generated pointless Renovate bumps.
Under yarn, `@tryghost/shared-theme-assets` was hoisted to the repo root, so the committed source maps referenced shared CSS four directories up (`../../../../node_modules/...`). pnpm links the package into each theme's own `node_modules`, so rebuilt maps now point two directories up (`../../node_modules/...`) — without committing this relocation, every `pnpm build` dirties 16 source maps in the working tree. The new paths also resolve correctly in the standalone subtree repos, which have no root-level `node_modules`; the old hoisted paths were broken there. The compiled CSS itself is byte-identical; only the maps change. Dope's `main.min.js` is content-identical too — gulp just normalises away a stray executable bit on the committed file.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
packages/ruby/pnpm-workspace.yaml (1)
1-5:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftSame per-package workspace configuration issue.
This file has the same issue as
packages/episode/pnpm-workspace.yaml- individual packages should not have their own workspace configuration files.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/ruby/pnpm-workspace.yaml` around lines 1 - 5, This package-level pnpm workspace config (the allowBuilds block containing dtrace-provider) should be removed and consolidated into the repository-wide pnpm-workspace.yaml; delete this file (packages/ruby/pnpm-workspace.yaml) and move any necessary entries (e.g. the allowBuilds -> dtrace-provider setting) into the root workspace config so only the root pnpm-workspace.yaml contains the allowBuilds configuration.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/episode/pnpm-workspace.yaml`:
- Around line 1-5: Keep the per-package pnpm-workspace.yaml files (do not remove
them); update the file that contains allowBuilds and the dtrace-provider entry
to include a brief comment stating these files exist to support
standalone/subtree installs (e.g., the Episode theme being deployed to
TryGhost/Episode) and explicitly note that workspace linking
(linkWorkspacePackages) and the monorepo-level packages: config only apply when
running pnpm from the monorepo root; reference the existing allowBuilds and
dtrace-provider keys so reviewers can find the exact file to edit.
---
Duplicate comments:
In `@packages/ruby/pnpm-workspace.yaml`:
- Around line 1-5: This package-level pnpm workspace config (the allowBuilds
block containing dtrace-provider) should be removed and consolidated into the
repository-wide pnpm-workspace.yaml; delete this file
(packages/ruby/pnpm-workspace.yaml) and move any necessary entries (e.g. the
allowBuilds -> dtrace-provider setting) into the root workspace config so only
the root pnpm-workspace.yaml contains the allowBuilds configuration.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 8eef6d35-3f9a-4bce-bf0e-d8ccca54c318
⛔ Files ignored due to path filters (19)
packages/alto/assets/built/screen.css.mapis excluded by!**/*.mappackages/bulletin/assets/built/screen.css.mapis excluded by!**/*.mappackages/dawn/assets/built/screen.css.mapis excluded by!**/*.mappackages/digest/assets/built/screen.css.mapis excluded by!**/*.mappackages/dope/assets/built/main.min.jsis excluded by!**/*.min.jspackages/dope/assets/built/screen.css.mapis excluded by!**/*.mappackages/ease/assets/built/screen.css.mapis excluded by!**/*.mappackages/edge/assets/built/screen.css.mapis excluded by!**/*.mappackages/edition/assets/built/screen.css.mapis excluded by!**/*.mappackages/episode/assets/built/screen.css.mapis excluded by!**/*.mappackages/headline/assets/built/screen.css.mapis excluded by!**/*.mappackages/journal/assets/built/screen.css.mapis excluded by!**/*.mappackages/london/assets/built/screen.css.mapis excluded by!**/*.mappackages/ruby/assets/built/screen.css.mapis excluded by!**/*.mappackages/solo/assets/built/screen.css.mapis excluded by!**/*.mappackages/taste/assets/built/screen.css.mapis excluded by!**/*.mappackages/wave/assets/built/screen.css.mapis excluded by!**/*.mappnpm-lock.yamlis excluded by!**/pnpm-lock.yamlyarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (85)
.github/workflows/alto.yml.github/workflows/bulletin.yml.github/workflows/dawn.yml.github/workflows/digest.yml.github/workflows/dope.yml.github/workflows/ease.yml.github/workflows/edge.yml.github/workflows/edition.yml.github/workflows/episode.yml.github/workflows/headline.yml.github/workflows/journal.yml.github/workflows/london.yml.github/workflows/ruby.yml.github/workflows/shared-theme-assets.yml.github/workflows/solo.yml.github/workflows/taste.yml.github/workflows/wave.ymlAGENTS.mdREADME.mdgulpfile.jspackage.jsonpackages/alto/README.mdpackages/alto/gulpfile.jspackages/alto/package.jsonpackages/alto/pnpm-workspace.yamlpackages/bulletin/README.mdpackages/bulletin/gulpfile.jspackages/bulletin/package.jsonpackages/bulletin/pnpm-workspace.yamlpackages/dawn/README.mdpackages/dawn/gulpfile.jspackages/dawn/package.jsonpackages/dawn/pnpm-workspace.yamlpackages/digest/README.mdpackages/digest/gulpfile.jspackages/digest/package.jsonpackages/digest/pnpm-workspace.yamlpackages/dope/README.mdpackages/dope/gulpfile.jspackages/dope/package.jsonpackages/dope/pnpm-workspace.yamlpackages/ease/README.mdpackages/ease/gulpfile.jspackages/ease/package.jsonpackages/ease/pnpm-workspace.yamlpackages/edge/README.mdpackages/edge/gulpfile.jspackages/edge/package.jsonpackages/edge/pnpm-workspace.yamlpackages/edition/README.mdpackages/edition/gulpfile.jspackages/edition/package.jsonpackages/edition/pnpm-workspace.yamlpackages/episode/gulpfile.jspackages/episode/package.jsonpackages/episode/pnpm-workspace.yamlpackages/headline/README.mdpackages/headline/gulpfile.jspackages/headline/package.jsonpackages/headline/pnpm-workspace.yamlpackages/journal/README.mdpackages/journal/gulpfile.jspackages/journal/package.jsonpackages/journal/pnpm-workspace.yamlpackages/london/README.mdpackages/london/gulpfile.jspackages/london/package.jsonpackages/london/pnpm-workspace.yamlpackages/ruby/README.mdpackages/ruby/gulpfile.jspackages/ruby/package.jsonpackages/ruby/pnpm-workspace.yamlpackages/solo/README.mdpackages/solo/gulpfile.jspackages/solo/package.jsonpackages/solo/pnpm-workspace.yamlpackages/taste/gulpfile.jspackages/taste/package.jsonpackages/taste/pnpm-workspace.yamlpackages/theme-translations/README.mdpackages/wave/README.mdpackages/wave/gulpfile.jspackages/wave/package.jsonpackages/wave/pnpm-workspace.yamlpnpm-workspace.yaml
✅ Files skipped from review due to trivial changes (39)
- packages/alto/pnpm-workspace.yaml
- packages/taste/pnpm-workspace.yaml
- packages/ease/pnpm-workspace.yaml
- packages/london/README.md
- packages/headline/pnpm-workspace.yaml
- packages/dope/pnpm-workspace.yaml
- packages/wave/pnpm-workspace.yaml
- packages/london/pnpm-workspace.yaml
- packages/journal/package.json
- packages/headline/package.json
- packages/bulletin/package.json
- packages/digest/package.json
- packages/theme-translations/README.md
- packages/ruby/package.json
- packages/dope/README.md
- packages/edition/gulpfile.js
- packages/solo/pnpm-workspace.yaml
- packages/bulletin/gulpfile.js
- packages/edition/package.json
- packages/dawn/package.json
- packages/bulletin/README.md
- packages/edge/pnpm-workspace.yaml
- packages/edge/package.json
- packages/headline/gulpfile.js
- packages/edition/pnpm-workspace.yaml
- packages/ruby/README.md
- packages/london/package.json
- packages/taste/gulpfile.js
- packages/ease/README.md
- packages/episode/package.json
- packages/alto/package.json
- packages/digest/README.md
- pnpm-workspace.yaml
- packages/alto/README.md
- packages/taste/package.json
- packages/wave/README.md
- packages/solo/README.md
- AGENTS.md
- packages/edge/README.md
🚧 Files skipped from review as they are similar to previous changes (20)
- packages/dope/gulpfile.js
- packages/ease/package.json
- packages/dawn/README.md
- packages/solo/gulpfile.js
- packages/wave/package.json
- gulpfile.js
- packages/edge/gulpfile.js
- packages/ruby/gulpfile.js
- packages/london/gulpfile.js
- packages/dope/package.json
- packages/ease/gulpfile.js
- packages/episode/gulpfile.js
- packages/dawn/gulpfile.js
- packages/solo/package.json
- packages/edition/README.md
- packages/digest/gulpfile.js
- packages/headline/README.md
- packages/wave/gulpfile.js
- .github/workflows/shared-theme-assets.yml
- README.md
The root `pnpm-workspace.yaml` carries the `dtrace-provider` build-script denial, but it does not propagate to the standalone repos that CI subtree-pushes from `packages/<theme>` (e.g. `TryGhost/Alto`). Those repos now pin pnpm via `packageManager`, so without a policy of their own, `pnpm install` in a standalone checkout exits non-zero with ERR_PNPM_IGNORED_BUILDS (verified in a clean simulation). Ship a settings-only `pnpm-workspace.yaml` inside each theme so the standalone repos install cleanly. pnpm ignores the nested files when installing from the monorepo root — verified that all 19 workspace projects still resolve and the lockfile is unchanged.
The pnpm/action-setup digest ac6db6d3c1f721f886538a378a2d73e85697340a no longer exists upstream — GitHub returns HTTP 422 for it — so any workflow job using it fails to resolve the action. Replaced it with 0e279bb959325dab635dd2c09392533439d90093, the verified digest behind the current v6/v6.0.8 tag. pnpm-workspace.yaml only carries development tooling (pnpm 11 build-script approvals) and does not belong in the installable theme zip, so it is now excluded alongside pnpm-lock.yaml in the gulp zip task. Found via review of TryGhost/Themes#529.
The pinned digest ac6db6d3c1f721f886538a378a2d73e85697340a no longer exists upstream — GitHub returns HTTP 422 for it, so any workflow job using pnpm/action-setup fails to resolve the action. Replaced it with 0e279bb959325dab635dd2c09392533439d90093, the verified digest behind the current v6/v6.0.8 tag. The installable zip was also checked: the zip script's explicit globs (assets/* *.hbs package.json) cannot include pnpm-workspace.yaml, so no zip change was needed. Discovered during the monorepo pnpm migration review in TryGhost/Themes#529.
The pnpm/action-setup digest ac6db6d3c1f721f886538a378a2d73e85697340a no longer exists upstream — GitHub returns HTTP 422 for it, so any workflow job using it fails to resolve the action. Replaced it with 0e279bb959325dab635dd2c09392533439d90093, the verified digest behind the current v6/v6.0.8 tag. Also excluded pnpm-workspace.yaml from the installable theme zip: it is development tooling (pnpm 11 build-script approvals), not theme content. Discovered during the TryGhost/Themes#529 pnpm migration review.
The pnpm/action-setup digest ac6db6d3c1f721f886538a378a2d73e85697340a no longer exists upstream (GitHub returns HTTP 422 for it), so every workflow job pinned to it fails to resolve the action. Replaced it with 0e279bb959325dab635dd2c09392533439d90093, the verified digest behind the current v6/v6.0.8 tag. Discovered during the monorepo pnpm migration in TryGhost/Themes#529. Also excluded pnpm-workspace.yaml from the theme zip: it only carries pnpm 11 build-script approvals (development tooling) and does not belong in the installable theme package.
The pnpm/action-setup digest ac6db6d3c1f721f886538a378a2d73e85697340a no longer exists upstream (GitHub returns HTTP 422 for it), so workflow jobs using it fail to resolve the action. Replaced it with 0e279bb959325dab635dd2c09392533439d90093, the verified digest behind the current v6/v6.0.8 tag, as discovered during the monorepo pnpm migration review in TryGhost/Themes#529. Also excluded pnpm-workspace.yaml from the theme zip: it only carries pnpm 11 build-script approvals (development tooling) and does not belong in the installable theme package.
The pnpm/action-setup digest ac6db6d3c1f721f886538a378a2d73e85697340a no longer exists upstream — GitHub returns HTTP 422 for it, so every workflow job using it fails to resolve the action. Replaced it with 0e279bb959325dab635dd2c09392533439d90093, the verified digest behind the current v6/v6.0.8 tag. This was discovered during the TryGhost/Themes pnpm migration, see TryGhost/Themes#529. Also excluded pnpm-workspace.yaml from the theme zip: it only carries pnpm 11 build-script approvals (development tooling) and doesn't belong in the installable theme package.
The pinned digest ac6db6d3c1f721f886538a378a2d73e85697340a no longer resolves as a commit upstream (GitHub returns HTTP 422), so every job using pnpm/action-setup fails at action resolution. It turned out to be the annotated tag object SHA of the v6 tag rather than a commit SHA, which GitHub Actions cannot resolve. Replaced it with 0e279bb959325dab635dd2c09392533439d90093, the verified commit the current v6/v6.0.8 tag points to. Discovered by CodeRabbit during the monorepo pnpm migration in TryGhost/Themes#529.
The ac6db6d3c1f721f886538a378a2d73e85697340a digest pinned for pnpm/action-setup no longer exists upstream — GitHub returns HTTP 422 for it, so every workflow job using it fails to resolve the action. Replaced it with 0e279bb959325dab635dd2c09392533439d90093, the verified digest behind the current v6/v6.0.8 tag. Also excluded pnpm-workspace.yaml from the theme zip: it only carries pnpm 11 build-script approvals (development tooling) and does not belong in the installable theme package. Refs TryGhost/Themes#529
The zip step's hard-coded exclude list covered yarn* and npm* but not pnpm*, so themes deployed from pnpm-based repos shipped pnpm-lock.yaml and pnpm-workspace.yaml to the live Ghost site (found via the pnpm migration in TryGhost/Themes#529, where all 16 demo-site deploys were affected). Added pnpm* to the default excludes. Preparing this fix surfaced that the build has been broken since Renovate bumped @actions/core, @actions/exec, and slug to ESM-only majors: the CommonJS source can no longer require() them, so ncc build fails and dist has not been rebuildable since February. Load the three packages via dynamic import() instead, keeping the source and dist CommonJS so the node20 runtime keeps executing the action as before. dist/ is intentionally not rebuilt in this commit; it must be regenerated with yarn build (which works again with this change) when the action is next shipped. Note ncc now also emits the dynamic imports as async chunk files next to dist/index.js — they are part of the build output and need to ship with it.
The zip step's hard-coded exclude list covered yarn* and npm* but not pnpm*, so themes deployed from pnpm-based repos shipped pnpm-lock.yaml and pnpm-workspace.yaml to the live Ghost site (found via the pnpm migration in TryGhost/Themes#529, where all 16 demo-site deploys were affected). Added pnpm* to the default excludes. Converting the source to TypeScript (it is a single small file) brings the repo in line with the standard GitHub Actions toolchain conventions and fixes the broken build at the root: the CommonJS source could no longer require() @actions/core, @actions/exec, or slug after Renovate bumped them to ESM-only majors, so ncc has been failing and dist has not been rebuildable since February. Static TypeScript imports let ncc bundle the ESM-only packages into the single CJS dist/index.js the node20 runtime executes — no dynamic-import workaround needed. Conventions applied alongside the conversion: - src/main.ts exports run(), src/index.ts is the entrypoint, matching the actions/typescript-action layout - Errors now report via core.setFailed instead of console.error + process.exit, and the success log uses core.info - The theme package.json is read with fs + JSON.parse instead of a runtime require() - Strict tsconfig, plugin:ghost/ts linting, and a typecheck script, all wired into the Test workflow next to lint and build - New check-dist workflow fails CI whenever the committed dist/ is not the build output of the current source — exactly the drift that let the build break unnoticed for months The pnpm* default zip exclude from the previous commit carries over to src/main.ts. dist/ is intentionally not rebuilt in this PR; check-dist stays red until dist is regenerated (yarn build) and committed when shipping.
Summary
Standardises the Themes monorepo on pnpm, matching the standalone theme repos (Casper, Ease-Help, Edition-Changelog, …) that were already migrated, so contributors and CI agree on a single pinned package manager and lockfile format. The previous setup relied on unpinned yarn classic.
Changes
packageManager: pnpm@11.5.1pinned at the root, and mirrored into all 16 theme packages so the subtree-pushed standalone repos (e.g.TryGhost/Alto) carry the pin too.pnpm-workspace.yamldeclarespackages/*withlinkWorkspacePackages: trueto mirror yarn workspaces behaviour:@tryghost/shared-theme-assets@2.7.1still resolves to the localpackages/_shared(symlink), while@tryghost/theme-translations@^0.0.9still installs0.0.9from the registry — verified identical to the previous yarn layout.dtrace-provider(optional bunyan native bindings, pulled in via gscan) was the only script pnpm 11 flagged; it's denied since themes never need it built.gulpfile.jsrequiresglobbut it was never declared — yarn hoisting masked it; pnpm's isolatednode_moduleswould break the build. Now an explicit root devDependency pinned to the previously-resolved13.0.6.shared-theme-assets.yml):- run: yarnreplaced with digest-pinnedpnpm/action-setup+actions/setup-node(pnpm store caching) andpnpm install --frozen-lockfile. Job structure, gating, and existing digests untouched;theme-translations.ymlis npm-only and unchanged.pnpm-debug.log/pnpm-lock.yamlinstead ofyarn-error.log.concurrentlyroot devDependency (nothing references it; it only generated Renovate bumps like Update dependency concurrently to v10.0.3 #525).Verification
pnpm install— clean install on pnpm 11.5.1, no build-script errorspnpm test:ci --theme altoand--theme london— no fatal Ghost 6.x compatibility issuespnpm zip --theme alto— produceddist/alto.zip; contents excludenode_modulesand lockfilepnpm build— fullbuildAllacross all themes succeeds (exercises theglobfix andmergeLocales); rebuiltassets/built/*noise restored so the diff stays scoped to the migrationnpm testinpackages/theme-translations— all tests passpnpm-lock.yaml