Set up npm credentials over `npm login` without re

2020-02-20 05:44发布

I'm trying to automate npm publish inside a Docker container but I have trouble when the npm login command tries to read the username and email from prompts:

npm login << EOF
username
password
email
EOF

It works in a Bash terminal but not in a container without stdin open, and shows the following error message:

Username: Password: npm ERR! cb() never called!
npm ERR! not ok code 0

According to npm-adduser:

The username, password, and email are read in from prompts.

So how can I run npm login without stdin open?

12条回答
家丑人穷心不美
2楼-- · 2020-02-20 06:28

I took a slightly different approach that seems to work great still. To begin with, you will need an auth token. This is easily obtainable by locally running npm adduser and then grabbing the generated token from your ~/.npmrc located in your user folder. In order to be authenticated on your ci server this auth token needs to be appended to the registry URL in the user's .npmrc (similar to how it was locally), not the .npmrc located in the repo, so these worked great as script steps in my CI configuration

- echo "//<npm-registry>:8080/:_authToken=$AUTH_TOKEN" > ~/.npmrc
- npm publish

where AUTH_TOKEN is stored as a secret variable in your settings. A good way to test this is to replace npm publish with npm whoami to test and make sure it successfully logged you in.

Here is my entire publish configuration

publish:
  stage: deploy
  only:
    - tags
  script:
    - yarn run build
    - echo "//<npm-registry>:8080/:_authToken=$NPME_AUTH_TOKEN" > ~/.npmrc
    - npm publish
    - echo 'Congrats on your publication!'

I'm using gitlab-ci but I don't see why this wouldn't apply to any ci application.

查看更多
叼着烟拽天下
3楼-- · 2020-02-20 06:30

This builds on top of Alexander F's answer. This is just a simplified version of the code he provided, mashed up with the example code provided by npm-registry-client.

"use strict";

var RegClient = require('npm-registry-client')
var client = new RegClient()
var uri = "https://registry.npmjs.org/npm"
var params = {timeout: 1000}

var username = 'my.npm.username'
var password = 'myPassword'
var email = 'my.email@gmail.com'

var params = {
  auth: {
    username,
    password,
    email
  }
};

client.adduser(uri, params, function (error, data, raw, res) {
  if(error) {
    console.error(error);
    return;
  }
  console.log(`Login succeeded`);
  console.log(`data: ${JSON.stringify(data,null,2)}`);
  console.log(`NPM access token: ${data.token}`);
});
查看更多
我欲成王,谁敢阻挡
4楼-- · 2020-02-20 06:32

An expect script worked for me. You need to make sure expect is installed, this command should do it for ubuntu:

apt-get install expect-dev

Your script could look something like this (npm_login_expect):

#!/usr/bin/expect -f

# set our args into variables
set i 0; foreach n $argv {set "p[incr i]" $n}

set timeout 60
#npm login command, add whatever command-line args are necessary
spawn npm login
match_max 100000

expect "Username"    
send "$p1\r"

expect "Password"
send "$p2\r" 

expect "Email"
send "$p3\r"

expect {
   timeout      exit 1
   eof
}

And then call it like this:

expect -f npm_login_expect myuser mypassword "myuser@domain.com"
查看更多
Luminary・发光体
5楼-- · 2020-02-20 06:39

npm-cli-login allows you to log in to NPM without STDIN.

In order to install run:

npm install -g npm-cli-login

Example usage:

npm-cli-login -u Username -p Password -e test@example.com -r https://your-private-registry-link
查看更多
聊天终结者
6楼-- · 2020-02-20 06:41

Depends on jq and three ENV vars set:

export NPM_REGISTRY_DOMAIN=
export NPM_REGISTRY_USER=
export NPM_REGISTRY_PASSWORD=

json="{\"name\": \""$NPM_REGISTRY_USER"\", \"password\": \""$NPM_REGISTRY_PASSWORD"\"}"

TOKEN=$(curl -s \
  -H "Accept: application/json" \
  -H "Content-Type:application/json" \
  -X PUT --data "$json" \
  --user "$NPM_REGISTRY_USER":"$NPM_REGISTRY_PASSWORD" \
  https://"$NPM_REGISTRY_DOMAIN"/-/user/org.couchdb.user:"$NPM_REGISTERY_USER" | \
            jq -r '.token'
    )

npm config set registry https://"$NPM_REGISTRY_DOMAIN"
npm set //"$NPM_REGISTRY_DOMAIN"/:_authToken "$TOKEN"

Based on the answer from https://stackoverflow.com/a/35831310/1663462

查看更多
【Aperson】
7楼-- · 2020-02-20 06:41

This worked in one of my jenkins jobs:

steps

  1. Generate _auth from npm registry credentials with base 64 using shell for security:
    echo -n 'myuser:mypassword' | openssl base64
    Result will be something like : eWFob29vb2E=
  1. Set npm registry url and _auth before npm install ...
    npm config set registry https://nexus-acme.com/repository/npm-group/
    npm config set _auth eWFob29vb2E=

That's all. You could run npm install, and your private modules will be downloaded.

查看更多
登录 后发表回答