patch-package icon indicating copy to clipboard operation
patch-package copied to clipboard

New patch fails with private registries (RFC)

Open sterlingwes opened this issue 3 years ago • 5 comments

We've been noticing an issue sporadically with writing new patches and having a private NPM registry. I can reproduce the issue reliably, and I can fix it locally, but I'm not sure what the underlying cause is here. Hoping someone can provide guidance on a better fix for this. If there isn't I'm happy to PR my proposal below.

Reproducing the issue

have a yarn repo with an .npmrc in it as follows:

registry=https://my-private-registry-host.example/repository/npm
always-auth=true

and an ~/.npmrc as follows:

//my-private-registry-host.example/repository/npm/:_auth="myNPMauthTOKEN"

pick any package in node_modules that has not had a patch written for it before and run yarn patch-package the-package:

▶ yarn patch-package yazl
yarn run v1.22.4
$ /path/to/repo/node_modules/.bin/patch-package the-package
patch-package 6.4.7+cd069d4b
• Creating temporary folder
• Installing [email protected] with yarn
warning package.json: No license field
warning No license field
error An unexpected error occurred: "https://my-private-registry-host.example/repository/npm/the-package/-/the-package-2.5.1.tgz: Request failed \"401 Unauthorized\"".

<<...some garbage output (console.log of some buffers it seems)...>>

If I add some more logs ahead of the yarn install that patch-package does, the output seems to make sense:

# ls -la in the tmpRepoPath
# the copied .npmrc is as noted above for the project one
total 16
drwx------    4 me  staff    128 19 May 16:07 .
drwx------@ 478 me  staff  15296 19 May 16:07 ..
-rw-r--r--    1 me  staff     75 19 May 16:07 .npmrc
-rw-r--r--    1 me  staff    454 19 May 16:07 package.json

# cat package.json in the tmpRepoPath
{"dependencies":{"the-package":"https://my-private-registry-host.example/repository/npm/the-package/-/the-package-2.5.1.tgz#a3d65d3dd659a5b0937850e8609f22fffa2b5c35"},"resolutions":{...}}

The Fix

I can fix the 401 by adding --registry https://my-private-registry-host.example/repository/npm to the yarn install command that patch-package builds. It's not clear why this resolves it, but I assume it has something to do with scoped auth tokens (in my $HOME/.npmrc).

Proposal

I propose making a change to allow passthrough flags that allow me to specify the registry I want to build the patch against.

In this case I'd run yarn patch-package the-package --registry https://my-private-registry-host.example/repository/npm and patch-package would add that flag to the install command.

I'd love to find a better fix for this but the underlying cause escapes me.

▶ yarn --version
1.22.4

sterlingwes avatar May 19 '21 20:05 sterlingwes

I can fix the 401 by adding --registry https://my-private-registry-host.example/repository/npm to the yarn install

Could you provide the full workaround here?

Psidium avatar Aug 12 '21 21:08 Psidium

@Psidium Did you manage it to work?

othonrm avatar Aug 20 '21 18:08 othonrm

@Psidium try adding the --registry argument to this file patch-package/dist/makePatch.js

try {
     // try first without ignoring scripts in case they are required
     // this works in 99.99% of cases
-   spawnSafe_1.spawnSafeSync(`yarn`, ["install", "--ignore-engines"], {
+                spawnSafe_1.spawnSafeSync(`yarn`, ["install", "--ignore-engines", "--registry https://my-private-registry-host.example.com"], {
                     cwd: tmpRepoNpmRoot,
                     logStdErrOnError: false,
                 });

parichay28 avatar Sep 10 '21 05:09 parichay28

npx patch-package package-name instead of the yarn command works well as a workaround

escapedcat avatar Oct 04 '21 08:10 escapedcat

May a better solution is to copy .npmrc than hardcode url to makePatch.js.

Here a quick hard fix for .npmrc. The idea is to add .npmrc file to env var. Should be similar for .yarnrc.

Create file : patches/patch-package+6.4.7.patch

diff --git a/node_modules/patch-package/dist/makePatch.js b/node_modules/patch-package/dist/makePatch.js
index 985589e..fd24a9a 100644
--- a/node_modules/patch-package/dist/makePatch.js
+++ b/node_modules/patch-package/dist/makePatch.js
@@ -83,6 +83,15 @@ function makePatch({ packagePathSpecifier, appPath, packageManager, includePaths
             }
         }
         else {
+            // @TODO: check if .yarnrc can be treated as .npmrc. If yes move to [".npmrc", ".yarnrc"].forEach((rcFile) => { 
+            // @TODO: check if this configuration via env:{ } and spawnSafeSync options is okay
+            const npmrcEnv = { env: {} }
+            const rcFile = '.npmrc'
+            const rcPath = path_1.join(appPath, rcFile);
+            if (fs_extra_1.existsSync(rcPath)) {
+                npmrcEnv.env.npm_config_userconfig = `${tmpRepo.name}${rcFile}`
+            }
+
             console.info(chalk_1.default.grey("•"), `Installing ${packageDetails.name}@${packageVersion} with npm`);
             try {
                 // try first without ignoring scripts in case they are required
@@ -91,6 +100,7 @@ function makePatch({ packagePathSpecifier, appPath, packageManager, includePaths
                     cwd: tmpRepoNpmRoot,
                     logStdErrOnError: false,
                     stdio: "ignore",
+                    ...npmrcEnv,
                 });
             }
             catch (e) {
@@ -99,6 +109,7 @@ function makePatch({ packagePathSpecifier, appPath, packageManager, includePaths
                 spawnSafe_1.spawnSafeSync(`npm`, ["i", "--ignore-scripts", "--force"], {
                     cwd: tmpRepoNpmRoot,
                     stdio: "ignore",
+                    ...npmrcEnv,
                 });
             }
         }

Thanks for this life saver lib guys !

florent-andre avatar Oct 08 '21 12:10 florent-andre