Skip to content

Fixed pack.js and Dockerfile references to deleted .npmrc#28205

Merged
9larsons merged 1 commit into
mainfrom
fix/pnpm-11-dockerfile-npmrc
May 27, 2026
Merged

Fixed pack.js and Dockerfile references to deleted .npmrc#28205
9larsons merged 1 commit into
mainfrom
fix/pnpm-11-dockerfile-npmrc

Conversation

@9larsons
Copy link
Copy Markdown
Contributor

@9larsons 9larsons commented May 27, 2026

Hotfix for #28197. Five distinct release-pipeline files broke after the .npmrc deletion, but the deeper story is that .npmrc was also carrying frozen-lockfile=false, which was silently absorbing several pnpm-deploy-vs-lockfile mismatches under pnpm 10. pnpm 11 ignores .npmrc for that directive, so the mismatches surface.

What was broken

  • Dockerfile.production:28 — production image builds. COPY fails on missing source.
  • docker/ghost-dev/Dockerfile:21 — devcontainer + local dev. Already failed on main: run 26525156893.
  • ghost/core/scripts/pack.js:124 — read root .npmrc to build the published Ghost tarball; would throw on next release.
  • pack.jspnpm pack of @tryghost/i18n/etc. needs pnpm-workspace.yaml in scope (pnpm 11 strict-validates catalog: refs); pack.js wrote it AFTER the pack loop.
  • pack.js — the shipped tarball's pnpm-workspace.yaml carried overrides + packageExtensions verbatim from root, but pnpm deploy's generated lockfile doesn't record them (they're already applied to the resolved package.json). pnpm 11's frozen-lockfile install (CI=true default for ghost-cli) failed ERR_PNPM_LOCKFILE_CONFIG_MISMATCH.
  • pack.js — after the existing peer-suffix-stripping and component-file: rewriting on the deployed package.json, the deploy lockfile no longer matched. Under pnpm 10 this was masked by frozen-lockfile=false in .npmrc; pnpm 11 fails ERR_PNPM_OUTDATED_LOCKFILE.
  • pack.jsminimumReleaseAge policy in the shipped workspace.yaml 404'd on the private component tarballs and failed install inside Dockerfile.production.

What changed

  • Dockerfiles — removed .npmrc from the COPY line in both. Single-token edit per file.
  • pack.js — stop reading the deleted root .npmrc.
  • pack.js — copy pnpm-workspace.yaml BEFORE the pack loop (so workspace catalog: refs resolve for pnpm pack of components).
  • pack.js — ship a trimmed pnpm-workspace.yaml carrying only catalog, catalogs, allowBuilds, strictDepBuilds (the things end-user installs need). Drop overrides, packageExtensions, packages, supply-chain policies. Explicitly set minimumReleaseAge: 0 since the published tarball is itself a release artifact and the policy 404s on private component tarballs.
  • pack.js — regenerate the deploy lockfile inside the deploy dir with pnpm install --lockfile-only after package.json post-processing, so the shipped tarball is internally consistent under pnpm 11's strict checks.
  • enforce-package-manager.js — re-applies the comment softening from the Updated pnpm to 11.4.0 #28197 review (lost to a rebase autostash on my end).

Verification

End-to-end through the full release pipeline, locally, with CI=true to match production install behavior:

Step Result
pnpm archive (in ghost/core/) ✅ tarball 34.3 MiB, lockfile regenerated, deploy workspace.yaml trimmed
docker build --target core -t … . (from extracted tarball) ✅ image builds, deps install cleanly
CI=true ghost install local --archive … ✅ "Ghost was installed successfully!"

How this slipped through #28197

Two layers of cause:

  1. I checked .npmrc references at the start of Updated pnpm to 11.4.0 #28197 and noted the two Dockerfile COPY lines and pack.js's read, but didn't follow through with edits when I deleted the file. Should have grepped post-delete as a final sweep.
  2. I tested ghost-cli install locally WITHOUT CI=true, which silently reconciled the lockfile mismatches via the default frozen-lockfile=false. CI runs with CI=truefrozen-lockfile=true → strict check tripped. Adding CI=true to my local verification checklist for any release-pipeline change.

And a third: Build & Publish Artifacts (which runs pnpm archive) was failing on #28197's CI but the merge gate didn't see it because that job wasn't in job_required_tests.needs. Fixed separately in #28206.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 27, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3e6f1631-eaff-4655-a5e8-6a79202a0a81

