码头工人詹金斯管道安装全球NPM包

时间:2019-02-02 07:29:04

标签: node.js docker jenkins npm

我是Docker / Jenkins的新手。

Jenkins通过以下方式触发容器

docker run -t -d -u 995:315 -w /workspace/projectname -v /workspace/projectname:/workspace/projectname:rw,z -v /workspace/projectname@tmp:/workspace/projectname@tmp:rw,z  circleci/node:latest

我的管道

pipeline {
    agent {
        docker {
            image 'circleci/node:latest'
        }
    }
    environment { 
        HOME="."
        NPM_CONFIG_PREFIX="${pwd()}/.npm-global"
        PATH="$PATH:${pwd()}/.npm-global/bin:${pwd tmp: true}/.npm-global/bin"
    }
    stages {
        stage('NPM Config') {
            steps {
                sh 'npm install -g @angular/cli'
                echo "PATH is: $PATH"
                sh '.npm-global/bin/ng version'
                sh '/workspace/projectname/.npm-global/bin/ng version'
                sh 'ng version'
            }
        }
    }
}

echo "PATH is: $PATH"打印出

PATH is: /sbin:/usr/sbin:/bin:/usr/bin;/usr/bin/;/etc/;/etc/ssh/ssh/:/workspace/projectname/.npm-global/bin:/workspace/projectname@tmp/.npm-global/bin

这两者

sh '.npm-global/bin/ng version'
sh '/workspace/projectname/.npm-global/bin/ng version'

做什么,我希望sh 'ng version'做。但是,sh 'ng version'给了我以下错误

ng version
/workspace/projectname@tmp/durable-9f9bc04a/script.sh: 2: /workspace/projectname@tmp/durable-9f9bc04a/script.sh: ng: not found

我正试图避免建立自己的形象,下一步将是什么好选择?

我也只使用npx,但为了使这项工作有效,我需要更改很多存储库及其脚本,而我不想这样做。

更新:看来管道正在忽略对PATH环境变量的更改

environment { 
   HOME="."
   NPM_CONFIG_PREFIX="${pwd()}/.npm-global"
   PATH="/foo/bar"
}

有一个特殊的可修改路径?还是权限问题?

3 个答案:

答案 0 :(得分:1)

如果您使用声明性管道进行构建,则无法在全局范围内安装任何内容。

如果您在管道执行过程中安装了“ angular-cli”,则npm将为您设置PATH变量,而ng将可用。

如果您构建自己的映像并计划以后再使用,则全局安装才有意义。但在这种情况下,图像将在构建后删除。

在这种情况下,我使用sh "ls -la1 $dir_name"sh "whereis ng"来调试“找不到可执行文件”问题。

此外,如果您使用а声明管道可以用最轻的图像,而不CI绑定。 我使用node:8.11.3-stretch

答案 1 :(得分:1)

在尝试用详细的文档整理内容之后,这是一个格式化的,希望有用的答案。

首先,environment块声明詹金斯级键值对:

  • 詹金斯级不是工作空间级,根据引号的类型选择可变插值级,所以如果我理解正确的话:

      

    echo '$PATH'将显示工作区PATH(在您的情况下为“默认”)

         

    echo "$PATH"由詹金斯(Jenkins)解释,因此显示了“修改后的” PATH

  • 键值对仅有效:即使看起来像shell环境变量设置,您也可以编写PATH = something,而=周围的空格在shell中不起作用

似乎主要认为是在工作空间不知道参数的情况下公开参数的,就像用户会交互式地提供信息(他们经常谈论凭据)。

第二,只有有限的steps列表可以进行有效呼叫,并且没有export步骤。

但是有一个withEnv步骤应该可以完成工作。我在声明性pipeline { ... }中找不到任何示例,仅在脚本化的node { ... }块中,声明性版本的定义指出所有步骤均有效。我找到了一个包装stage块的步骤的示例(尽管在node中),所以我们希望它与stages相同(否则,您必须指定{{1 }}上的每个withEnv上-或作为stage内的另一个包装,这需要您的环境mod:确实可行,但很无聊)。

类似的事情应该起作用,或者至少值得一试:

stage

好吧,你明白了。

最后,如果这个 pipeline { agent { ... } environment { HOME="." NPM_CONFIG_PREFIX="${pwd()}/.npm-global" PATH="$PATH:${pwd()}/.npm-global/bin:${pwd tmp: true}/.npm-global/bin" } withEnv(["PATH=$PATH", /*or*/ "PATH=${PATH}", /*or*/ "PATH+NPM=${pwd()}/.npm-global/bin:${pwd tmp: true}/.npm-global/bin"]) { stages { stage('NPM Config') { steps { ... } } stage('something else that needs ng') { ... } } } } 不起作用,并且比重写管道更麻烦您,使用带有PATH块的脚本替代可能会很有趣并且更加灵活。

我很乐意从OP或周围的任何詹金斯大师那里得到一些反馈!

答案 2 :(得分:0)

正确的方法是使用Jenkins的Node.js插件。 它允许您管理节点和npm软件包的不同版本,而无需手动将它们安装在构建计算机上。 这是一个使用节点13和全局eslint的配置示例: enter image description here

在管道中,您可以执行以下操作:

stage('Use node commands and npm packages') {
  steps {
    nodejs(nodeJSInstallationName: 'node13') {
      sh 'npm -v'  //substitute with your code
      sh 'node -v'
      sh 'eslint ...'
    }
  }
}

完整示例:https://pillsfromtheweb.blogspot.com/2020/05/how-to-use-different-nodejs-versions-on.html