繁体   English   中英

Docker Jenkins Pipeline 安装全局 NPM 包

[英]Docker Jenkins Pipeline install global NPM packages

我是 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 ,但我需要更改很多 repos 及其脚本才能使其正常工作,我宁愿不这样做。

更新:看起来管道忽略了更改下的 PATH 环境变量

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

是否有特殊的可能来修改 PATH? 或者可能是权限问题?

如果您使用声明性管道进行构建,那么全局安装任何东西都是没有意义的。

如果您在管道执行期间安装 'angular-cli',npm 将为您设置 PATH 变量,并且 ng 将可用。

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

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

此外,如果您使用声明性管道,您可以使用最轻的图像而无需 CI 绑定。 我使用节点:8.11.3-stretch

这是一个格式化的,希望有用的答案,在尝试用他们的详细文档解决问题之后。

首先, environment块声明 Jenkins 级别的键值对:

  • Jenkins 级别不是工作区级别,根据引号的类型选择可变插值级别,所以如果我理解正确:

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

    echo "$PATH"将由 Jenkins 解释,因此显示“修改后的” PATH

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

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

其次,只有有限的步骤列表进行有效调用,并且没有export步骤。

但是有一个withEnv步骤应该可以完成这项工作。 我没有在声明性pipeline { ... }找到任何示例,仅在脚本node { ... }块中,声明性版本的定义声明所有步骤都是有效的。 我发现了一个步骤包装stage块的示例(尽管在一个node ),所以让我们希望它对于stages是相同的(否则你必须在每个stage指定withEnv - 或者作为一个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东西不起作用并且比重写管道更困扰你,那么使用带有node块的脚本替代方案可能会更有趣并且更灵活。

我很想从 OP 或周围的任何 Jenkins 大师那里得到一些反馈!

正确的方法是使用 Jenkins 的 Node.js 插件。 它允许您管理不同版本的 node 和 npm 包,而无需在构建机器上手动安装它们。 这是一个全局使用节点 13 和 eslint 的配置示例: 在此处输入图片说明

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM