Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't store sh command output through DSL (groovy) in Jenkins pipeline job

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
like image 428
Jitesh Sojitra Avatar asked Dec 03 '16 10:12

Jitesh Sojitra


People also ask

What is SH in Jenkins pipeline?

On Linux, BSD, and Mac OS (Unix-like) systems, the sh step is used to execute a shell command in a Pipeline. Jenkinsfile (Declarative Pipeline) pipeline { agent any stages { stage('Build') { steps { sh 'echo "Hello World"' sh ''' echo "Multiline shell steps works too" ls -lah ''' } } } }

Is Jenkins DSL Groovy?

Jenkinsfiles, using a Domain Specific Language (DSL) based on the Groovy programming language, are persistent files that model delivery pipelines 'as code'.

How do I load Groovy script in Jenkins pipeline?

In Jenkinsfile, simply use load step to load the Groovy script. After the Groovy script is loaded, the functions insides can be used where it can be referenced, as shown above.


1 Answers

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: '[email protected]',
                    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!

like image 95
Wimateeka Avatar answered Sep 23 '22 14:09

Wimateeka