21

I'm building a Docker image for an application based in node.js where some of the dependencies requires an NPM token for a private NPM registry, but when building the image the variable containing the token is null, e.g.

docker build -t 3273e0bfe8dd329a96070382c1c554454ca91f96 --build-args NPM_TOKEN=null -f Dockerfile

a simplified pipeline is:

pipeline {

  environment {
    NPM_TOKEN = credentials('npm-token')
  }

  agent {
    dockerfile {
      additionalBuildArgs "--build-args NPM_TOKEN=${env.NPM_TOKEN}"
    }
  }

  stages {
    stage('Lint') { 
      steps { 
        sh 'npm run lint' 
      }
    }
  }

}

Is there a way to use the env variable in that section or it is not currently supported?

BTW, I've followed the suggestions in Docker and private modules related to how to use a NPM token to build a docker image

pablodcar
  • 798
  • 1
  • 6
  • 15

3 Answers3

14

This is definitely a bug with the declarative pipeline. You can track the issue related to this here: https://issues.jenkins-ci.org/browse/JENKINS-42369

If you move away from using the declarative pipeline and use the scripted pipelines instead, this won't occur, although your Jenkinsfile will be "wordier"

Spencer Malone
  • 1,449
  • 12
  • 12
  • 3
    Would be nice if you show an example for a scripted pipeline which resolves this problem. – Alex Jan 08 '19 at 09:07
3

found a solution for this. Use credentials manager to add NPM_TOKEN. Then you can do

pipeline {
  agent {
    docker {
      image 'node:latest'
      args '-e NPM_TOKEN=$NPM_TOKEN'
    }

  }
  stages {
    stage('npm install') {
      steps {
        sh 'npm install'
      }
    }
    stage('static code analysis') {
      steps {
        sh 'npx eslint .'
      }
    }
  }
}
Max Paymar
  • 588
  • 1
  • 7
  • 23
2

I came up with a workaround for this and it still uses declarative pipeline. I'm using this technique to download private github repos with pip.

// Workarounds for https://issues.jenkins-ci.org/browse/JENKINS-42369
// Warning: The secret will show up in your build log, and possibly be in your docker image history as well.
// Don't use this if you have a super-confidential codebase

def get_credential(name) {
  def v;
  withCredentials([[$class: 'StringBinding', credentialsId: name, variable: 'foo']]) {
      v = env.foo;
  }
  return v
}

def get_additional_build_args() {
    return "--build-arg GITHUB_ACCESS_TOKEN=" + get_credential("mysecretid")
}


pipeline {
    agent {
        dockerfile {
            filename 'Dockerfile.test'
            additionalBuildArgs get_additional_build_args()
        }
    }
KP99
  • 378
  • 1
  • 9