无法通过DSL(groovy)在Jenkins管道作业中存储sh命令输出

5
我想在Jenkins管道作业中获取上一次构建的输出,并将其附加在电子邮件中(使用emailext插件)。 Curl运行良好并提供正确的构建输出,但我无法将其存储在变量中以便附加到电子邮件中。 我正在使用最新的jenkins版本。
我可以看到有几篇相关的帖子关于简单的sh命令,但是对于curl响应存储,那些方法不起作用。
尝试过的代码:
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

https://dev59.com/N1oV5IYBdhLWcg3wN8hD - tim_yates
很抱歉,我尝试过这些方法并阅读了这篇文章,但它不起作用,构建失败后也无法执行下一行。感谢Tim! - Jitesh Sojitra
你的第一种方法应该能得到正确的结果,只是不要重新定义变量。 - iloahz
嗯,使用echo命令好像有误。我再试一次... - Jitesh Sojitra
可能需要查看您脚本中更多的上下文。问题可能不仅仅存在于这行代码。 - David M. Karr
这里有任何更新吗?我遇到了类似的问题。 - Japster24
1个回答

6

看起来您缺少内部数组以及运行脚本所需的一些双引号和转义双引号:

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

此外,有多种方法可以编写shell脚本,这取决于您使用的Jenkins流水线类型。在Jenkins声明性流水线中,您需要为所有脚本类型的代码和设置变量包含一个script {...}块,它看起来像这样:
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
                 )
            }
        }
    }

Jenkins脚本管道中,您不需要script{}块,实际上可以将其放置在大多数位置。我通常将其放置在阶段块stage('some stage'){...}中,并且我是这样做的:
V5_DIR = WORKSPACE + '/' + sh([script: "basename ${V5_GIT_URL} .git", returnStdout: true]).trim()

尽管我也使用过curl命令(用于脚本化流水线),但我不需要内部数组...
lastSuccessfulCommit = sh(
     script: "curl -sL --user ${JENKINS_API_USER}:${JENKINS_API_PSW} \"${lastSuccessfulCommitUrl}\" | sed -e 's/<[^>]*>//g'",
     returnStdout: true
)

作为参考,在这两个环境中,回显变量的样子如下:

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

希望这份文档也能有所帮助,但我知道最近 Jenkins 的文档可能相当不足,因此我还找到了一篇关于如何避免在 Jenkins Declarative pipelines 中犯错的很棒的要点总结。祝你好运!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接