我正在尝试通过运行诸如以下命令之类的shell命令从从属服务器获取某些值:
git rev-parse HEAD
git config --get remote.origin.url
我为此尝试编写的方法是:
def executeCommand(String command) {
stdout = sh script: command, returnStdout: true
return stdout.trim()
}
现在,当我尝试运行第一个命令时:
output = executeCommand('git rev-parse HEAD')
我收到错误消息:
[Running] groovy "/Users/user-a/Documents/cmd.groovy"
Caught: groovy.lang.MissingMethodException: No signature of method: cmd.sh() is applicable for argument types: (LinkedHashMap) values: [[script:git rev-parse HEAD, returnStdout:true]]
Possible solutions: is(java.lang.Object), use([Ljava.lang.Object;), run(), run(), any(), tap(groovy.lang.Closure)
groovy.lang.MissingMethodException: No signature of method: cmd.sh() is applicable for argument types: (LinkedHashMap) values: [[script:git rev-parse HEAD, returnStdout:true]]
Possible solutions: is(java.lang.Object), use([Ljava.lang.Object;), run(), run(), any(), tap(groovy.lang.Closure)
at cmd.executeCommand(cmd.groovy:2)
at cmd.run(cmd.groovy:6)
我也尝试过:
output = command.execute().text
但这不会返回任何内容。
我对如何在Jenkins的Groovy中运行shell命令并记录输出的想法不多了。
更多详细信息
我正在与Jenkins共享库一起使用。我已经为Jenkinsfile
公开了一个名为getLatestBuildDetails()
的方法。此方法在我的库中定义。该方法中的动作之一是在本地执行git
命令。因此,为了在本地运行任何shell命令,我创建了executeCommand
函数,该函数将实际命令作为字符串运行并执行它,并返回输出以供getLatestBuildDetails()
答案 0 :(得分:1)
库类不能直接调用诸如sh或git之类的步骤。但是,他们可以实现封闭类范围之外的方法,这些方法进而调用管道步骤,例如:
// src/org/foo/Zot.groovy
package org.foo;
def checkOutFrom(repo) {
git url: "git@github.com:jenkinsci/${repo}"
}
return this
然后可以从脚本管道调用以下内容:
def z = new org.foo.Zot()
z.checkOutFrom(repo)
这种方法有局限性;例如,它阻止了超类的声明。
或者,可以使用此方法将一组步骤显式传递给库类,构造函数或仅一个方法:
package org.foo
class Utilities implements Serializable {
def steps
Utilities(steps) {this.steps = steps}
def mvn(args) {
steps.sh "${steps.tool 'Maven'}/bin/mvn -o ${args}"
}
}
当在类(如上述)上保存状态时,该类必须实现Serializable接口。这样可以确保使用该类的Pipeline(如下面的示例所示)可以在Jenkins中正确地暂停和恢复。
@Library('utils') import org.foo.Utilities
def utils = new Utilities(this)
node {
utils.mvn 'clean package'
}
如果库需要访问诸如env之类的全局变量,则应以类似的方式将这些变量显式传递到库类或方法中。
与其将脚本管道中的许多变量传递到库中,
package org.foo
class Utilities {
static def mvn(script, args) {
script.sh "${script.tool 'Maven'}/bin/mvn -s ${script.env.HOME}/jenkins.xml -o ${args}"
}
}
以上示例显示了将脚本传递到一个静态方法中的方法,该方法从“脚本管道”调用如下:
@Library('utils') import static org.foo.Utilities.*
node {
mvn this, 'clean package'
}
在您的情况下,您应该编写如下内容:
def getLatestBuildDetails(context){
//...
executeCommand(context, 'git rev-parse HEAD')
//...
}
def executeCommand(context, String command) {
stdout = script.sh(script: command, returnStdout: true)
return stdout.trim()
}
Jenkins文件:
@Library('library_name') _
getLatestBuildDetails(this)
有关更多信息,请参阅jenkins共享库文档:https://jenkins.io/doc/book/pipeline/shared-libraries/
答案 1 :(得分:-1)