Ich versuche, npm publish
in einem Docker-Container zu automatisieren, aber ich habe Probleme, wenn der $npm login
-Befehl versucht, den Benutzernamen und die E-Mail aus den Eingabeaufforderungen zu lesen:
npm login << EOF
username
password
email
EOF
es funktioniert in Terminal-Bash, aber nicht in Container ohne STDIN, und es wird die folgende Fehlermeldung angezeigt:
Username: Password: npm ERR! cb() never called!
npm ERR! not ok code 0
Laut npm-adduser :
Benutzername, Passwort und E-Mail-Adresse werden in Eingabeaufforderungen eingelesen.
Wie kann ich also npm login
ausführen, ohne dass STDIN geöffnet ist?
TL; DR: Stellen Sie eine HTTP-Anforderung direkt an die Registrierung:
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
Hinter den Kulissen macht npm adduser
eine HTTP-Anfrage an die Registry. Anstatt adduser
zu zwingen, sich so zu verhalten, wie Sie möchten, können Sie die Anforderung direkt an die Registrierung senden, ohne das CLI zu durchlaufen, und dann das Authentifizierungstoken mit npm set
festlegen.
Der Quellcode schlägt vor , dass Sie eine PUT-Anforderung an http://your_registry/-/user/org.couchdb.user:your-username
mit der folgenden Nutzlast stellen könnten
{
name: username,
password: password
}
und das würde einen neuen Benutzer in der Registrierung erstellen.
Vielen Dank an @shawnzhu, dass Sie einen saubereren Ansatz gefunden haben, um das Problem zu lösen.
Ein erwartetes Skript hat für mich funktioniert. Sie müssen sicherstellen, dass Expect installiert ist;
apt-get install expect-dev
Ihr Skript könnte ungefähr so aussehen (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
}
Und dann nennen wir es so:
expect -f npm_login_expect myuser mypassword "[email protected]"
Ich habe einen etwas anderen Ansatz gewählt, der immer noch gut zu funktionieren scheint. Zunächst benötigen Sie ein Auth-Token. Dies ist leicht erhältlich, indem Sie npm adduser
lokal ausführen und dann das generierte Token von Ihrem ~/.npmrc
in Ihrem Benutzerordner abholen. Um auf Ihrem ci-Server authentifiziert zu werden, muss dieses Authentifizierungs-Token an die Registrierungs-URL im .npmrc
des Benutzers angehängt werden (ähnlich wie lokal), nicht im .npmrc
des Repos, sodass diese als Skriptschritte in my funktionieren CI-Konfiguration
- echo "//<npm-registry>:8080/:_authToken=$AUTH_TOKEN" > ~/.npmrc
- npm publish
aUTH_TOKEN wird in Ihren Einstellungen als geheime Variable gespeichert. Eine gute Möglichkeit, dies zu testen, besteht darin, npm publish
durch npm whoami
zu ersetzen, um zu testen, ob Sie erfolgreich angemeldet sind.
Hier ist meine gesamte Veröffentlichungskonfiguration
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!'
Ich verwende gitlab-ci, sehe aber nicht, warum dies für keine ci-Anwendung gilt.
Kaum zu glauben, dass es nach all dieser Zeit immer noch keine Lösung für npm login gibt. Sicher, Sie können sich ein Token einmal schnappen und es für alle Ihre CI-Anforderungen verwenden. Und was ist, wenn eines Tages Admins beschließen, dass Token auslaufen?
Unten ist meine gehackte Javascript-Lösung mit npm-registry-client
-Paket. Übergeben Sie einfach ein json-String-Argument, um sich anzumelden und eine .npmrc
-Datei in Ihr aktuelles Verzeichnis zu schreiben. Um sich abzumelden, verwenden Sie npm logout
wie gewohnt.
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}`);
});
Beispieleingabe:
{
"uri": "https://my-nmp.reg",
"scope": "@my-scope",
"params": {
"auth": {
"username": "secret-agent",
"password": "12345",
"email": "[email protected]"
}
}
}
Dies baut auf der Antwort von Alexander F auf. Dies ist nur eine vereinfachte Version des von ihm bereitgestellten Codes, zusammen mit dem von npm-registry-client bereitgestellten Beispielcode.
"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}`);
});
Mit npm-cli-login können Sie sich ohne STDIN bei NPM anmelden.
Zur Installation ausführen
npm install -g npm-cli-login
verwendungsbeispiel: -
npm-cli-login -u Benutzername -p Kennwort -e [email protected] -r https: // Ihr-privater-Registry-Link
Sie können stattdessen ein Expect-Skript verwenden oder ein Knotenskript schreiben, das pty.js verwendet.
Für die Lösung 2, die von ke_wa in dieser duplizierten Post angezeigt wird, hat gearbeitet.
Vermanschen:
export NPM_USERNAME=mUs34
export NPM_PASSWORD=mypassW0rD
export [email protected]
npm adduser<<!
$NPM_USERNAME
$NPM_PASSWORD
$NPM_EMAIL
!
Eine einfache Lösung besteht darin, den Benutzer und das Passwort im ~/.npmrc einzurichten
@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
Dies funktioniert auch, um das Authentifizierungstoken anstelle des Kennworts anzugeben
So mach ich es:
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
Empfohlen von JFrog https://www.jfrog.com/confluence/display/RTF/npm+Registry#npmRegistry-UsingLoginCredentials