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

[BUG] npm install does not include pre-release when determining version to install #7851

Open
2 tasks done
johnwc opened this issue Oct 17, 2024 · 19 comments
Open
2 tasks done
Labels
Bug thing that needs fixing Needs Triage needs review for next steps

Comments

@johnwc
Copy link

johnwc commented Oct 17, 2024

Is there an existing issue for this?

  • I have searched the existing issues

This issue exists in the latest npm version

  • I am using the latest npm

Current Behavior

When installing via npm install our-library@">4.2.0-beta", npm does not find any version to install. It ignores any pre-release version unless you specify the exact pre-release version. Same with npm outdated, it does show that there is a new pre-release version available in the Latest column, but Wanted column is always current installed pre-release version. I have tried using >4.2.0-beta, ^4.2.0-beta, and ~4.2.0-beta. None will cause the outdated to show the new pre-release as wanted.

Expected Behavior

With the use of >4.2.0-beta, outdated and install should consider pre-release versions. Or add a command line switch to enable looking for pre-release versions.

Steps To Reproduce

Installing

  1. Build library that has pre-release version 1.0.1-beta-123 and publish it to npm repo.
  2. Try to install using >1.0.0-beta

Updating

  1. Build library that has pre-release version 1.0.1-beta-123 and publish it to npm repo.
  2. Install using @^1.0.1-beta-123
  3. Build new pre-release version 1.0.2-beta-456 and publish it to npm repo.
  4. Run npm outdated. Wanted shows 1.0.1-beta-123, Latest shows 1.0.2-beta-456

Environment

  • npm: 10.9.0
  • Node.js: v21.7.3
  • OS Name: Windows 11
  • npm config:
@johnwc johnwc added Bug thing that needs fixing Needs Triage needs review for next steps labels Oct 17, 2024
@ljharb
Copy link
Contributor

ljharb commented Oct 17, 2024

This is by design, in all versions of npm. If you want prereleases included, the range has to explicitly include them, at each level.

@johnwc
Copy link
Author

johnwc commented Oct 17, 2024

@ljharb this bug report is pointing out that the range does not work at all for pre-release.

@ljharb
Copy link
Contributor

ljharb commented Oct 17, 2024

beta-123 and beta-456 are incompatible prerelease categories. Perhaps you want beta.123 and beta.456?

@johnwc
Copy link
Author

johnwc commented Oct 17, 2024

I have tried all different types of formats. I just changed it to using a dash instead of period to test if it would work. And why are stating it is incompatible, it adheres to semver formatting.

image

@johnwc
Copy link
Author

johnwc commented Oct 17, 2024

Also this, doesn't seem to accept the range.

> npm install our-library@">4.2.32-beta.ge8343d1e"

npm error code ETARGET
npm error notarget No matching version found for our-library@>4.2.32-beta.ge8343d1e.
npm error notarget In most cases you or one of your dependencies are requesting
npm error notarget a package version that doesn't exist.

@ljharb
Copy link
Contributor

ljharb commented Oct 17, 2024

It's certainly valid - i just meant that they're two completely different buckets. In that latter example, use ^ instead of >, and i'd expect it to work.

@johnwc
Copy link
Author

johnwc commented Oct 17, 2024

It installs with ^ but it does not find any later pre-releases upon running the outdated command. The pre-release is stuck as Wanted, and the newer pre-release is in Latest. There is no way to update your pre-release installed version using npm update. You have to manually run install again with the new pre-release version.

@ljharb
Copy link
Contributor

ljharb commented Oct 17, 2024

hm, i wonder if that's because the part after the dot isn't numeric?

@johnwc
Copy link
Author

johnwc commented Oct 17, 2024

Should the value after the dot even come into play yet, as the patch number is already higher in the newer pre-release

Example

>npm install our-library@^4.2.29-beta.g8c00b605
npm warn deprecated @npmcli/move-file@1.1.2: This functionality has been moved to @npmcli/fs
npm warn deprecated @npmcli/move-file@2.0.1: This functionality has been moved to @npmcli/fs

added 5 packages, and audited 1427 packages in 9s

162 packages are looking for funding
  run `npm fund` for details

25 vulnerabilities (2 low, 8 moderate, 11 high, 4 critical)

To address all issues, run:
  npm audit fix

