Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-62993

Auto-detect NodeJS-Tool based on package.json engines.node version

XMLWordPrintable

    • Icon: New Feature New Feature
    • Resolution: Won't Do
    • Icon: Minor Minor
    • nodejs-plugin
    • None

      As described in nodejs docs] you can specify the nodejs version suitable for your project in package.json.

      I think it would be nice if one could write something like this in pipeline:

      nodejsAutodetect {
          // your node and npm scripts
      }

      and then nodejs-plugin would scan all installed versions of node and check whether the version fits or not. If it fits it would use that version for the block.

      I have created a groovy script in a shared library for my current project which does that. It is far from perfect, but i think a good proof of concept:

      import jenkins.plugins.nodejs.NodeJSUtils;
      
      @Grab('com.vdurmont:semver4j:3.1.0')
      import com.vdurmont.semver4j.Semver
      
      @NonCPS
      def determineInstalledNodeJSVersions() {
        def installedNodeJSVersions = [:]
        NodeJSUtils.getInstallations().each { entry ->
          def name = entry.getName()
          def version = entry.getProperties()[0].installers[0].id
          installedNodeJSVersions[name] = version
        }
        return installedNodeJSVersions.sort({it1, it2 -> it2.value <=> it1.value})
      }
      
      def nodejsAutodetect(Closure body) {
      
        def availableVersions = determineInstalledNodeJSVersions()
        // get lastest version
        def latestNodeJS = map.find { true }
        def nodeJSToUse = latestNodeJS.key
      
        if(!env.DETECTED_NODEJS_VERSION) {
          def packageJson = readJSON file: 'package.json'
          if(packageJson['engines'] && packageJson['engines']['node']) {
            versionString = packageJson['engines']['node']
            
            availableVersions.find { entry ->
              Semver semNPM = new Semver(entry.value, Semver.SemverType.NPM)    
              if(semNPM.satisfies(versionString)) {
                nodeJSToUse = entry.key
                env.DETECTED_NODEJS_VERSION = nodeJSToUse
                return true
              } else {
                return false
              }
            }
          } else {
            println "Did not find 'node' entry in package.json, so using latest installed nodejs."
          }
        } else {
          nodeJSToUse = env.DETECTED_NODEJS_VERSION
        }
      
        nodejs(nodeJSToUse) {
          body()
        }
      }
      

      I think it would be a nice improvement for your library.

      I am exited to hear what you think about it.

            nfalco Nikolas Falco
            andi_bade Andi Bade
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: