fix(publish): forward strictSsl to libnpmpublish so self-signed registries work#12396
Conversation
…tries work `pnpm publish` was ignoring `strictSsl: false` from `.npmrc` / `pnpm-workspace.yaml` because `createPublishOptions` never included `strictSSL` in the options object passed to `libnpmpublish`. `npm-registry-fetch` (used internally by `libnpmpublish`) defaults `strictSSL` to `true`, so the flag had to be forwarded explicitly. Fixes #12012. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
📝 WalkthroughWalkthrough
ChangesstrictSsl forwarding fix for pnpm publish
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~3 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 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. 🔧 ESLint
ESLint install timed out. The project may have too many dependencies for the sandbox. 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. Comment |
Code Review by Qodo
Context used 1. Weak strictSSL absence test
|
PR Summary by QodoFix publish to honor strictSsl for self-signed registries WalkthroughsDescription• Forward strictSsl to libnpmpublish as strictSSL so publish respects .npmrc/workspace config. • Prevent publish failures/timeouts against registries using self-signed certificates. • Add unit coverage to ensure strictSSL is set only when configured. Diagramgraph TD
A["pnpm publish"] --> B["createPublishOptions()"] --> C{{"libnpmpublish"}} --> D{{"npm-registry-fetch"}} --> E{{"Registry (self-signed)"}}
F["Config strictSsl"] --> B
High-Level AssessmentForwarding File ChangesBug fix (1)
Tests (1)
Documentation (1)
|
There was a problem hiding this comment.
🧹 Nitpick comments (1)
releasing/commands/test/publish/publishConfigAccess.test.ts (1)
35-51: 💤 Low valueConsider adding a test case for
strictSsl: trueto complete the coverage.The two tests correctly verify the critical cases (
falseforwarding and omitted behavior). For symmetry with theaccesstest suite below (which covers multiple scenarios) and to ensure explicittrueis also forwarded correctly, consider adding:test('forwards strictSsl: true as strictSSL to npm-registry-fetch', async () => { const opts = await createPublishOptions( { name: 'pkg', version: '1.0.0' }, { ...baseOpts(), strictSsl: true } ) expect(opts.strictSSL).toBe(true) })This is optional since the default is already
trueand the issue was specifically aboutfalsenot being honored.🤖 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 `@releasing/commands/test/publish/publishConfigAccess.test.ts` around lines 35 - 51, Add a third test case to the createPublishOptions: strictSSL describe block to verify that strictSsl: true is correctly forwarded as strictSSL: true to npm-registry-fetch. This test should follow the same pattern as the existing test for strictSsl: false, using the same createPublishOptions call structure and verifying that opts.strictSSL equals true. This ensures complete coverage for all three scenarios (true, false, and undefined) and maintains consistency with similar test suites in the file.
🤖 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.
Nitpick comments:
In `@releasing/commands/test/publish/publishConfigAccess.test.ts`:
- Around line 35-51: Add a third test case to the createPublishOptions:
strictSSL describe block to verify that strictSsl: true is correctly forwarded
as strictSSL: true to npm-registry-fetch. This test should follow the same
pattern as the existing test for strictSsl: false, using the same
createPublishOptions call structure and verifying that opts.strictSSL equals
true. This ensures complete coverage for all three scenarios (true, false, and
undefined) and maintains consistency with similar test suites in the file.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 13c923cc-32df-4e37-b77d-039213ea2bcd
📒 Files selected for processing (3)
.changeset/fix-publish-strict-ssl.mdreleasing/commands/src/publish/publishPackedPkg.tsreleasing/commands/test/publish/publishConfigAccess.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: ubuntu-latest / Node.js 24 / Test
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use Standard Style with trailing commas, prefer functions over classes, declare functions after they are used relying on hoisting, limit function arguments to two or three with options objects for additional parameters
Follow import order: standard libraries, external dependencies (sorted alphabetically), then relative imports
Use JSDoc for function contracts (preconditions, postconditions, edge cases, why it exists) not for re-narrating the body; do not record past implementation shape or refactor history in comments
Files:
releasing/commands/src/publish/publishPackedPkg.tsreleasing/commands/test/publish/publishConfigAccess.test.ts
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
When checking if a caught error is an Error object in Jest, use util.types.isNativeError() instead of instanceof Error because instanceof checks can fail across VM realms
Files:
releasing/commands/test/publish/publishConfigAccess.test.ts
🧠 Learnings (4)
📚 Learning: 2026-05-26T21:01:06.666Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11966
File: .changeset/require-tarball-integrity.md:6-6
Timestamp: 2026-05-26T21:01:06.666Z
Learning: In pnpm lockfile-related release notes/docs (especially changeset markdown), preserve URL hostnames exactly as they appear in pnpm-lock.yaml tarball resolution entries—keep hosts like `codeload.github.com`, `bitbucket.org`, and `gitlab.com` in lowercase. Do not “correct” them to title-case/preserve brand capitalization (e.g., LanguageTool rules like `GITHUB` capitalization) because these are literal URL fragments, not platform brand names.
Applied to files:
.changeset/fix-publish-strict-ssl.md
📚 Learning: 2026-05-14T09:04:00.133Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11622
File: resolving/npm-resolver/test/publishedBy.test.ts:350-354
Timestamp: 2026-05-14T09:04:00.133Z
Learning: In the pnpm/pnpm repository, ESLint is the authoritative style linter. Do not raise review findings for missing trailing commas in multiline function calls (e.g., `fs.writeFileSync(...)`) when this repo’s ESLint configuration does not report them and lint passes. Prefer deferring to the ESLint results for this specific trailing-comma rule rather than enforcing it manually in code review.
Applied to files:
releasing/commands/src/publish/publishPackedPkg.tsreleasing/commands/test/publish/publishConfigAccess.test.ts
📚 Learning: 2026-06-05T13:47:26.046Z
Learnt from: vsumner
Repo: pnpm/pnpm PR: 12190
File: installing/deps-installer/src/install/index.ts:2337-2343
Timestamp: 2026-06-05T13:47:26.046Z
Learning: In the pnpm/pnpm codebase, `PnpmError` automatically prefixes `err.code` with `ERR_PNPM_` when you pass a code that does not already start with `ERR_PNPM_` (it normalizes `this.code` via `code.startsWith('ERR_PNPM_') ? code : `ERR_PNPM_${code}``). Therefore, during code review you should NOT flag `new PnpmError(...)` call sites for passing a bare error code (e.g., `new PnpmError('FROZEN_STORE_INCOMPATIBLE_WITH_PNPR', ...)`); the resulting `err.code` will still be `ERR_PNPM_FROZEN_STORE_INCOMPATIBLE_WITH_PNPR`.
Applied to files:
releasing/commands/src/publish/publishPackedPkg.tsreleasing/commands/test/publish/publishConfigAccess.test.ts
📚 Learning: 2026-06-05T13:47:05.929Z
Learnt from: vsumner
Repo: pnpm/pnpm PR: 12190
File: installing/deps-installer/test/install/frozenStore.ts:2-17
Timestamp: 2026-06-05T13:47:05.929Z
Learning: In the pnpm/pnpm repository, the shared Jest preset keeps `injectGlobals` at its default (`true`), so `test` and `expect` are available as Jest globals. Therefore, reviewers should not flag (or treat as TypeScript/compilation errors) missing `import { test, expect } from 'jest/globals'` when a test file uses `test`/`expect` without importing them. Importing from `jest/globals` may still be used for consistency with sibling files, but it is not required for execution in this repo unless a Jest preset is explicitly configured with `injectGlobals: false`.
Applied to files:
releasing/commands/test/publish/publishConfigAccess.test.ts
🔇 Additional comments (2)
releasing/commands/src/publish/publishPackedPkg.ts (1)
163-163: LGTM!.changeset/fix-publish-strict-ssl.md (1)
1-6: LGTM!
Summary
pnpm publishwas silently ignoringstrict-ssl=false(from.npmrc) andstrictSsl: false(frompnpm-workspace.yaml) when publishing to registries that use self-signed certificates, causing aUNABLE_TO_VERIFY_LEAF_SIGNATUREerror after a long timeout.createPublishOptionsinpublishPackedPkg.tsnever includedstrictSSLin the options object forwarded tolibnpmpublish. Sincenpm-registry-fetch(used internally bylibnpmpublish) defaultsstrictSSLtotrue, the option had to be passed explicitly.options.strictSsl → strictSSLinpublishOptions, matching the same behaviour that already works forpnpm install.Test plan
publishConfigAccess.test.tsverify thatstrictSsl: falsemaps tostrictSSL: falsein the publish options object, and thatstrictSSLis absent whenstrictSslis not set.Fixes pnpm/pnpm#12012.
Written by an agent (Claude Code, claude-sonnet-4-6).
Summary by CodeRabbit
Bug Fixes
pnpm publishto respectstrictSsl: falseconfiguration for registries with self-signed certificates.Tests