📥 Commits

Reviewing files that changed from the base of the PR and between 6ce05f3 and 7331fbf.

📒 Files selected for processing (4)
  • .github/scripts/enforce-package-manager.js
  • Dockerfile.production
  • docker/ghost-dev/Dockerfile
  • ghost/core/scripts/pack.js
✅ Files skipped from review due to trivial changes (3)
  • docker/ghost-dev/Dockerfile
  • .github/scripts/enforce-package-manager.js
  • Dockerfile.production
🚧 Files skipped from review as they are similar to previous changes (1)
  • ghost/core/scripts/pack.js

Walkthrough

This PR clarifies pnpm detection comments in the CI enforcement script, removes copying the root .npmrc from Docker pre-install COPY steps (production and dev) so only package.json, pnpm-lock.yaml, and pnpm-workspace.yaml are used for installs, and updates ghost/core/scripts/pack.js to import js-yaml, emit a trimmed deploy pnpm-workspace.yaml, avoid writing pnpm.overrides into the packaged package.json, regenerate the deploy lockfile, and require pnpm-workspace.yaml (with a non-empty default catalog), pnpm-lock.yaml, and package.json in deploy output.

Possibly related PRs

  • TryGhost/Ghost#28197: Related change to .github/scripts/enforce-package-manager.js pnpm detection fallback logic.
  • TryGhost/Ghost#28080: Related Dockerfile.production changes that restructure files copied before pnpm install.
  • TryGhost/Ghost#27879: Related changes to ghost/core/scripts/pack.js packaging flow and deploy artifact contents.

Suggested reviewers

  • EvanHahn
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and accurately describes the main change: fixing pack.js and Dockerfile references to the deleted .npmrc file.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, explaining what was broken, what changed, and including verification details.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/pnpm-11-dockerfile-npmrc

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@9larsons 9larsons force-pushed the fix/pnpm-11-dockerfile-npmrc branch from f26407d to 39400ce Compare May 27, 2026 16:52
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
ghost/core/scripts/pack.js (1)

131-131: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update log message to reflect write operation instead of copy.

The message says "Copied .npmrc" but line 125 uses writeFileSync to write the file directly rather than copying it. The message should say "Wrote .npmrc" or "Wrote .npmrc and copied pnpm-workspace.yaml" to accurately describe what the code does.

📝 Suggested fix for log message accuracy
-console.log('Copied .npmrc (with frozen-lockfile=false) and pnpm-workspace.yaml');
+console.log('Wrote .npmrc (with frozen-lockfile=false) and copied pnpm-workspace.yaml');
🤖 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 `@ghost/core/scripts/pack.js` at line 131, The console log message inaccurately
says "Copied .npmrc" even though the file is created via writeFileSync; update
the log in the pack.js console.log call to reflect a write operation (e.g.,
"Wrote .npmrc (with frozen-lockfile=false) and copied pnpm-workspace.yaml").
Locate the writeFileSync usage that writes .npmrc and the console.log statement
and change the text to mention "Wrote .npmrc" while still noting that
pnpm-workspace.yaml was copied.
🤖 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.

Outside diff comments:
In `@ghost/core/scripts/pack.js`:
- Line 131: The console log message inaccurately says "Copied .npmrc" even
though the file is created via writeFileSync; update the log in the pack.js
console.log call to reflect a write operation (e.g., "Wrote .npmrc (with
frozen-lockfile=false) and copied pnpm-workspace.yaml"). Locate the
writeFileSync usage that writes .npmrc and the console.log statement and change
the text to mention "Wrote .npmrc" while still noting that pnpm-workspace.yaml
was copied.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c2e92ea0-c8d6-4f86-8baf-5afde2891190

📥 Commits

Reviewing files that changed from the base of the PR and between b5852fd and 39400ce.

📒 Files selected for processing (4)
  • .github/scripts/enforce-package-manager.js
  • Dockerfile.production
  • docker/ghost-dev/Dockerfile
  • ghost/core/scripts/pack.js