Run `npm audit` for details.

>npm outdated our-library
Package                    Current                 Wanted                Latest  Location                       Depended by
our-library  4.2.29-beta.g8c00b605  4.2.29-beta.g8c00b605  4.2.37-beta-439e0756  node_modules/our-library       project

>npm update our-library
npm warn deprecated @npmcli/move-file@1.1.2: This functionality has been moved to @npmcli/fs
npm warn deprecated @npmcli/move-file@2.0.1: This functionality has been moved to @npmcli/fs

up to date, audited 1427 packages in 6s

162 packages are looking for funding
  run `npm fund` for details

27 vulnerabilities (2 low, 9 moderate, 12 high, 4 critical)

To address all issues, run:
  npm audit fix

Run `npm audit` for details.

@ljharb
Copy link
Contributor

ljharb commented Oct 17, 2024

oh! i missed that. prereleases are for a specific version triple. your range there can only ever match prereleases for v4.2.32. Prereleases for a higher version need their own explicit range.

@ljharb
Copy link
Contributor

ljharb commented Oct 17, 2024

In other words, typically people only make prereleases for a new major version, because that way ^X.0.0-0 can cover all of them for a given X.

@johnwc
Copy link
Author

johnwc commented Oct 17, 2024

That may be true and valid for public pre-releases, but for internal teams working off of shared libraries in repos, our patch versions increase with each build. The part after the period is just the commit hash of git.

How can we get a feature added then to have a command line switch or a setting in packages.json to allow upgrading pre-releases like normal releases?

@ljharb
Copy link
Contributor

ljharb commented Oct 17, 2024

The commit hash seems like something that would go in the build signifier (+), which npm doesn't support and actively strips.

Is there a reason you can't just use normal patch versions?

@johnwc
Copy link
Author

johnwc commented Oct 17, 2024

We are using patch version, as you can see that the patch version increments on each build 4.2.29-beta -> 4.2.37-beta

@ljharb
Copy link
Contributor

ljharb commented Oct 17, 2024

Sorry, i meant, non-prerelease patch versions. Like, just 4.2.29 and 4.2.37. Then you'd get all the semver ranges you want.

Prereleases are meant for one-off testing, not for parallel release lines.

@johnwc
Copy link
Author

johnwc commented Oct 17, 2024

That is a difference of opinion. Pre-release build is just that, a release that is not stable, not one-off tests. They are versions of the code that can be used while development is going on. Especially for large projects that have different libraries.

@ljharb
Copy link
Contributor

ljharb commented Oct 17, 2024

I mean, given the way npm has implemented semver and ranges forever, it's a bit more concrete than opinion. It's not going to work for what you want, unfortunately.

@johnwc
Copy link
Author

johnwc commented Oct 18, 2024

Ok, it is a npm opinion, but that should not force it upon everyone. npm is merely a package manager, it should not dictate a team's way of versioning when the team is perfectly aligned with the versioning scheme the package manager is supposed to conform to. Plus, if you go to npm documentation, they literally point you to an example search interface that explains how to select based on pre-release ranges... Why would it not work the way most folks would expect it to work, and most all other package managers work? Not asking to rewrite it, I am asking for an opt-in way of enabling it to work.

Also, just because something is always done a certain way doesn't mean change can't be made for improvement. Otherwise, we would still be writing in assembly...

@shadowspawn
Copy link
Contributor

shadowspawn commented Oct 22, 2024

The special prerelease behaviour is surprising the first time you hit it when expecting a different behaviour.

There is extensive coverage in the semver README which explains the behaviour and the rationale: https://github.com/npm/node-semver#prerelease-tags

(@ljharb touched on the key issues above, but the README lays it out nicely.)

You might get most of what you want by not updating the patch version with every build? Conventionally 4.2.32-beta.ge8343d1e is a pre-release build of 4.2.32. What "release" are you heading towards? You can include a build number in the prerelease information like: 4.2.32-beta.1.ge8343d1e, or treating the hash as meta information: 4.2.32-beta.1+ge8343d1e

The underlying semver package supports a includePrerelease flag which is what you asked for, but as far as I can see that is not exposed by the npm CLI configuration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug thing that needs fixing Needs Triage needs review for next steps
Projects
None yet
Development

No branches or pull requests

3 participants