Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jenkins pipeline : select nodejs version (+ python version)

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

like image 863
Olivier Avatar asked Feb 15 '17 22:02

Olivier


People also ask

How does Jenkins decide which node to use?

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.

How do I set node Jenkins version?

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.


1 Answers

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.

like image 109
Olivier Avatar answered Oct 05 '22 23:10

Olivier