Skip to content

[rush] Preserve pnpm credential environment variables on POSIX - #6040

Open
Mike DelGaudio (mikedelgaudio) wants to merge 2 commits into
microsoft:mainfrom
mikedelgaudio:fix/pnpm-posix-credential-environment
Open

Mike DelGaudio (mikedelgaudio) wants to merge 2 commits into
microsoft:mainfrom
mikedelgaudio:fix/pnpm-posix-credential-environment

Conversation

@mikedelgaudio

Copy link
Copy Markdown
Contributor

Summary

Fix missing pnpm registry authentication on POSIX when provideNpmrcCredentialsViaEnvironment is enabled.

Follow-up to #5995: Rush creates URL-scoped npm_config_* credential variables, but passing them through /bin/sh can discard them before pnpm starts. On Linux with dash, a clean install using pnpm 10.34.5 fails with ERR_PNPM_FETCH_401 and no Authorization header.

Details

  • Add an internal useShell execution option, defaulting to existing shell behavior.
  • Opt package-manager launches out of the POSIX shell only when the existing credential-environment experiment/version gate applies. Pass the executable and original argument array directly to the child process.
  • Cover workspace installs, legacy installs, autoinstaller installation/update, and rush-pnpm.
  • Preserve Windows shell handling for .cmd shims, default behavior for other callers, output handling, retries, and exit-code capture.
  • Keep credentials in the child environment; do not introduce credential files or shell overrides.
  • Include the Rush patch release note.

How it was tested

Revalidated the unchanged patch on macOS with Node 22.21.1:

  • rush --quiet test --only @microsoft/rush-lib --include-phase-deps --parallelism 4: 931 tests passed, zero failures.
  • Six new real-subprocess regressions cover generated credential preservation, the install retry execution path, literal POSIX arguments, exit-code capture, failure rejection, and unchanged default shell execution.
  • Whole-suite Rush-library coverage: 63.89% lines and 77.87% branches (not changed-lines coverage).
  • rush change --verify --target-branch origin/main, Prettier checking all changed files, and git diff --check origin/main...HEAD passed.

Prior Linux validation of this exact patch, recorded in the implementation handoff:

  • Linux/dash with Node 22.16.0: the same Rush-library command passed all 931 tests.
  • Manual clean authenticated-registry comparison with pnpm 10.34.5, isolated HOME/package stores, an empty user npm config, and synthetic credentials: released Rush 5.179.0 failed with 401; patched Rush installed successfully without writing the resolved token to generated config.
  • Patched rush-pnpm outdated and autoinstaller update authenticated successfully.

The manual Linux registry reproduction was not rerun on macOS. Windows was not executed locally; its existing shell path is unchanged and the POSIX-only argument test is skipped on Windows. Full legacy-install and cold autoinstaller-install integrations were not separately exercised.

Bypass the shell for package-manager invocations when the npmrc credential environment experiment is active. Preserve Windows command shims and default shell behavior for other callers.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 88399e18-c0da-4cfc-af47-6673b1cc1545
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 88399e18-c0da-4cfc-af47-6673b1cc1545
"changes": [
{
"packageName": "@microsoft/rush",
"comment": "Fix pnpm registry credentials being dropped by POSIX shells when provideNpmrcCredentialsViaEnvironment is enabled.",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
"comment": "Fix pnpm registry credentials being dropped by POSIX shells when provideNpmrcCredentialsViaEnvironment is enabled.",
"comment": "Fix pnpm registry credentials being dropped by POSIX shells when `provideNpmrcCredentialsViaEnvironment` is enabled.",

let environment: NodeJS.ProcessEnv;

beforeAll(async () => {
directory = await fs.promises.mkdtemp(`${os.tmpdir()}/rush credentials `);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Don't use os.tempdir. We want to keep all writes in deterministic places.

// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.

import * as fs from 'node:fs';

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Use FileSystem from node-core-library.

Comment on lines +43 to +48
await fs.promises.mkdir(sourceFolder);
await fs.promises.mkdir(targetFolder);
await fs.promises.writeFile(
`${sourceFolder}/.npmrc`,
'//registry.example.test/npm/:_authToken=${RUSH_TEST_TOKEN}\n'
);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

FileSystem.writeFile has an option to ensure the folder exists.

);
});

(IS_WINDOWS ? it.skip : it)(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ensure the cache key for this project's tests takes the OS into account.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Needs triage

Development

Successfully merging this pull request may close these issues.

3 participants