Skip to content

fix: set user agent in headless lifecycle scripts#12092

Merged
zkochan merged 1 commit into
pnpm:mainfrom
morning-verlu:codex/fix-lifecycle-user-agent
Jun 1, 2026
Merged

fix: set user agent in headless lifecycle scripts#12092
zkochan merged 1 commit into
pnpm:mainfrom
morning-verlu:codex/fix-lifecycle-user-agent

Conversation

@morning-verlu

@morning-verlu morning-verlu commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Fixes #12003.

What changed

  • Pass the configured user agent into root lifecycle scripts during headless installs.
  • Add a regression test for the lockfile-only then install path from the issue.
  • Add a patch changeset for @pnpm/installing.deps-restorer and pnpm.

This is in the TypeScript headless lifecycle options path. I did not make a pacquet change because pacquet is not assembling these root lifecycle script options.

Validation

  • pnpm install completed; optional fuse-native native build printed spawn node-gyp ENOENT, but install exited 0.
  • cargo build -p pnpr-fixtures --bin pnpr-prepare
  • env PATH=/tmp/pnpm-codex-bin:$PATH pnpm --filter pnpm test test/install/lifecycleScripts.ts -t "correct user agent"
  • env PATH=/tmp/pnpm-codex-bin:$PATH git push -u origin codex/fix-lifecycle-user-agent ran the repo pre-push checks successfully.
  • git diff --check

Summary by CodeRabbit

  • Bug Fixes
    • Fixed an issue where the npm_config_user_agent environment variable was not being properly passed to lifecycle scripts during headless installations, ensuring scripts have proper context about the package manager being used.

@morning-verlu morning-verlu requested a review from zkochan as a code owner June 1, 2026 00:37
@welcome

welcome Bot commented Jun 1, 2026

Copy link
Copy Markdown

💖 Thanks for opening this pull request! 💖
Please be patient and we will get back to you as soon as we can.

@coderabbitai

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 41fb55b7-c851-49dd-9fa7-c63e80504672

📥 Commits

Reviewing files that changed from the base of the PR and between 54d2b57 and a1971ba.

📒 Files selected for processing (3)
  • .changeset/lucky-user-agent.md
  • installing/deps-restorer/src/index.ts
  • pnpm/test/install/lifecycleScripts.ts
📜 Recent 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). (2)
  • GitHub Check: Analyze (javascript)
  • GitHub Check: Compile & Lint
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Follow Standard Style with trailing commas, preferring functions over classes, and declaring functions after they are used (relying on hoisting)
Use a single options object instead of multiple parameters when a function needs more than two or three arguments
Follow Import Order: Standard libraries first, then external dependencies (alphabetically), then relative imports
Write self-documenting code where function names, parameters, and types explain what a function does without requiring prose comments
Do not write comments that restate what the code already says; refactor via renaming, splitting helpers, or restructuring instead
Do not repeat documentation at call sites that already exists in JSDoc on the callee; update JSDoc once for all call sites to benefit
Use JSDoc only for a function's contract (preconditions, postconditions, edge cases, why the function exists), not for re-narrating the body
Do not record past implementation shape, refactor history, or 'the previous code did X' framing in code; use git log and git blame instead
Write comments only when: the reason for code is non-obvious (hidden invariant, workaround for known bug, deliberate exception), or the right name doesn't fit (temporary technical constraint)

Files:

  • pnpm/test/install/lifecycleScripts.ts
  • installing/deps-restorer/src/index.ts
🧠 Learnings (3)
📚 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/lucky-user-agent.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:

  • pnpm/test/install/lifecycleScripts.ts
  • installing/deps-restorer/src/index.ts
📚 Learning: 2026-05-24T08:18:00.622Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11895
File: pnpm/test/deploy.ts:91-95
Timestamp: 2026-05-24T08:18:00.622Z
Learning: In pnpm/pnpm integration tests that intentionally hit the real npm registry (registry.npmjs.org)—for example when the test passes `--config.registry=https://registry.npmjs.org/` to `execPnpm` and simply increases the timeout—do not request adding a runtime environment-variable gate (e.g., `PNPM_RUN_PUBLIC_REGISTRY_TESTS`). This is the established pattern for those tests (see files like `pnpm/test/install/pacquet.ts` and `pnpm/test/deploy.ts`).

