我是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"
}
有一个特殊的可修改路径?还是权限问题?
答案 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的配置示例:
在管道中,您可以执行以下操作:
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