0

I'm using in Jenkins 2.73.1, in a multibranch pipeline Copy Artifact Plugin to get the last successful artifacts from two other pipelines, see my Jenkinsfile:

def branchname = "${BRANCH_NAME}".replace("/", "%2F")
pipeline {
  agent {
    label 'windows'
  }
  stages {
    stage('get artifacts') {
      steps {
        script {
          parallel('get-backend': {
            step([$class: 'CopyArtifact', projectName: "backend/${branchname}", target: 'input/backend'])
          },
          'get-frontend': {
            step([$class: 'CopyArtifact', projectName: "frontend/${branchname}", target: 'input/frontend'])
          })
        }
      }
    }
  }
}

In the build log I see e.g.:

...
[Pipeline] script
[Pipeline] {
[Pipeline] parallel
[Pipeline] [get-backend] { (Branch: get-backend)
[Pipeline] [get-frontend] { (Branch: get-frontend)
[Pipeline] [get-backend] step
[Pipeline] [get-frontend] step
[get-frontend] Copied 344 artifacts from "frontend » foo/bar" build number 17
[Pipeline] [get-frontend] }
[get-backend] Copied 2'287 artifacts from "backend » foo/bar" build number 3
[Pipeline] [get-backend] }
[Pipeline] // parallel
[Pipeline] }
[Pipeline] // script
...

Question / Goal: I'd like to parse and save to a file (to be archived, then loaded and parsed by groovy in a different pipeline) the build number of frontend and backend (in the log see "build number 17" and "build number 3").

In the question Jenkins Pipeline - Reading previous stage log I read it's possible to redirect the standard output of an sh script into a groovy variable, like this:

def out = sh script: 'command', returnStdout: true

But in my pipeline I need to use windows, also the step in this case is not a command but it's a "step" (containing class "CopyArtifact", still new to Jenkins, I just made it work googling around and found some examples using this syntax).

How can I achieve my goal? Should I parse the entire log in this case or is there a more elegant solution? Please provide some code in your answer, so I can test it directly.

firepol
  • 1,731
  • 22
  • 39

2 Answers2

0

You cannot get the output of a Jenkins step, only the sh step allows it, but in this case you get the output or the inner sh (or bat) command.

However in your case it is pretty simple as you only need the other builds numbers, you can use Jenkins API, as described in this question:

def backendBuildId = sh script: "wget http://yourjenkinsurl/job/backend/${branchname}/lastSuccessfulBuild", returnStdout: true
def frontendBuildId = sh script: "wget http://yourjenkinsurl/job/frontend/${branchname}/lastSuccessfulBuild", returnStdout: true

For more details, please check the API details in your Jenkins.

Pom12
  • 7,622
  • 5
  • 50
  • 69
  • Depending on the timing and concurrency of jobs, this does have a possibility of a race condition. If the frontend or backend job happens to finish between the time the artifacts are copied and your wget runs, the results may not match. – Rob Hales Oct 06 '17 at 14:52
  • In my case I get these 2 artifacts in parallel and we don't really build them too often at the same time, so in our case it may work. Probably it's a good idea to run these 2 sh commands before the get step. – firepol Oct 06 '17 at 19:06
  • 1
    Your answer doesn't work, as I stated in my quesrion I'm using **Windows**, and calling the wget command as you specified above, using `sh` gives me this error: `java.io.IOException: CreateProcess error=2, The system cannot find the file specified [...] java.io.IOException: Cannot run program "nohup"`. Anyway, I tried with bat instead of sh, it fails because **Forbidden 403**: it needs authentication. Isn't there a smarter way to use the jenkins api, since it's running its own pipeline it doesn't make a lot of sense to authenticate again. It should use internal commands instead... – firepol Oct 09 '17 at 12:38
0

You could write the build number to a file in the upstream jobs and include that in the archive. Then you copy that artifact forward. You could use the pipeline utility steps plugin to gather information from the file, but if you keep the file simple (i.e. write nothing but the build number), then something like this would get you the build number:

def backendBuildId = sh script: "cat backendBuild.txt", returnStdout: true

or on Windows:

def backendBuildId = bat script: "type backendBuild.txt", returnStdout: true
Rob Hales
  • 5,123
  • 1
  • 21
  • 33
  • Given the issues (rest api not convenient in our setup, as we need authentication to access the URL, and gnu wget for windows doesn't seem to handle this properly), this was the best (and easiest to implement) answer for our case. – firepol Oct 12 '17 at 07:21