@9larsons 9larsons force-pushed the fix/pnpm-11-dockerfile-npmrc branch from 39400ce to 25a37ec Compare May 27, 2026 17:00
@9larsons 9larsons changed the title Fixed Dockerfile COPY referencing deleted .npmrc Fixed pack.js and Dockerfile references to deleted .npmrc May 27, 2026
@9larsons 9larsons enabled auto-merge (squash) May 27, 2026 17:08
@codecov
Copy link
Copy Markdown

codecov Bot commented May 27, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 73.88%. Comparing base (b5852fd) to head (7331fbf).
⚠️ Report is 4 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #28205      +/-   ##
==========================================
- Coverage   73.88%   73.88%   -0.01%     
==========================================
  Files        1531     1531              
  Lines      129865   129873       +8     
  Branches    15585    15586       +1     
==========================================
+ Hits        95956    95961       +5     
- Misses      32946    32949       +3     
  Partials      963      963              
Flag Coverage Δ
admin-tests 54.17% <ø> (ø)
e2e-tests 73.88% <ø> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@9larsons 9larsons disabled auto-merge May 27, 2026 17:58
@9larsons 9larsons force-pushed the fix/pnpm-11-dockerfile-npmrc branch 2 times, most recently from bf012ce to 6ce05f3 Compare May 27, 2026 18:04
The pnpm 11 upgrade in #28197 deleted the root .npmrc, which removed
both a file reference (broke Docker COPY) and the `frozen-lockfile=false`
directive that had been silently absorbing several lockfile/workspace
mismatches in published-tarball installs (pnpm 11 ignores .npmrc keys
other than auth/registry, so it couldn't carry the directive anyway).

Five distinct issues across the release pipeline:

1. `Dockerfile.production` and `docker/ghost-dev/Dockerfile` listed
   .npmrc in their COPY directives. Docker fails on missing sources —
   devcontainer image build went red on first push to main.

2. `pack.js` read root .npmrc to build the published tarball. Would
   throw on the next `pnpm archive` / release.

3. pnpm 11 strict-validates `catalog:` refs in workspace package.jsons,
   so `pnpm pack` of @tryghost/i18n etc. needs pnpm-workspace.yaml in
   scope. pack.js wrote it AFTER the pack loop. Reordered to write it
   first.

4. The packaged pnpm-workspace.yaml shipped overrides + packageExtensions
   verbatim from root, but `pnpm deploy` generates a lockfile that
   doesn't record them (they're already applied to the resolved
   package.json). pnpm 11's frozen-lockfile install (CI=true default for
   ghost-cli) compares config to lockfile as raw strings and fails
   ERR_PNPM_LOCKFILE_CONFIG_MISMATCH. Solution: pack.js writes a
   trimmed workspace.yaml carrying only catalog/catalogs/allowBuilds/
   strictDepBuilds — the things end-user installs actually need.

5. After pack.js's package.json post-processing (strip peer suffixes,
   rewrite file: refs to component tarballs), the deploy lockfile no
   longer matched. Under pnpm 10 this was masked by frozen-lockfile=false
   in the shipped .npmrc. Solution: pack.js regenerates the lockfile
   inside the deploy dir with `pnpm install --lockfile-only` so the
   shipped tarball is internally consistent.

Also re-applies the comment softening from the #28197 review of
.github/scripts/enforce-package-manager.js (was lost to a rebase
autostash on my end before merge).
@9larsons 9larsons force-pushed the fix/pnpm-11-dockerfile-npmrc branch from 6ce05f3 to 7331fbf Compare May 27, 2026 18:10
@9larsons 9larsons enabled auto-merge (squash) May 27, 2026 18:17
@9larsons 9larsons merged commit 5b6eba0 into main May 27, 2026
54 checks passed
@9larsons 9larsons deleted the fix/pnpm-11-dockerfile-npmrc branch May 27, 2026 18:32
9larsons added a commit that referenced this pull request May 27, 2026
refs #28197, #28205. 

This fixes the `ghost-dev` compose for pnpm 11.

The dev Dockerfile (`docker/ghost-dev/Dockerfile`) only stages
`ghost/{core,i18n,parse-email-address}` `package.json`s at build time.
Compose then mounts `./ghost` into the container at runtime, which
exposes `ghost/admin`'s `workspace:*` deps (e.g.
`@tryghost/admin-x-framework` → lives in `apps/admin-x-framework/`).
pnpm 10 was lenient about the missing workspace packages; pnpm 11
strict-validates the workspace graph and `pnpm dev` fails instead of
being tolerated.
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