npm / npm

This repository is moving to: https://github.com/npm/cli

Home Page:http://npm.community

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

"npm publish" tags pre-versions as "latest"

scott113341 opened this issue · comments

I'm opening this issue because:

  • npm is crashing.
  • npm is producing an incorrect install.
  • npm is doing something I don't understand.
  • Other (see below for feature requests):

What's going wrong?

Running npm version premajor && npm publish will tag the premajor version as latest by default. I confirmed this happens when running all pre-release options: premajor | preminor | prepatch | prerelease.

(I was not able to verify the behavior resulting from the from-git option due to an error: Error: Version not changed, /Users/scott/.nvm/versions/node/v6.2.2/lib/node_modules/npm/lib/version.js:92:47. This happened when my most recent commit's tag was set to vX.0.0-0, vX.0.0, X.0.0-0, and X.0.0, where X was a version number that was greater than all other previous versions. This may be a separate issue, or I was doing something wrong.)

As @iarna pointed out in #10189, there are valid reasons that authors would want to tag pre-release versions as latest. However, I think that this is not good default behavior (though it is documented: "Publishing a package sets the latest tag to the published version unless the --tag option is used. For example, npm publish --tag=beta.")

Semver documentation states:

A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version. Examples: 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92.

Source: http://semver.org/#spec-item-9

I propose that the latest tag only be set if the version to be published is not a pre-release version. I am happy to do the work on this and submit a PR, but I'd like to first discuss and get approval before putting the time in.

Thank you for your hard work on npm!

How can the CLI team reproduce the problem?

From https://www.npmjs.com/package/@scott113341/testo

testo|master ⇒ node -v && npm -v && npm info @scott113341/testo | grep latest && npm version premajor -ddd && npm publish -ddd && npm info @scott113341/testo | grep latest
v6.2.2
3.10.3
  'dist-tags': { latest: '3.0.0-0' },
npm info it worked if it ends with ok
npm verb cli [ '/Users/scott/.nvm/versions/node/v6.2.2/bin/node',
npm verb cli   '/Users/scott/.nvm/versions/node/v6.2.2/bin/npm',
npm verb cli   'version',
npm verb cli   'premajor',
npm verb cli   '-ddd' ]
npm info using npm@3.10.3
npm info using node@v6.2.2
npm info git [ 'status', '--porcelain' ]
npm info lifecycle @scott113341/testo@4.0.0-0~preversion: @scott113341/testo@4.0.0-0
npm sill lifecycle @scott113341/testo@4.0.0-0~preversion: no script for preversion, continuing
npm verb version.write data { name: '@scott113341/testo',
npm verb version.write   version: '4.0.0-0',
npm verb version.write   description: '',
npm verb version.write   main: 'index.js',
npm verb version.write   scripts: { test: 'echo "Error: no test specified" && exit 1' },
npm verb version.write   author: '',
npm verb version.write   license: 'ISC' } to package.json
v4.0.0-0
npm info lifecycle @scott113341/testo@4.0.0-0~version: @scott113341/testo@4.0.0-0
npm sill lifecycle @scott113341/testo@4.0.0-0~version: no script for version, continuing
npm info git [ 'add', '/Users/scott/Documents/sites/testo/package.json' ]
npm info git [ 'commit', '-m', '4.0.0-0' ]
npm info git [ 'tag', 'v4.0.0-0', '-am', '4.0.0-0' ]
npm info lifecycle @scott113341/testo@4.0.0-0~postversion: @scott113341/testo@4.0.0-0
npm sill lifecycle @scott113341/testo@4.0.0-0~postversion: no script for postversion, continuing
npm verb exit [ 0, true ]
npm info ok 
npm info it worked if it ends with ok
npm verb cli [ '/Users/scott/.nvm/versions/node/v6.2.2/bin/node',
npm verb cli   '/Users/scott/.nvm/versions/node/v6.2.2/bin/npm',
npm verb cli   'publish',
npm verb cli   '-ddd' ]
npm info using npm@3.10.3
npm info using node@v6.2.2
npm verb publish [ '.' ]
npm sill cache add args [ '.', null ]
npm verb cache add spec .
npm sill cache add parsed spec Result {
npm sill cache add   raw: '.',
npm sill cache add   scope: null,
npm sill cache add   escapedName: null,
npm sill cache add   name: null,
npm sill cache add   rawSpec: '.',
npm sill cache add   spec: '/Users/scott/Documents/sites/testo',
npm sill cache add   type: 'directory' }
npm verb addLocalDirectory /Users/scott/.npm/@scott113341/testo/4.0.0-0/package.tgz not in flight; packing
npm verb correctMkdir /Users/scott/.npm correctMkdir not in flight; initializing
npm info lifecycle @scott113341/testo@4.0.0-0~prepublish: @scott113341/testo@4.0.0-0
npm sill lifecycle @scott113341/testo@4.0.0-0~prepublish: no script for prepublish, continuing
npm verb tar pack [ '/Users/scott/.npm/@scott113341/testo/4.0.0-0/package.tgz',
npm verb tar pack   '/Users/scott/Documents/sites/testo' ]
npm verb tarball /Users/scott/.npm/@scott113341/testo/4.0.0-0/package.tgz
npm verb folder /Users/scott/Documents/sites/testo
npm verb addLocalTarball adding from inside cache /Users/scott/.npm/@scott113341/testo/4.0.0-0/package.tgz
npm verb correctMkdir /Users/scott/.npm correctMkdir not in flight; initializing
npm sill cache afterAdd @scott113341/testo@4.0.0-0
npm verb afterAdd /Users/scott/.npm/@scott113341/testo/4.0.0-0/package/package.json not in flight; writing
npm verb correctMkdir /Users/scott/.npm correctMkdir not in flight; initializing
npm verb afterAdd /Users/scott/.npm/@scott113341/testo/4.0.0-0/package/package.json written
npm sill publish { name: '@scott113341/testo',
npm sill publish   version: '4.0.0-0',
npm sill publish   description: '',
npm sill publish   main: 'index.js',
npm sill publish   scripts: { test: 'echo "Error: no test specified" && exit 1' },
npm sill publish   author: '',
npm sill publish   license: 'ISC',
npm sill publish   gitHead: '43ad9c6c0673f53edfa34115740f5a334878bce7',
npm sill publish   readme: 'ERROR: No README data found!',
npm sill publish   _id: '@scott113341/testo@4.0.0-0',
npm sill publish   _shasum: '53473bf0fc81d0c750a3144d25c21aece5164d19',
npm sill publish   _from: '.' }
npm verb getPublishConfig undefined
npm sill mapToRegistry name @scott113341/testo
npm sill mapToRegistry scope (from package name) @scott113341
npm verb mapToRegistry no registry URL found in name for scope @scott113341
npm sill mapToRegistry using default registry
npm sill mapToRegistry registry https://registry.npmjs.org/
npm sill mapToRegistry data Result {
npm sill mapToRegistry   raw: '@scott113341/testo',
npm sill mapToRegistry   scope: '@scott113341',
npm sill mapToRegistry   escapedName: '@scott113341%2ftesto',
npm sill mapToRegistry   name: '@scott113341/testo',
npm sill mapToRegistry   rawSpec: '',
npm sill mapToRegistry   spec: 'latest',
npm sill mapToRegistry   type: 'tag' }
npm sill mapToRegistry uri https://registry.npmjs.org/@scott113341%2ftesto
npm verb publish registryBase https://registry.npmjs.org/
npm sill publish uploading /Users/scott/.npm/@scott113341/testo/4.0.0-0/package.tgz
npm verb request uri https://registry.npmjs.org/@scott113341%2ftesto
npm verb request sending authorization for write operation
npm info attempt registry request try #1 at 5:26:19 PM
npm verb request using bearer token for auth
npm verb request id cf0c3bccd49b9f48
npm http request PUT https://registry.npmjs.org/@scott113341%2ftesto
npm http 200 https://registry.npmjs.org/@scott113341%2ftesto
npm verb headers { 'content-type': 'application/json',
npm verb headers   'content-encoding': 'gzip',
npm verb headers   'cache-control': 'max-age=0',
npm verb headers   'transfer-encoding': 'chunked',
npm verb headers   'accept-ranges': 'bytes',
npm verb headers   date: 'Sat, 02 Jul 2016 00:26:20 GMT',
npm verb headers   via: '1.1 varnish',
npm verb headers   connection: 'keep-alive',
npm verb headers   'x-served-by': 'cache-sjc3132-SJC',
npm verb headers   'x-cache': 'MISS',
npm verb headers   'x-cache-hits': '0',
npm verb headers   'x-timer': 'S1467419179.762953,VS0,VE655' }
npm verb request invalidating /Users/scott/.npm/registry.npmjs.org/_40scott113341_252ftesto on PUT
+ @scott113341/testo@4.0.0-0
npm info lifecycle @scott113341/testo@4.0.0-0~publish: @scott113341/testo@4.0.0-0
npm sill lifecycle @scott113341/testo@4.0.0-0~publish: no script for publish, continuing
npm info lifecycle @scott113341/testo@4.0.0-0~postpublish: @scott113341/testo@4.0.0-0
npm sill lifecycle @scott113341/testo@4.0.0-0~postpublish: no script for postpublish, continuing
npm verb exit [ 0, true ]
npm info ok 
  'dist-tags': { latest: '4.0.0-0' },

supporting information:

  • npm -v prints: 3.10.3
  • node -v prints: v6.2.2
  • npm config get registry prints: https://registry.npmjs.org/
  • Windows, OS X, or Linux?: OS X
  • Network issues:
    • Geographic location where npm was run: USA
    • I use a proxy to connect to the npm registry.
    • I use a proxy to connect to the web.
    • I use a proxy when downloading Git repos.
    • I access the npm registry via a VPN
    • I don't use a proxy, but have limited or unreliable internet access.
  • Container:
    • I develop using Vagrant on Windows.
    • I develop using Vagrant on OS X or Linux.
    • I develop / deploy using Docker.
    • I deploy to a PaaS (Triton, Heroku).

As a temporary measure, I have created this package:

GitHub: https://github.com/scott113341/npm-publish-safe-latest
npm: https://www.npmjs.com/package/npm-publish-safe-latest

😄

EDIT: Use np instead, which has the expected functionality baked in: https://github.com/sindresorhus/np

👍 Yes, very unintuitive, especially if you've never worked with dist-tags before. We at the Bootstrap Core Team have gotten shot by this footgun: twbs/bootstrap#18520

One other thing I discovered: npm publish --no-tag sets the dist-tag to false when publishing:

$ npm version major
$ npm publish --no-tag
$ npm info . dist-tags
{ latest: '14.0.0', false: '17.0.0' }

I propose that the latest tag only be set if the version to be published is not a pre-release version. I am happy to do the work on this and submit a PR, but I'd like to first discuss and get approval before putting the time in.

I totally agree. Users should not get prereleases by default. The point of prereleases is to be before a release so if the author is publishing a prerelease they usually don't want their community to get it by default until more testing has been done with that prerelease. By allowing prereleases to become the default when the user doesn't specify the version, npm is encouraging huge instability in codebases using npm.

Even better if npm would pick up the first dot-delimited identifier from the Semver prerelease and if it starts with a letter use that as the dist-tag, since that's a common standard for use in Semver: 1.0.0-alpha.1, 2.1.3-beta.2016.12.24 for dist-tag alpha, beta respectively.

We're closing this support issue as it has gone three days without activity. The npm CLI team itself does not provide support via this issue tracker, but we are happy when users help each other here. In our experience once a support issue goes dormant it's unlikely to get further activity. If you're still having problems, you may be better served by joining package.community and asking your question there.

For more information about our new issue aging policies and why we've instituted them please see our blog post.

I am happy to do the work on this and submit a PR, but I'd like to first discuss and get approval before putting the time in.

No one replied to him…

@othiym23 Could you please reopen this and re-tag it as not a support issue? This is feature/change request, not a request for debugging help.

@cvrebert My employment with npm, Inc. was terminated as of January 12 of this year, and my rights and responsibilities for managing this project ended at that time. You'll have to find somebody else to ask.

If anyone is looking for a way around this, check out the np package, which includes safeguards against this (and a whole lot of very useful publishing functionality): https://github.com/sindresorhus/np

The only real alternative to this is using np, right? I've published an unsecure, alpha release to thousands of users because of this issue that no one from npm ever bothered to check.