I'm facing an issue with a Jenkins pipeline in a Jenkinsfile. I have 4 different nodeJs versions on my Jenkins instance. I would like to choose which one I'm going to use in my pipeline, but official plugin examples (https://wiki.jenkins-ci.org/display/JENKINS/NodeJS+Plugin) simply don't work.
I tried this first approach, failing because $PATH is overwritten by the tools
section.
pipeline {
agent any
tools {
// I hoped it would work with this command...
nodejs 'nodejs6'
}
stages {
stage('Example') {
steps {
sh 'npm --version'
// Failed saying :
// Running shell script
//nohup: failed to run command 'sh': No such file or directory
}
}
}
}
I tried this second approach, failing because the tool
command seems to do nothing at all.
pipeline {
agent any
stages {
stage('Example') {
steps {
// ... or this one
tool name: 'nodejs6'
sh 'node --version'
sh 'npm --version'
// Does not use this version of node, but the default one... 7.5.0 with npm 4.3.0
}
}
}
}
Finally, I tried this one, which works for NodeJS but... does not seem to be "very smart", and does not allow me to handle properly my specific version of "Python" --Yes I also have 2 different versions of Python that I would like to handle the same way I do for node--
pipeline {
agent any
stages{
stage ('Which NodeJS'){
steps{
withEnv(["PATH+NODEJS=${tool 'nodejs6'}/bin","PATH+PYTHON27=${tool 'python27'}"]) {
// Check node version
sh 'which node' // Works properly
sh 'node -v' // Expected 6.9.x version
sh 'npm -v' // Expected 3.x version
sh 'python27 -v'
// Failed with
// /nd-jenkinsfile_XXX@tmp/xx/script.sh: python27: not found
}
}
}
}
}
I also have a 4th solution, not using pipeline
syntax. It works for nodejs, but not for python (so far). And once again, it does not seems very elegant to manually define env.PATH
...
node {
// Setup tools...
stage ('Setup NodeJs'){
def nodejsHome = tool 'nodejs6'
env.NODE_HOME = "${nodejsHome}"
env.PATH = "${nodejsHome}/bin:${env.PATH}"
sh 'which node'
sh 'node -v'
sh 'npm -v'
}
stage ('Setup Python 2.7'){
def pythonBin = tool 'python27'
// Jenkins docker image has Jenkins user's home in "/var/jenkins_home"
sh "rm -Rf /var/jenkins_home/tools/python ; mkdir -p /var/jenkins_home/tools/python"
// Link python to python 2.7
sh "ln -s ${pythonBin} /var/jenkins_home/tools/python/python"
// Include link in path --don't use "~" in path, it won't be resolved
env.PATH = "~/tools/python:${env.PATH}:~/tools/python"
// Displays correctly Python 2.7
sh "python --version"
}
}
All in all, I'm just wondering which solution (certainly another one that I have not listed here) is the best? Which one do you advice and why?
Cheers, Olivier
By default, Jenkins employs the algorithm known as consistent hashing to make this decision. More specifically, it hashes the name of the node, in numbers proportional to the number of available executors, then hashes the job name to create a probe point for the consistent hash.
To do this go back to the “Manage Jenkins”. Then Global Tool Configuration. Scroll down to Nodejs select the “Add NodeJS”. File in the form name :nodejs and select the intend Nodejs version.
So. This is a problem from "EnvInject" plugin: https://issues.jenkins-ci.org/browse/JENKINS-26583
My workaround #4 above is the correct solution if you want to keep EnvInject.
env.NODE_HOME="${tool 'Node 6.x'}"
env.PATH="${env.NODE_HOME}/bin:${env.PATH}"
sh 'npm -version'
Otherwise, removing EnvInject plugin is also a good solution when possible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With