npm icon indicating copy to clipboard operation
npm copied to clipboard

Having `npm` as a dependency does not always gurantee that required version of `npm` is used

Open 34j opened this issue 1 month ago • 4 comments

https://github.com/semantic-release/npm/blob/14c1fc8b7626d0f4e4875fa93664ebca4068757b/package.json#L31

https://github.com/semantic-release/npm/blob/14c1fc8b7626d0f4e4875fa93664ebca4068757b/lib/publish.js#L23-L27

Since npm publish is executed via execa, if @semantic-release/npm is not installed via npx, the npm installed as a dependency may not necessarily be used as described in: https://github.com/semantic-release/semantic-release/pull/3913 https://github.com/semantic-release/semantic-release/pull/3920. Therefore, I suggest checking the npm version at runtime.

I see you have semantic-release and plugins under devDependencies and installing with pnpm, which might be complicating things. Please try removing from devDependencies and just use npx to both install and run

34j avatar Oct 27 '25 05:10 34j

i'd like to get this closer to being in a state of it "just works", but i dont think the situation is quite how you describe it. the key detail about our use of execa, as you've linked to, is our use of preferLocal. the purpose of this flag is to intentionally use the locally installed version (relative to the executable being run. in this context, the semantic-release binary) rather than the one available in the environment from a machine installation. the reason we install npm as a dependency of the npm plugin for semantic-release and execute with the preferLocal flag is specifically to avoid inconsistencies from various machine installed versions of npm.

the only pattern i've been able to sort of put together for where this doesnt work as intended is when folks install semantic-release as a direct (dev) dependency, and therefore the transitive dependency of the npm plugin and npm itself, locally with pnpm. even when installed locally with npm, rather than globally with npx or npm, we have not seen the problem reported as a problem.

looking more closely at the docs of the preferLocal flag, i see that preferLocal expects the binary to be in the node_modules/.bin/ directory of the project, which is an npm convention. i am not a user of pnpm, so i'm not as familiar with it. does it maybe not follow the convention of making binaries from packages available in that location? could that be why we see this problem sometimes with pnpm users?

travi avatar Oct 31 '25 20:10 travi

related, which seems to confirm the theory about being a quirk about how pnpm exposes binaries: https://github.com/sindresorhus/execa/issues/1204

travi avatar Oct 31 '25 20:10 travi

Therefore, I suggest checking the npm version at runtime.

i'm not sure how we'd even be able to reliably check this at runtime due to the way this behavior surfaces. the closest i can think of is to run npm --version in the same way we are executing the other npm commands. i think i instead lean in the direction of detecting that semantic-release was locally installed with pnpm and warning about that, or similar.

i almost lean toward this simply being a way we expand our docs to specifically suggest avoiding local installation with pnpm. that is already covered by the idea of further encouraging global installation through npx, but this could at least be listed as one of the specific reasons for that recommendation. runtime errors can often be more visible documentation that actual documentation though 🤔

open to further thoughts on this

travi avatar Oct 31 '25 20:10 travi

Thank you for your response. I didn't realize there was such a complicated background to this. However, some kind of runtime suggestion would be helpful, as I spent a considerable amount of time debugging when I encountered this issue (different npm versions being used) (without knowing the recommendation).

34j avatar Nov 01 '25 03:11 34j