我是 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"
}
是否有特殊的可能修改PATH?或者可能是权限问题?
最佳答案
在尝试用详细的文档整理内容之后,这是一个格式化的、希望有用的答案。
首先,environment
block 声明 Jenkins 级别的键值对:
Jenkins 级别不是工作区级别,变量插值级别是根据引号类型选择的,所以如果我理解正确的话:
echo '$PATH'
would show the workspacePATH
("default", in your case)echo "$PATH"
would be interpreted by Jenkins, hence showing the "modified"PATH
仅键值对有效:即使它看起来像 shell 环境变量设置,您也可以编写
PATH = some
而=
周围的空格在 shell 中不起作用
人们似乎主要认为是在工作区不知道参数的情况下公开参数,就像用户以交互方式提供信息一样(他们谈论了很多有关凭据的信息)。
第二,仅列出steps的有限列表。进行有效调用,并且没有导出
步骤。
但是有一个 withEnv
步骤可以完成这项工作。我在声明性 pipeline { ... }
中没有找到任何示例,仅在脚本化 node { ... }
block 中,声明性版本的定义声明所有步骤都是有效的。我发现了一个包装 stage
block 的步骤示例(尽管在 node
中),所以我们希望它对于 stages
是相同的(否则你必须在每个 stage
上指定 withEnv
- 或者作为 stage
内的另一个包装器 - 这需要你的环境 mods:当然可行但很无聊)。
这样的东西应该有效,或者至少值得一试:
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
block 的脚本替代方案可能会更有趣并且更灵活。
我希望得到 OP 或周围任何 Jenkins 专家的一些反馈!
关于node.js - Docker Jenkins Pipeline 安装全局 NPM 包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54490999/