Jenkins 2 NPM_TOKEN credential
Asked Answered
A

3

7

I'm trying to run Jenkins 2 pipeline (Jenkinsfile) that will use npm publish to publish a package to local NPM repository.
In order to do that I've try to use the following stage in Jenkinsfile:

stage('TEST npm whoami') {
    withEnv(["PATH+NPM=${tool name: 'node-6', type: 'jenkins.plugins.nodejs.tools.NodeJSInstallation'}/bin"]) {
    withCredentials([[$class: 'StringBinding', credentialsId: 'npm-token', variable: 'NPM_TOKEN']]) {
        sh """
           npm whoami
           """
    }
    }
}

Currently I'm running only npm whoami and once that will work I'll replace it with npm publish.

This is the output I'm getting:

+ npm whoami
npm ERR! Linux 4.7.5-1.el7.elrepo.x86_64
npm ERR! argv "/var/lib/jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/node-6/bin/node" "/var/lib/jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/node-6/bin/npm" "whoami"
npm ERR! node v6.5.0
npm ERR! npm  v3.10.3
npm ERR! code ENEEDAUTH

npm ERR! need auth this command requires you to be logged in.
npm ERR! need auth You need to authorize this machine using `npm adduser`
Arnaldo answered 13/10, 2016 at 8:55 Comment(1)
Just to verify, credentialsId is usually a guid. Did you put 'npm-token' here for the idea? And what happens if you just echo $NPM_TOKENFireboat
C
8

From looking at this GitHub issue, it seems like NPM_TOKEN isn't something that npm itself recognizes, but rather a custom environment variable that heroku (and maybe other platforms) interpret.

What I've done, based on some of the discussion in that issue, is to create a project-level .npmrc at job execution time based on the token env var from my credential, then remove the file again before continuing. E.g.:

stage('TEST npm whoami') {
    withCredentials([string(
                credentialsId: 'npm-token',
                variable: 'NPM_TOKEN')]) {
        sh "echo //npm.skunkhenry.com/:_authToken=${env.NPM_TOKEN} > .npmrc"
        sh 'npm whoami'
        sh 'rm .npmrc'
    }
}

Hope this helps!

Crossbow answered 25/5, 2017 at 19:20 Comment(1)
Slightly tweaked variant - with .npmrc written to the build server's $HOME dir and wrapped on a try-catch block that ensures the file's deleted every run: ~~~ withCredentials([string(credentialsId: 'NPM_TOKEN', variable: 'NPM_TOKEN')]) { String text = "//registry.npmjs.org/:_authToken=${env.NPM_TOKEN}" String npmrc = '\$HOME/.npmrc' writeFile file: npmrc, text: text try { sh 'npm publish' } finally { sh "rm ${npmrc}" } } ~~~Seaplane
I
3

The answer of Gerard Ryan and Gaston is correct, I just wanted to add one detail that I did not get at first:

If you want to use a private repository, the .npmrc should also specify the registry:

withCredentials([string(credentialsId: 'registry', variable: 'token')]) {
            try {
                sh "echo registry=<your-registry-URL> >> .npmrc"
                sh "echo //<your-registry-URL>/:_authToken=${env.token} >> .npmrc"
                sh 'npm whoami'
            } finally {
                sh 'rm ~/.npmrc'
            }
}
Izettaizhevsk answered 23/9, 2019 at 11:15 Comment(3)
Apparently, not all version of Jenkins will accept the try { ... } finally { ... } in this form. Expected a step @ line 194, column 17. try {Superfetation
The try...finally block will only work with Scripted Pipeline. With Declarative Pipeline you will get something like the following error: WorkflowScript: 115: Expected a step @ line 115, column 13 To fix that you should wrap it in script e.g. script { try {withCredentials(){...}} finally {}}Ander
Please mind that in the response above .npmrc is created in a current directory while remove command attempts to remove it from user's home folderAnder
M
1

We can use pipeline npm plugin

and config pipeline

withNPM(npmrcConfig: 'my-custom-nprc') {
    sh 'npm install'
}
Mcavoy answered 6/4, 2023 at 2:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.