【问题标题】:include downstream/child Jenkins job's console output into triggering job's console output将下游/子 Jenkins 作业的控制台输出包含到触发作业的控制台输出中
【发布时间】:2014-04-03 10:03:22
【问题描述】:

2 个 Jenkins 工作:A 和 B。

A 触发 B 作为阻塞构建步骤(“阻塞直到触发的项目完成构建”)。有没有办法将 B 的控制台输出包含到 A 的控制台输出中?

动机:浏览器使用 Jenkins A 的控制台输出包含一个指向 B 控制台输出的链接,这很好。但是当通过命令行工具 (jenkins-cli) 使用 Jenkins 时,没有快速简便的方法来查看 B 的控制台输出。

有什么想法吗?

【问题讨论】:

标签: jenkins triggers console


【解决方案1】:

有趣。我会尝试这样的。

来自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 标头来检测子作业何时完成,如上所述。

【讨论】:

    【解决方案2】:

    我知道这是一个老问题,但我最近自己不得不这样做。我认为这会帮助其他想要做同样事情的人。这是一个 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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多