Applied to files:

  • pnpm/test/install/lifecycleScripts.ts
🔇 Additional comments (3)
installing/deps-restorer/src/index.ts (1)

236-251: LGTM!

pnpm/test/install/lifecycleScripts.ts (1)

43-62: LGTM!

.changeset/lucky-user-agent.md (1)

1-6: LGTM!


📝 Walkthrough

Walkthrough

This PR fixes a regression where npm_config_user_agent was undefined during lifecycle script execution when the lockfile already existed. The implementation adds a single line to pass the user agent into script options during headless installs, validated by a new test, and documented for release.

Changes

User Agent Environment Variable for Lifecycle Scripts

Layer / File(s) Summary
User agent propagation in headless installs
installing/deps-restorer/src/index.ts, pnpm/test/install/lifecycleScripts.ts, .changeset/lucky-user-agent.md
headlessInstall now passes opts.userAgent into scriptsOpts so lifecycle scripts can access npm_config_user_agent. A test confirms the environment variable is correctly set during headless installs with an up-to-date lockfile. Patch version bumps for @pnpm/installing.deps-restorer and pnpm document the fix.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested reviewers

  • zkochan

Poem

🐰 A user agent hops back into view,
Through headless scripts, now it comes through,
One line makes the lifecycle sing,
No more undefined—what a thing! 🌟

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main fix: setting user agent in headless lifecycle scripts, which is the core issue being addressed.
Linked Issues check ✅ Passed All coding requirements from #12003 are met: user agent is passed to lifecycle scripts, the regression test covers the lockfile-only then install scenario, and the changeset documents the behavior change.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing the user agent in headless lifecycle scripts as specified in #12003; no extraneous modifications detected.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


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.

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Review Summary by Qodo

Set user agent in headless lifecycle scripts

🐞 Bug fix

Grey Divider

Walkthroughs

Description
• Pass configured user agent to root lifecycle scripts during headless installs
• Add regression test for lockfile-only then install path
• Update @pnpm/installing.deps-restorer and pnpm packages
Diagram
flowchart LR
  A["HeadlessOptions"] -- "userAgent parameter" --> B["Root Lifecycle Scripts"]
  B -- "npm_config_user_agent env var" --> C["Preinstall Hook Execution"]
  D["Lockfile-only Install"] -- "followed by" --> E["Full Install"]
  E -- "triggers headless path" --> C

Loading

Grey Divider

File Changes

1. installing/deps-restorer/src/index.ts 🐞 Bug fix +1/-0

Pass user agent to lifecycle script options

• Added userAgent field to root lifecycle script options object
• Passes configured user agent from opts.userAgent to lifecycle execution context

installing/deps-restorer/src/index.ts


2. pnpm/test/install/lifecycleScripts.ts 🧪 Tests +21/-0

Add headless install user agent regression test

• Added new test case for headless install user agent propagation
• Test creates workspace with optimisticRepeatInstall enabled
• Executes lockfile-only install followed by full install
• Verifies npm_config_user_agent environment variable is set correctly

pnpm/test/install/lifecycleScripts.ts


3. .changeset/lucky-user-agent.md 📝 Documentation +6/-0

Add changeset for user agent fix

• New changeset documenting patch version bumps
• Covers @pnpm/installing.deps-restorer and pnpm packages
• Describes fix for npm_config_user_agent in root lifecycle scripts

.changeset/lucky-user-agent.md


Grey Divider

Qodo Logo

@zkochan zkochan merged commit 118e9be into pnpm:main Jun 1, 2026
10 checks passed
@welcome

welcome Bot commented Jun 1, 2026

Copy link
Copy Markdown

Congrats on merging your first pull request! 🎉🎉🎉

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.

Pnpm doesn't set npm_config_user_agent if lockfile is already up to date

2 participants