5

I would like to get last build output in pipeline Jenkins job and attach in email (using emailext plugin). Curl works fine and gives proper build output but i can't store in variable to attach in the email. I'm using latest jenkins version.

I can see there are couple of related posts for simple sh command but that doesn't work for curl response store.

Tried code:

1.

def consoleOutput = sh(returnStdout: true, script: 'curl http://' + jenkinsUser + ':' + jenkinsUserToken + '@' + jenkinsServer + ':8080/job/' + 'myJob/lastBuild/consoleText').trim()
echo consoleOutput

2.

sh 'curl http://' + jenkinsUser + ':' + jenkinsUserToken + '@' + jenkinsServer + ':8080/job/' + "${env.JOB_NAME}" + '/lastBuild/consoleText; echo $? > status'
def consoleOutput = readFile('status').trim()

3.

def consoleOutput = sh(script: 'curl http://' + jenkinsUser + ':' + jenkinsUserToken + '@' + jenkinsServer + ':8080/job/' + '/myJob/lastBuild/consoleText', returnStatus: true).split("\r?\n")
echo consoleOutput
halfer
  • 19,824
  • 17
  • 99
  • 186
Jitesh Sojitra
  • 3,655
  • 7
  • 27
  • 46

1 Answers1

6

It looks like you're missing the inner array and some double quotes and escaped double quotes for running the script:

sh([ script: "curl \"http://${jenkinsUser}:${jenkinsUserToken}@${jenkinsServer}:8080/job/myJob/lastBuild/consoleText\"").trim()

Also there are multiple ways to do shell scripts and it depends on the type of jenkins pipeline you are using.

In a jenkins declarative pipeline you need to include a script {...} block for all script type code and setting variables, and that would look like this:

pipeline { 
    agent {
        ...
    } 
    parameters {
        ...
    }
    environment {
   ...
   }
   stages {
        stage('Run Required Scripts') {
            steps {
               ...
                script {
                    NOTIFIER_BULD_NAME = sh([script: "./getNotifier.sh", returnStdout: true]).trim()
                    EMAIL_TEXT = sh([script: "./printEmailText.sh ${CURRENT_BUILD}  ${PREVIOUS_BUILD}", returnStdout: true]).trim()
                    BODY= sh([ script: "curl \"http://${jenkinsUser}:${jenkinsUserToken}@${jenkinsServer}:8080/job/myJob/lastBuild/consoleText\"").trim()
                }
            }
        }
        stage('Send Email') {
            when {
                expression {
                    // Only send when there is text.
                    "${EMAIL_TEXT}" != "";
                }
            }
            steps{
                emailext (
                    to: 'software@company.com',
                    subject: "You have mail - ${EMAIL_TEXT}",
                    body: """${NOTIFIER_BULD_NAME} - ${EMAIL_TEXT}: 
... 
${BODY}
""",
                     attachLog: false
                 )
            }
        }
    }

In a Jenkins scripted pipeline, you don't need a script{} block, you can actually put it most places. Mostly I've put it in stage blocks stage('some stage'){...} and I've done it like this:

V5_DIR = WORKSPACE + '/' + sh([script: "basename ${V5_GIT_URL} .git", returnStdout: true]).trim()

Although I've also used curl commands (for scripted pipelines) and didn't need the inner array...

lastSuccessfulCommit = sh(
     script: "curl -sL --user ${JENKINS_API_USER}:${JENKINS_API_PSW} \"${lastSuccessfulCommitUrl}\" | sed -e 's/<[^>]*>//g'",
     returnStdout: true
)

And for reference, echoing vars looks like this in both

 sh([script: "echo \"Value: ${someVariable}\""])

Hopefully this documentation helps a bit too, but I know recently Jenkins documentation can be pretty spotty, so I also found a great gist about how to not do things for Jenkins Declarative pipelines. Good luck!

Wimateeka
  • 2,474
  • 2
  • 16
  • 32