Jenkins Pipeline - 如何使用 'tool' 选项指定自定义工具?
Jenkins Pipeline - How do I use the 'tool' option to specify a custom tool?
我通过自定义工具插件在 Jenkins 中定义了一个自定义工具。如果我创建自由式项目,Install custom tools
选项会在执行期间正确找到并使用工具 (Salesforce DX)。
但是,我找不到通过管道文件执行相同操作的方法。我已经使用管道语法片段生成器来获取:
tool name: 'sfdx', type: 'com.cloudbees.jenkins.plugins.customtools.CustomTool'
我已将其放入阶段定义中:
stage('FetchMetadata') {
print 'Collect Prod metadata via SFDX'
tool name: 'sfdx', type: 'com.cloudbees.jenkins.plugins.customtools.CustomTool'
sh('sfdx force:mdapi:retrieve -r metadata/ -u DevHub -k ./metadata/package.xml')
}
但我收到一条错误消息,指出 line 2: sfdx: command not found
我应该以其他方式使用此代码段吗?
完整的 Jenkinsfile 信息:
node {
currentBuild.result = 'SUCCESS'`
try {
stage('CheckoutRepo') {
print 'Get the latest code from the MASTER branch'
checkout scm
}
stage('FetchMetadata') {
print 'Collect Prod metadata via SFDX'
tool name: 'sfdx', type: 'com.cloudbees.jenkins.plugins.customtools.CustomTool'
sh('sfdx force:mdapi:retrieve -r metadata/ -u DevHub -k ./metadata/package.xml')
}
stage('ConvertMetadata') {
print 'Unzip retrieved metadata file'
sh('unzip unpackaged.zip .')
print 'Convert metadata to SFDX format'
sh('/usr/local/bin/sfdx force:mdapi:convert -r metadata/unpackaged/ -d force-app/')
}
stage('CommitChanges') {
sh('git add --all')
print 'Check if any changes need committing'
sh('if ! git diff-index --quiet HEAD --; then echo "changes found - pushing to repo"; git commit -m "Autocommit from Prod @ $(date +%H:%M:%S\' \'%d/%m/%Y)"; else echo "no changes found"; fi')
sshagent(['xxx-xxx-xxx-xxx']) {
sh('git push -u origin master')
}
}
}
catch (err) {
currentBuild.result = 'FAILURE'
print 'Build failed'
error(err)
}
}
更新
我使用 this example Jenkinsfile 取得了一些进展
我的舞台现在是这样的:
stage('FetchMetadata') {
print 'Collect Prod metadata via SFDX'
def sfdxLoc = tool 'sfdx'
sh script: "cd topLevel; ${sfdxLoc}/sfdx force:mdapi:retrieve -r metadata/ -u DevHub -k ./metadata/package.xml"
}
不幸的是,虽然看起来 Jenkins 现在正在寻找 运行 sfdx 工具,但我收到一个新错误:
TypeError: Cannot read property 'run' of undefined
at Object.<anonymous> (/var/lib/jenkins/.cache/sfdx/tmp/heroku-script-509584048:20:4)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.runMain (module.js:604:10)
at run (bootstrap_node.js:394:7)
at startup (bootstrap_node.js:149:9)
at bootstrap_node.js:509:3
如果您使用的是 Windows,您可能会因为 sfdx 安装文件夹的路径而遇到问题。 Dreamhouse Jenkinsfile 是为 linux shell 或 Mac 终端编写的,因此需要进行一些更改才能使其在 Windows 上运行。
${sfdxLoc}/sfdx
应该是
\"${sfdxLoc}/sfdx\"
以便命令行正确处理任何空格。
https://wipdeveloper.com/2017/06/22/salesforce-dx-jenkins-jenkinsfile/
我运行陷入同样的问题。我得到了这个解决方法:
environment {
GROOVY_HOME = tool name: 'Groovy-2.4.9', type: 'hudson.plugins.groovy.GroovyInstallation'
}
stages {
stage('Run Groovy') {
steps {
bat "${groovy_home}/bin/groovy <script.name>"
}
}
}
默认情况下,工具路径未添加到 PATH
(这是我 1.6 Jenkins 服务器安装的习惯)。在执行 bat 命令时添加 ${groovy_home}
可以解决这个问题。
这种调用工具的方式基本上是从脚本化管道语法借来的。
我将它用于我所有的自定义工具(不仅是 groovy)。
工具部分:
tool name: 'Groovy-2.4.9', type: 'hudson.plugins.groovy.GroovyInstallation'
像您一样由代码段生成器生成。
根据 Jenkins users mailing list,最终解决方案的工作仍在进行中,因此我的解决方案确实是一个解决方案。
这是我第一次评论堆栈溢出,但几天来我一直在寻找这个答案,我认为我有一个潜在的解决方案。查看 Fholst 答案,我想对其进行扩展。我认为该环境节可能适用于声明性语法,但在脚本化管道上,您必须使用等效的 withEnv(),并通过 gString 传入工具:即 ${tool 'nameOfToolDefinedInGlobalTools'}。对于我的特定用例,出于我无法控制的原因,我们没有在我们的 jenkins 主机上安装 maven,但是在全局工具配置中定义了一个。这意味着我需要在我的步骤中执行我的 sh 命令之前将 mvn 添加到路径中。我能做的是:
withEnv(["PATH+MVN=${tool 'NameOfMavenTool'}/bin"]){
sh '''
echo "PATH = ${PATH}"
'''
}
这应该能满足您的需求。请忽略 sh 行上的三重单引号,我实际上加载了几个环境变量,只是从我的代码片段中删除了它们。
希望这对那些多年来一直在寻找此解决方案的人有所帮助。我感觉到你的痛苦。通过查看声明性管道脚本的控制台输出(如果您使用 tools{} 节,它将向您展示它如何构建这些环境变量并包装您的后续声明性步骤)和以下 link:https://go.cloudbees.com/docs/cloudbees-documentation/use/automating-projects/jenkinsfile/
我通过自定义工具插件在 Jenkins 中定义了一个自定义工具。如果我创建自由式项目,Install custom tools
选项会在执行期间正确找到并使用工具 (Salesforce DX)。
但是,我找不到通过管道文件执行相同操作的方法。我已经使用管道语法片段生成器来获取:
tool name: 'sfdx', type: 'com.cloudbees.jenkins.plugins.customtools.CustomTool'
我已将其放入阶段定义中:
stage('FetchMetadata') {
print 'Collect Prod metadata via SFDX'
tool name: 'sfdx', type: 'com.cloudbees.jenkins.plugins.customtools.CustomTool'
sh('sfdx force:mdapi:retrieve -r metadata/ -u DevHub -k ./metadata/package.xml')
}
但我收到一条错误消息,指出 line 2: sfdx: command not found
我应该以其他方式使用此代码段吗?
完整的 Jenkinsfile 信息:
node {
currentBuild.result = 'SUCCESS'`
try {
stage('CheckoutRepo') {
print 'Get the latest code from the MASTER branch'
checkout scm
}
stage('FetchMetadata') {
print 'Collect Prod metadata via SFDX'
tool name: 'sfdx', type: 'com.cloudbees.jenkins.plugins.customtools.CustomTool'
sh('sfdx force:mdapi:retrieve -r metadata/ -u DevHub -k ./metadata/package.xml')
}
stage('ConvertMetadata') {
print 'Unzip retrieved metadata file'
sh('unzip unpackaged.zip .')
print 'Convert metadata to SFDX format'
sh('/usr/local/bin/sfdx force:mdapi:convert -r metadata/unpackaged/ -d force-app/')
}
stage('CommitChanges') {
sh('git add --all')
print 'Check if any changes need committing'
sh('if ! git diff-index --quiet HEAD --; then echo "changes found - pushing to repo"; git commit -m "Autocommit from Prod @ $(date +%H:%M:%S\' \'%d/%m/%Y)"; else echo "no changes found"; fi')
sshagent(['xxx-xxx-xxx-xxx']) {
sh('git push -u origin master')
}
}
}
catch (err) {
currentBuild.result = 'FAILURE'
print 'Build failed'
error(err)
}
}
更新 我使用 this example Jenkinsfile 取得了一些进展 我的舞台现在是这样的:
stage('FetchMetadata') {
print 'Collect Prod metadata via SFDX'
def sfdxLoc = tool 'sfdx'
sh script: "cd topLevel; ${sfdxLoc}/sfdx force:mdapi:retrieve -r metadata/ -u DevHub -k ./metadata/package.xml"
}
不幸的是,虽然看起来 Jenkins 现在正在寻找 运行 sfdx 工具,但我收到一个新错误:
TypeError: Cannot read property 'run' of undefined
at Object.<anonymous> (/var/lib/jenkins/.cache/sfdx/tmp/heroku-script-509584048:20:4)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.runMain (module.js:604:10)
at run (bootstrap_node.js:394:7)
at startup (bootstrap_node.js:149:9)
at bootstrap_node.js:509:3
如果您使用的是 Windows,您可能会因为 sfdx 安装文件夹的路径而遇到问题。 Dreamhouse Jenkinsfile 是为 linux shell 或 Mac 终端编写的,因此需要进行一些更改才能使其在 Windows 上运行。
${sfdxLoc}/sfdx
应该是
\"${sfdxLoc}/sfdx\"
以便命令行正确处理任何空格。
https://wipdeveloper.com/2017/06/22/salesforce-dx-jenkins-jenkinsfile/
我运行陷入同样的问题。我得到了这个解决方法:
environment {
GROOVY_HOME = tool name: 'Groovy-2.4.9', type: 'hudson.plugins.groovy.GroovyInstallation'
}
stages {
stage('Run Groovy') {
steps {
bat "${groovy_home}/bin/groovy <script.name>"
}
}
}
默认情况下,工具路径未添加到 PATH
(这是我 1.6 Jenkins 服务器安装的习惯)。在执行 bat 命令时添加 ${groovy_home}
可以解决这个问题。
这种调用工具的方式基本上是从脚本化管道语法借来的。
我将它用于我所有的自定义工具(不仅是 groovy)。
工具部分:
tool name: 'Groovy-2.4.9', type: 'hudson.plugins.groovy.GroovyInstallation'
像您一样由代码段生成器生成。
根据 Jenkins users mailing list,最终解决方案的工作仍在进行中,因此我的解决方案确实是一个解决方案。
这是我第一次评论堆栈溢出,但几天来我一直在寻找这个答案,我认为我有一个潜在的解决方案。查看 Fholst 答案,我想对其进行扩展。我认为该环境节可能适用于声明性语法,但在脚本化管道上,您必须使用等效的 withEnv(),并通过 gString 传入工具:即 ${tool 'nameOfToolDefinedInGlobalTools'}。对于我的特定用例,出于我无法控制的原因,我们没有在我们的 jenkins 主机上安装 maven,但是在全局工具配置中定义了一个。这意味着我需要在我的步骤中执行我的 sh 命令之前将 mvn 添加到路径中。我能做的是:
withEnv(["PATH+MVN=${tool 'NameOfMavenTool'}/bin"]){
sh '''
echo "PATH = ${PATH}"
'''
}
这应该能满足您的需求。请忽略 sh 行上的三重单引号,我实际上加载了几个环境变量,只是从我的代码片段中删除了它们。
希望这对那些多年来一直在寻找此解决方案的人有所帮助。我感觉到你的痛苦。通过查看声明性管道脚本的控制台输出(如果您使用 tools{} 节,它将向您展示它如何构建这些环境变量并包装您的后续声明性步骤)和以下 link:https://go.cloudbees.com/docs/cloudbees-documentation/use/automating-projects/jenkinsfile/