3

2 Jenkins jobs: A and B.

A triggers B as blocking build step ("Block until the triggered projects finish their builds"). Is there a way to include B's console output into A's console output?

Motivation: for browser use of Jenkins A's console output contains a link to B's console output which is fine. But when using Jenkins via command line tools (jenkins-cli) there's no quick and easy way to see B's console output.

Any ideas?

tshepang
  • 12,111
  • 21
  • 91
  • 136
user2124712
  • 161
  • 2
  • 13
  • See [my answer](http://stackoverflow.com/a/31573477/1744774) to [Output the console text of a Jenkins job that my Job is running](http://stackoverflow.com/questions/31521030/output-the-console-text-of-a-jenkins-job-that-my-job-is-running). – Gerold Broser Aug 02 '15 at 16:40

2 Answers2

1

Interesting. I'd try something like this.

From http://jenkinsurl/job/jobname/lastBuild/api/

Accessing Progressive Console Output
You can retrieve in-progress console output by making repeated GET requests with a parameter. You'll basically send GET request to this URL (or this URL if you want HTML that can be put into tag.) The start parameter controls the byte offset of where you start.

The response will contain a chunk of the console output, as well as the X-Text-Size header that represents the bytes offset (of the raw log file). This is the number you want to use as the start parameter for the next call.

If the response also contains the X-More-Data: true header, the server is indicating that the build is in progress, and you need to repeat the request after some delay. The Jenkins UI waits 5 seconds before making the next call. When this header is not present, you know that you've retrieved all the data and the build is complete.

So you can trigger a downstream job, but don't "block until downstream completes". Instead, add an extra step (execute shell, probably) and write a script that will read the console output of the other job as indicated above, and display it in console output of current job. You will have to detect when the child job finished by looking for X-More-Data: true header, as detailed above.

Slav
  • 27,057
  • 11
  • 80
  • 104
0

I know this is an old question, but i had to this myself recently. I figure this would help someone else looking to do the same. Here's a Groovy script that will read a given job's progressiveText URL. The code is written in such a way that it should be plug and play. Make sure to set the jenkinsBase and jobName first. The approach is no different to what has already been mentioned.

Here's a short set of instructions on how to use this: (1) Configure downstream job so that anonymous users hasRead and ViewStatus rights. (2) In the upstream job, create a Trigger/call builds on other projects step that will call the downstream job. (3) Do not check the "Block until the triggered projects finish their builds. (4) Right after that step, create an Execute Groovy script step and paste the following code:

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()) 
}

This script can be further improved by programatically getting the downstream job number.

There is also a Python version of this approach here.

t3knoid
  • 23
  • 3