0

So I've read the doc at npm upgrade#caret dependencies. But npm upgrade does not seem to work for me. It is possible this has something to do with github packages. The package that fails to update is a package in our internal github packages repo.

And here is my package.json

{ 
  <snip>
 "devDependencies": {
    "@1uphealth/build-lifecycle-scripts": "^0.0.0",
    "@types/jest": "^25.2.2",
    "jest": "^26.0.1",
  },
  "dependencies": {}
}

But asking for an upgrade does nothing.

% npm ls --depth=0                                            
@1uphealth/core-example-lib@0.0.0
├── @1uphealth/build-lifecycle-scripts@0.0.0
├── @types/jest@25.2.3
└── jest@26.1.0

% npm upgrade --only=dev
<nothing happens>                                     
% npm upgrade --only=dev @1uphealth/build-lifecycle-scripts
<nothing happens>

But, an explicit install of the 0.0.1 version works fine...

% npm install '@1uphealth/build-lifecycle-scripts@^0.0.1'
+ @1uphealth/build-lifecycle-scripts@0.0.1
updated 1 package and audited 585 packages in 3.514s
<snip>
% npm ls --depth=0                               
@1uphealth/core-example-lib@0.0.0 /Users/marvin/git/internal/components/0.x/core-example-lib
├── @1uphealth/build-lifecycle-scripts@0.0.1
├── @types/jest@25.2.3
└── jest@26.1.0

Here is my .npmrc

@1uphealth:registry=https://npm.pkg.github.com/1uphealth

So should npm update be updating this install? Does this seem like something broken in github packages repository implementation? Or, am I doing something wrong?

Marvin
  • 2,537
  • 24
  • 35

1 Answers1

2

OK. So reading more closely, the documentation at npm-semver for caret ranges explains this. I had read that page but thought that the basic rules about "major", "minor", "patch" were something that I just understood -- major versions are breaking chnages, minor versions are compatible additions to the API, and patch are fixes/changes that don't affect the API. But this sentence

Allows changes that do not modify the left-most non-zero digit in the [major, minor, patch] tuple

explains that it is more subtle. The basic result is that for 0 major-versions, the minor version is considered a breaking change. So while ^1.0.0 will allow (be satisfied by) 1.1.0 and ^2.0.0 will allow 2.1.0, ^0.0.0 will actually not allow ANYTHING else, and '^0.1.0' will allow only ^0.1.[0-9]*.

Essentially (mostly) the minor version "becomes" the major version. So the rationale is that for 0 major versions, many releases will be breaking changes and this allows that to be done without forcing a 1.x release (which suggests a certain maturity of the component that may not be warranted.)

Marvin
  • 2,537
  • 24
  • 35