Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pinst suggestion for Yarn Berry no longer works with newer NPM versions #1491

Open
1 task done
blimmer opened this issue Aug 7, 2024 · 1 comment
Open
1 task done

Comments

@blimmer
Copy link
Contributor

blimmer commented Aug 7, 2024

Troubleshoot

Context

Currently, the docs recommend using this set of scripts for Yarn Berry (2+):

{
  "scripts": {
    // Yarn doesn't support prepare script
    "postinstall": "husky",
    // Include this if publishing to npmjs.com
    "prepack": "pinst --disable",
    "postpack": "pinst --enable"
  }
}

However, this no longer works. There are some details in typicode/pinst#23. The TLDR is that newer versions of NPM seem not to respect what's actually in the published tarball. Instead, they have some kind of database they reference where the postinstall -> _postinstall rename no longer works.

I wrote up a simple example here: https://github.com/blimmer/husky-npm-prepare-issue

You can see that this has started failing somewhere in the Node 20.x / NPM 10.x line:

Screenshot 2024-08-07 at 11 02 44

You can see that the rename of postinstall -> _postinstall isn't recorded in the npm view output:

> npm view @blimmer/husky-npm-prepare-issue@latest scripts
{
  postinstall: 'husky',
  prepack: 'pinst --disable',
  postpack: 'pinst --enable'
}

Even though the tarball actually shows the rename:

> npm install --ignore-scripts @blimmer/husky-npm-prepare-issue@latest
> cat node_modules/@blimmer/husky-npm-prepare-issue/package.json

{
  "name": "@blimmer/husky-npm-prepare-issue",
  "publishConfig": {
    "access": "public"
  },
  "version": "2.0.4",
  "bin": {
    "husky-npm-prepare-issue": "./bin.js"
  },
  "scripts": {
    "_postinstall": "husky",
    "prepack": "pinst --disable",
    "postpack": "pinst --enable"
  },
  "keywords": [],
  "license": "ISC",
  "devDependencies": {
    "husky": "^9.1.4",
    "pinst": "^3.0.0"
  }
}

This issue is described here: https://gist.github.com/djcsdy/2f5a287b3ba16f2a8f0312f45588e6ce and relates to the higher-level NPM issue described here: https://blog.vlt.sh/blog/the-massive-hole-in-the-npm-ecosystem

Really, it would be nice if Yarn would just support some script that runs locally when running yarn install (e.g., prepare) - see also yarnpkg/berry#2967

Because this is fundamentally broken right now, I wanted to post on the husky issue tracker for visibility.

Workaround

On my end, I worked around this with the following changes:

  1. Remove all calls to pinst from scripts in package.json.

  2. Update my semantic-release config to run yarn pinst --disable instead:

    module.exports = {
      branches: ["main"],
      plugins: [
    	// !! This is what I added !!
        [
          "@semantic-release/exec",
          {
            prepareCmd: "yarn pinst --disable && yarn build",
          }
        ],
        [
          "@semantic-release/commit-analyzer",
          {
            preset: "conventionalcommits"
          }
        ],
        "@semantic-release/release-notes-generator",
        "@semantic-release/npm",
        "@semantic-release/github"
      ]
    };

If you're publishing from CI and not using semantic-release, you could add the call to pinst --disable in your workflow. You just can't seem to have it tied to an NPM lifecycle anymore.

Discoverability

If you see output like this, you're running into this issue (adding for discoverability in the issue tracker):

> npx --verbose my-package
npm info run my-package postinstall node_modules/my-package husky
npm info run my-package postinstall { code: 127, signal: null }

> npm install --save-dev my-package
npm error code 127
npm error path /private/tmp/foo/node_modules/my-package
npm error command failed
npm error command sh -c husky
npm error sh: husky: command not found
npm error A complete log of this run can be found in: /Users/blimmer/.npm/_logs/2024-08-07T17_16_17_181Z-debug-0.log
@djcsdy
Copy link

djcsdy commented Dec 20, 2024

It should be noted that "prepack": "pinst --disable" never worked as intended. It always results in wrong information going into the npm database. It's just that most tools ignored the wrong information, including npm before npm v10.4.0. Explanation here: https://gist.github.com/djcsdy/3ca078e23fdac4c50e077c84e8284a95

A lot of projects are starting to get hit by this problem:

I assume this is just the tip of the iceberg. EVERY historical package that has been published using pinst in the recommended configuration is broken and cannot be installed correctly by npm >= 10.4. This problem is NOT limited to packages that were published recently.

I am seeing a lot of confusion about the underlying cause, which is not really surprising.

I think the only responsible course of action is to immediately stop recommending that developers use pinst in their prepack and postpack scripts since this results in broken packages and always has done.

Unfortunately the only safe way I know of to run pinst is to run it BEFORE yarn publish. There's no safe way I know of to cause yarn publish to run pinst --disable automatically. It's unfortunate that the solution is so unergonomic, but the only alternative is many broken packages.

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

No branches or pull requests

2 participants