【发布时间】:2014-04-03 10:03:22
【问题描述】:
2 个 Jenkins 工作:A 和 B。
A 触发 B 作为阻塞构建步骤(“阻塞直到触发的项目完成构建”)。有没有办法将 B 的控制台输出包含到 A 的控制台输出中?
动机:浏览器使用 Jenkins A 的控制台输出包含一个指向 B 控制台输出的链接,这很好。但是当通过命令行工具 (jenkins-cli) 使用 Jenkins 时,没有快速简便的方法来查看 B 的控制台输出。
有什么想法吗?
【问题讨论】:
2 个 Jenkins 工作:A 和 B。
A 触发 B 作为阻塞构建步骤(“阻塞直到触发的项目完成构建”)。有没有办法将 B 的控制台输出包含到 A 的控制台输出中?
动机:浏览器使用 Jenkins A 的控制台输出包含一个指向 B 控制台输出的链接,这很好。但是当通过命令行工具 (jenkins-cli) 使用 Jenkins 时,没有快速简便的方法来查看 B 的控制台输出。
有什么想法吗?
【问题讨论】:
有趣。我会尝试这样的。
来自http://jenkinsurl/job/jobname/lastBuild/api/
访问渐进式控制台输出
您可以通过使用参数发出重复的 GET 请求来检索正在进行的控制台输出。你基本上会向这个 URL 发送 GET 请求(或者这个 URL,如果你想要可以放入标签的 HTML。) start 参数控制你开始的字节偏移量。响应将包含一部分控制台输出,以及表示字节偏移量的 X-Text-Size 标头(原始日志文件的)。这是您要用作下一次调用的开始参数的数字。
如果响应还包含 X-More-Data: true 标头,则服务器指示构建正在进行中,您需要在延迟一段时间后重复请求。 Jenkins UI 会等待 5 秒,然后再进行下一次调用。当此标头不存在时,您知道您已检索到所有数据并且构建已完成。
因此您可以触发下游作业,但不要“阻塞直到下游完成”。相反,添加一个额外的步骤(可能是execute shell)并编写一个脚本,该脚本将读取另一个作业的控制台输出,如上所示,并将其显示在当前作业的控制台输出中。您必须通过查找 X-More-Data: true 标头来检测子作业何时完成,如上所述。
【讨论】:
我知道这是一个老问题,但我最近自己不得不这样做。我认为这会帮助其他想要做同样事情的人。这是一个 Groovy 脚本,它将读取给定作业的progressiveText URL。代码的编写方式应该是即插即用的。确保首先设置 jenkinsBase 和 jobName。该方法与已经提到的方法没有什么不同。
以下是关于如何使用它的简短说明: (1) 配置下游作业,以便匿名用户具有读取和查看状态权限。 (2) 在上游作业中,在将调用下游作业的其他项目步骤上创建触发器/调用构建。 (3) 在触发的项目完成构建之前不要选中“阻塞。(4) 在该步骤之后,创建一个 Execute Groovy 脚本步骤并粘贴以下代码:
def jenkinsBase = // Set to Jenkins base URL here
def jobName = // Set to jenkins job name
def jobNumber = 'lastBuild' // Tail last build
def address = null
def response = null
def start = 0 // Start at offset 0
def cont = true // This semaphore holds the value of X-More-Data header value
try {
while (cont == true) { // Loop while X-More-Data value is equal to true
address = "${jenkinsBase}/job/${jobName}/${jobNumber}/logText/progressiveText?start=${start}"
def urlInfo = address.toURL()
response = urlInfo.openConnection()
if (response.getResponseCode() != 200) {
throw new Exception("Unable to connect to " + address) // Throw an exception to get out of loop if response is anything but 200
}
if (start != response.getHeaderField('X-Text-Size')) { // Print content if the starting offset is not equal the value of X-Text-Size header
response.getInputStream().getText().eachLine { line ->
println(line)
}
}
start = response.getHeaderField('X-Text-Size') // Set new start offset to next byte
cont = response.getHeaderField('X-More-Data') // Set semaphore to value of X-More-Data field. If this is anything but true, we will fall out of while loop
sleep(3000) // wait for 3 seconds
}
}
catch (Exception ex) {
println (ex.getMessage())
}
可以通过以编程方式获取下游作业编号来进一步改进此脚本。
这种方法还有一个 Python 版本here。
【讨论】: