berry: [Bug] It's unclear when postinstall script runs

We have this root package.json:

{
  "name": "@company/our-packages",
  "private": true,
  "workspaces": [
    "*"
  ],
  "scripts": {
    "postinstall": "bash postinstall-script.sh"
  }
}

The postinstall script used to run in Yarn 2.2 but after upgrading to v2.4, it doesn’t and we’re getting this warning instead:

➤ YN0006: │ @company/our-packages@workspace:. lists build scripts, but is referenced through a soft link. Soft links don’t support build scripts, so they’ll be ignored.

I came to ask on Discord but still quite don’t know what the expected behavior is – for example, @larixer suggested that the first install should invoke the postinstall but subsequent ones should trigger the warning.

So I tried building a Sherlock repro which expects the YN0006 error produced but the “bug” is that it doesn’t:

UPDATE: better repro posted in https://github.com/yarnpkg/berry/issues/2209#issuecomment-738335690.

Reproduction

Playground

const installPromise = packageJsonAndInstall({
"name": "@company/our-packages",
"private": true,
"workspaces": [
    "*"
],
"scripts": {
    "postinstall": "echo running postinstall..."
}
});

const output = await installPromise;
// it was suggested by @larixer that the first run shouldn't produce YN0006:
expect(output).not.toContain('YN0006');
expect(output).toContain('workspace:. must be built because it never did before or the last one failed');

const output2 = await yarn('install');
expect(output2).toContain('YN0006');
expect(output2).not.toContain('workspace:. must be built because it never did before or the last one failed');

Output:

Error: expect(received).toContain(expected) // indexOf

Expected substring: "YN0006"
Received string:    "➤ YN0000: ┌ Resolution step
➤ YN0000: └ Completed
➤ YN0000: ┌ Fetch step
➤ YN0000: └ Completed
➤ YN0000: ┌ Link step
➤ YN0000: └ Completed
➤ YN0000: Done in 0s 76ms
"
at module.exports (evalmachine.<anonymous>:19:17)
at process._tickCallback (internal/process/next_tick.js:68:7)

Why I believe YN0006 should be produced:

  • Workspace root is a “soft link” package (linkType: soft in yarn.lock)
  • The warning says “Soft links don’t support build scripts, so they’ll be ignored.”
  • The docs of YN0006 also confirm that: “Since Yarn avoids doing anything unsafe, it cannot run build scripts on soft links.”

It is a bit strange that I see YN0006 in my real project but not in the Sherlock repro – it might be a mistake of that setup but I can’t spot it yet. In any case, I’d like to understand when postinstall script runs (or doesn’t) as it’s pretty important for our project.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 16 (9 by maintainers)

Most upvoted comments

Workspaces are special. Soft links aren’t built because Yarn is presumed not being the owner of the target location (as in, it isn’t allowed to generate files there), but in the case of workspaces it’s prefectly safe since they are, by definition, the project itself. So in their case they are allowed to run build scripts, per the same rules as other packages (ie their build scripts only run if any package within their dependency tree changed).

“Workspaces are special” - does this mean that there is a bug in yarn reporting this as an error in a workspaced environment? Would we envision in the future that postinstall scripts are fine for workspaced projects using nodeLinker: node-modules?

@arcanis per what you wrote:

Workspaces are special. Soft links aren’t built because Yarn is presumed not being the owner of the target location (as in, it isn’t allowed to generate files there), but in the case of workspaces it’s prefectly safe since they are, by definition, the project itself. So in their case they are allowed to run build scripts, per the same rules as other packages (ie their build scripts only run if any package within their dependency tree changed).

a soft linked workspace should run postinstall scripts but the behaviour I am seeing with 2.4 is contradictory.

workspace-root@workspace:. lists build scripts, but is referenced through a soft link. Soft links don't support build scripts, so they'll be ignored

The script is ignored with the above message

I checked the provided repro and the postinstall does run on 2.4 but it also prints a warning. What’s happening is that the node-modules linker sees a package with a postinstall that is also a SOFT link so it prints the warning and skips the build for it, then the core comes along and runs builds on all workspaces either way. The warning getting printed for workspaces was fixed in https://github.com/yarnpkg/berry/pull/2491

which due to this bug means lifecycle scripts are completely unusable

They’re still run by the core, you just see a warning from the node-modules linker.