J'essaie d'automatiser npm publish
dans un conteneur de menu fixe, mais j'ai eu des problèmes lorsque la commande $npm login
essaie de lire le nom d'utilisateur et l'adresse électronique à partir des invites:
npm login << EOF
username
password
email
EOF
cela fonctionne en terminal bash mais pas en conteneur sans STDIN ouvert et affiche le message d'erreur suivant:
Username: Password: npm ERR! cb() never called!
npm ERR! not ok code 0
Selon npm-adduser :
Le nom d'utilisateur, le mot de passe et l'adresse électronique sont lus à partir des invites.
Alors, comment puis-je exécuter npm login
sans STDIN ouvert?
TL; DR: Effectuer une demande HTTP directement au registre:
TOKEN=$(curl -s \
-H "Accept: application/json" \
-H "Content-Type:application/json" \
-X PUT --data '{"name": "username_here", "password": "password_here"}' \
http://your_registry/-/user/org.couchdb.user:username_here 2>&1 | grep -Po \
'(?<="token": ")[^"]*')
npm set registry "http://your_registry"
npm set //your_registry/:_authToken $TOKEN
En coulisse, npm adduser
adresse une requête HTTP au registre. Au lieu de forcer adduser
à se comporter comme vous le souhaitez, vous pouvez adresser la demande directement au registre sans passer par le cli, puis définir le jeton d'authentification avec npm set
.
Le code source suggère que vous pouvez envoyer une requête PUT à http://your_registry/-/user/org.couchdb.user:your-username
avec la charge suivante
{
name: username,
password: password
}
et cela créerait un nouvel utilisateur dans le registre.
Merci beaucoup à @shawnzhu pour avoir trouvé une approche plus propre pour résoudre le problème.
Un script attendu a fonctionné pour moi. Vous devez vous assurer que expect est installé, cette commande devrait le faire pour Ubuntu:
apt-get install expect-dev
Votre script pourrait ressembler à ceci (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
}
Et puis appelez ça comme ça:
expect -f npm_login_expect myuser mypassword "[email protected]"
J'ai adopté une approche légèrement différente qui semble fonctionner encore très bien. Pour commencer, vous aurez besoin d'un jeton d'authentification. Ceci est facilement accessible en exécutant localement npm adduser
, puis en récupérant le jeton généré dans votre ~/.npmrc
situé dans votre dossier utilisateur. Pour être authentifié sur votre serveur ci, ce jeton d’authentification doit être ajouté à l’URL du registre dans le .npmrc
de l’utilisateur (similaire à ce qu’il était localement), pas le .npmrc
situé dans le référentiel. Celles-ci ont donc bien fonctionné comme étapes de script dans mon Configuration CI
- echo "//<npm-registry>:8080/:_authToken=$AUTH_TOKEN" > ~/.npmrc
- npm publish
où AUTH_TOKEN est stocké en tant que variable secrète dans vos paramètres . Un bon moyen de tester cela consiste à remplacer npm publish
par npm whoami
pour tester et vous assurer qu'il vous a connecté avec succès.
Voici toute ma configuration de publication
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!'
J'utilise gitlab-ci mais je ne vois pas pourquoi cela ne s'appliquerait à aucune application ci.
Difficile de croire qu'après tout ce temps, il n'y a toujours pas de solution pour la connexion npm. Bien sûr, vous pouvez saisir un jeton une fois et l’utiliser pour tous vos besoins en matière de CI, mais qu’en est-il de la sécurité d’un jeton qui n’expire jamais? Et si un jour les administrateurs décidaient que les jetons devaient expirer?
Ci-dessous ma solution javascript hacky utilisant le package npm-registry-client
. Il suffit de passer un argument de chaîne json, il se connectera et écrira un fichier .npmrc
dans votre répertoire actuel. Pour vous déconnecter, utilisez npm logout
comme d'habitude.
var client = new (require('npm-registry-client'))({});
var std_in = JSON.parse(process.argv[2]);
if (std_in.uri === undefined) {
console.error('Must input registry uri!');
return;
}
// fix annoying trailing '/' thing in registry uri
if (std_in.uri[std_in.uri.length - 1] !== '/') {
std_in.uri = std_in.uri + '/';
}
if (std_in.scope === undefined) {
console.error('Must input scope!');
return;
//std_in.scope = '@my-scope'; // or add default scope of your own
}
if (std_in.scope[0] !== '@') {
std_in.scope = '@' + std_in.scope;
}
client.adduser(std_in.uri, std_in.params, function(err, data, raw, res) {
if (err) {
console.error(err);
return;
}
require('fs').writeFileSync('.npmrc', `${std_in.scope}:registry=${std_in.uri}\n//${(std_in.uri.split('//'))[1]}:_authToken=${data.token}`);
});
Exemple d'entrée:
{
"uri": "https://my-nmp.reg",
"scope": "@my-scope",
"params": {
"auth": {
"username": "secret-agent",
"password": "12345",
"email": "[email protected]"
}
}
}
Cela s'appuie sur la réponse d'Alexander F. Ceci est juste une version simplifiée du code qu'il a fourni, mélangé avec l'exemple de code fourni par 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 = '[email protected]'
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}`);
});
npm-cli-login vous permet de vous connecter à NPM sans STDIN.
Afin d'installer run
npm install -g npm-cli-login
exemple d'utilisation: -
npm-cli-login -u Nom d'utilisateur -p Mot de passe -e [email protected] -r https: // votre-lien-registre-privé
Vous pouvez utiliser un script attendu à la place ou écrire un script de noeud qui utilise pty.js .
Pour la solution 2 exposée par ke_wa dans ce poste dupliqué a fonctionné.
Écraser:
export NPM_USERNAME=mUs34
export NPM_PASSWORD=mypassW0rD
export [email protected]
npm adduser<<!
$NPM_USERNAME
$NPM_PASSWORD
$NPM_EMAIL
!
Une solution simple configure l'utilisateur et le mot de passe dans le ~/.npmrc
@jfrog:registry=http://localhost:8081/artifactory/api/npm/npm-local/
//localhost:8081/artifactory/api/npm/npm-local/:_password=cGFzc3dvcmQ=
//localhost:8081/artifactory/api/npm/npm-local/:username=admin
//localhost:8081/artifactory/api/npm/npm-local/:[email protected]
//localhost:8081/artifactory/api/npm/npm-local/:always-auth=true
Cela fonctionne également pour spécifier le jeton d'authentification au lieu du mot de passe
Je le fais comme ça:
echo "@my:registry https://artifactory.my.io/artifactory/api/npm/npm-release-local/" >> ~/.npmrc
echo "//artifactory.my.io/artifactory/api/npm/npm-release-local/:_password=${ARTIFACTORY_API_KEY}" >> ~/.npmrc
echo "//artifactory.my.io/artifactory/api/npm/npm-release-local/:username=${ARTIFACTORY_USERNAME}" >> ~/.npmrc
echo "//artifactory.my.io/artifactory/api/npm/npm-release-local/:[email protected]" >> ~/.npmrc
echo "//artifactory.my.io/artifactory/api/npm/npm-release-local/:always-auth=true" >> ~/.npmrc
Recommandé par JFrog https://www.jfrog.com/confluence/display/RTF/npm+Registry#npmRegistry-UsingLoginCredentials