[英]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.