运行Shell脚本时如何在Jenkins中将构建标记为不稳定


93

在我正在研究的项目中,我们正在使用Shell脚本执行不同的任务。有些是运行rsync的sh / bash脚本,有些是PHP脚本。PHP脚本之一正在运行一些集成测试,这些测试将输出到JUnit XML,代码覆盖率报告等。

Jenkins能够根据退出状态将作业标记为成功/失败。在PHP中,如果脚本在运行期间检测到测试失败,则以1退出。其他shell脚本运行命令并使用其中的退出代码将构建标记为失败。

// :: End of PHP script:
// If any tests have failed, fail the build
if ($build_error) exit(1);

Jenkins术语中,不稳定的构建定义为:

如果构建成功构建,并且一个或多个发布者报告该构建不稳定,则该构建不稳定。例如,如果配置了JUnit发布者并且测试失败,则将构建标记为不稳定。

运行Shell脚本时,如何让Jenkins将构建标记为不稳定,而不仅仅是成功/失败?


我achived运行它指出错误的作业步骤,并使用詹金斯插件stackoverflow.com/questions/25442343/...
fantastory

Answers:


58

使用Text-finder插件。

而不是退出状态1(这将使构建失败),请执行以下操作:

if ($build_error) print("TESTS FAILED!");

在生成后操作中,启用文本查找器,设置正则表达式以匹配您打印的消息(TESTS FAILED!),然后选中该条目下的“如果找到则不稳定”复选框。


2
自jenkins 2.26版以来,请参见以下答案以获取未安装插件的选项:stackoverflow.com/a/49676269/1347649
JSoet18年

61

现代的Jenkins版本(自2016年10月2.26起)解决了这个问题:这只是Execute shell构建步骤的高级选项!

退出构建代码

您可以选择并设置一个任意的退出值。如果匹配,构建将不稳定。只需选择一个不可能由您的构建中的实际过程启动的值即可。


我喜欢这个选项,因为它不需要您安装任何其他插件
Mattherman'5

2
由于这是最新的詹金斯(Jenkins)实施的-这应该是一个可以接受的答案
smoke_lp

3
“现代Jenkins版本”是指Jenkins 2.26或更高版本。参见issue.jenkins-ci.org/browse/JENKINS-23786
蓝色

5
shJenkinsfile?中使用step命令时,是否可以通过代码指定此代码?GUI中的设置在哪里?我找不到它了。
bluenote10 '19

1
我必须在构建步骤下单击打开“高级...”按钮以显示此内容。将单个(不是特别高级的)选项隐藏在“单击此处执行操作”折叠器的后面不是很有用,但是就是这样。
三人房

57

无需打印魔术字符串和使用TextFinder即可完成。这是一些信息。

基本上,您需要一个http:// yourserver.com / cli中的.jar文件(可在Shell脚本中找到),然后可以使用以下命令将构建标记为不稳定:

java -jar jenkins-cli.jar set-build-result unstable

要在错误时标记构建不稳定,可以使用:

failing_cmd cmd_args || java -jar jenkins-cli.jar set-build-result unstable

问题是必须从shell脚本中获得jenkins-cli.jar。您可以将其放在易于访问的路径中,也可以通过job的shell脚本进行下载:

wget ${JENKINS_URL}jnlpJars/jenkins-cli.jar

2
我真的很喜欢这个解决方案,为此我实现了一个ruby类,以便在我的rakefiles中轻松重用。:)
夏尔

3
+1-比接受的答案更好的解决方案,因为“文本查找器”每个作业只能搜索一个字符串,因此您只能将构建状态设置为两个值之一。
gareth_bowles13年

4
有趣的解决方案。但是,如果您的Jenkins需要身份验证,则需要在其配置中设置公钥身份验证,否则任何jenkins-cli命令都会失败,并出现AccessDeniedException。
汤姆·德吕

2
如果您使用的是无法通过网络访问主服务器的从服务器,则此方法将无效。例如,如果Jenkins从服务器无法创建返回到服务器的HTTP或HTTPS连接。
史蒂夫HHH

3
我想使用此解决方案,但set-build-result已在中弃用jenkins-cli
DrLime2k10

27

您应该使用Jenkinsfile来包装您的构建脚本,并使用来简单地将当前构建标记为UNSTABLE currentBuild.result = "UNSTABLE"

   阶段{
      状态= / *您的构建命令转到此处* /
      if(状态===“ MARK-AS-UNSTABLE”){
        currentBuild.result =“不稳定”
      }
   }

3
为什么这个答案没有更多支持?它有什么问题(使用“ magic”字符串UNSTABLE除外)吗?看来比其他答案更直接。
凯文

2
问题是关于自由式工作,而这个答案是关于管道工作。管道答案不适用于自由式工作
马克·怀特

这怎么工作?我收到一个错误:Expected one of "steps", "stages", or "parallel" for stage尝试在舞台内直接设置currentBuild.result时。
dokaspar


6

在我的作业脚本中,我有以下语句(此作业仅在Jenkins主服务器上运行):

# This is the condition test I use to set the build status as UNSTABLE
if [ ${PERCENTAGE} -gt 80 -a ${PERCENTAGE} -lt 90 ]; then
  echo WARNING: disc usage percentage above 80%

  # Download the Jenkins CLI JAR:
  curl -o jenkins-cli.jar ${JENKINS_URL}/jnlpJars/jenkins-cli.jar

  # Set build status to unstable
  java -jar jenkins-cli.jar -s ${JENKINS_URL}/ set-build-result unstable

fi

您可以在Jenkins Wiki上看到这一点以及有关设置构建状态的更多信息:https : //wiki.jenkins-ci.org/display/JENKINS/Jenkins+CLI


4
  1. 配置PHP构建以生成xml junit报告

    <phpunit bootstrap="tests/bootstrap.php" colors="true" >
       <logging>
           <log type="junit" target="build/junit.xml" 
               logIncompleteSkipped="false" title="Test Results"/>
       </logging>
    
       ....
    
     </phpunit>
  2. 完成状态为0的构建脚本

    ...
    exit 0;
  3. 添加构建后操作为测试报告XML 发布JUnit测试结果报告。测试失败时,此插件会将“稳定版本”更改为“不稳定”。

    **/build/junit.xml
  4. 添加具有控制台输出扫描和未选中选项的Jenkins Text Finder插件。此插件在致命错误上导致整个构建失败。

    PHP Fatal error:

3

我发现最灵活的方法是通过读取groovy post build插件中的文件。 在此处输入图片说明

import hudson.FilePath
import java.io.InputStream

def build = Thread.currentThread().executable

String unstable = null
if(build.workspace.isRemote()) {
    channel = build.workspace.channel;
    fp = new FilePath(channel, build.workspace.toString() + "/build.properties")
    InputStream is = fp.read()
    unstable = is.text.trim()
} else {
    fp = new FilePath(new File(build.workspace.toString() + "/build.properties"))
    InputStream is = fp.read()
    unstable = is.text.trim()
}

manager.listener.logger.println("Build status file: " + unstable)
if (unstable.equalsIgnoreCase('true')) {
    manager.listener.logger.println('setting build to unstable')
    manager.buildUnstable()
}

如果文件内容为“ true”,则构建将设置为不稳定。这将在运行该作业的本地主服务器和任何从属服务器上运行,并且适用于可以写入磁盘的任何类型的脚本。


我假设这确实表明“如果工作空间中有一个名为build.properties的文件”,则标记为不稳定。那正确吗?我是Groovy的新手,您可以介意进一步解释一下吗?
uchuugaka '16

@uchuugaka是的,如果有文件并且包含这些内容。文件名和内容是任意的。使用适合您情况的任何东西。
jeremyjjbrown

谢谢!很有帮助。Groovy Postbuild是相当间接的,Groovy从Java中吸取了大量的东西并增加了更多……这对我来说是个新技巧。
uchuugaka '16

@uchuugaka我不认为这是groovy的问题:)
jeremyjjbrown

完全没有问题。只是一个挑战!
uchuugaka '16

2

仅当作业状态未从“成功”更改为“失败”或“中止”时,TextFinder才是好的。对于这种情况,请在PostBuild步骤中使用常规脚本:

errpattern = ~/TEXT-TO-LOOK-FOR-IN-JENKINS-BUILD-OUTPUT.*/;
manager.build.logFile.eachLine{ line ->
    errmatcher=errpattern.matcher(line)
    if (errmatcher.find()) {
        manager.build.@result = hudson.model.Result.NEW-STATUS-TO-SET
    }
 }

在我写过的帖子中查看更多详细信息:http : //www.tikalk.com/devops/JenkinsJobStatusChange/


2

这里复制我的答案,因为我花了一些时间寻找这个:

现在可以在更新版本的Jenkins中实现,您可以执行以下操作:

#!/usr/bin/env groovy

properties([
  parameters([string(name: 'foo', defaultValue: 'bar', description: 'Fails job if not bar (unstable if bar)')]),
])


stage('Stage 1') {
  node('parent'){
    def ret = sh(
      returnStatus: true, // This is the key bit!
      script: '''if [ "$foo" = bar ]; then exit 2; else exit 1; fi'''
    )
    // ret can be any number/range, does not have to be 2.
    if (ret == 2) {
      currentBuild.result = 'UNSTABLE'
    } else if (ret != 0) {
      currentBuild.result = 'FAILURE'
      // If you do not manually error the status will be set to "failed", but the
      // pipeline will still run the next stage.
      error("Stage 1 failed with exit code ${ret}")
    }
  }
}

管道语法生成器在“高级”选项卡中向您显示:

管道语法示例


2

我以为我会为可能正在寻找类似内容的人们发布另一个答案。

在构建工作中,有些情况下我们希望构建继续进行,但被标记为不稳定。对于我们来说,它与版本号有关。

因此,我想在构建中设置一个条件,如果满足该条件,则将构建设置为不稳定。

我将条件步骤(单个)选项用作构建步骤。

然后,我使用Execute system Groovy脚本作为满足该条件时将运行的构建步骤。

我使用了Groovy Command并将脚本设置如下

import hudson.model.*

def build = Thread.currentThread().executable
build.@result = hudson.model.Result.UNSTABLE

return

看来效果很好。

我在这里偶然发现了解决方案

http://tech.akom.net/archives/112-Marking-Jenkins-build-UNSTABLE-from-environment-inject-groovy-script.html


1

作为现有答案的替代方案,您可以使用简单的HTTP POST设置构建结果来访问Groovy脚本控制台REST API

    curl -X POST \
     --silent \
     --user "$YOUR_CREDENTIALS" \
     --data-urlencode "script=Jenkins.instance.getItemByFullName( '$JOB_NAME' ).getBuildByNumber( $BUILD_NUMBER ).setResult( hudson.model.Result.UNSTABLE )" $JENKINS_URL/scriptText

优点:

  • 无需下载并运行巨大的jar文件
  • 无需设置和读取某些全局状态(控制台文本,工作区中的文件)
  • 无需插件(Groovy除外)
  • 无需配置在“通过”或“失败”情况下多余的额外构建步骤。

对于此解决方案,您的环境必须满足以下条件:

  • Jenkins REST API可以从奴隶访问
  • 从站必须有权访问允许访问Jenkins Groovy脚本REST API的凭据。

0

将构建设置为不稳定的一种简单方法是在“ execute shell”块中运行 exit 13


-3

您可以只调用“ exit 1”,此时构建将失败并且无法继续。我结束了一个passthrough make函数来为我处理它,然后调用safemake而不是make来构建:

function safemake {
  make "$@"
  if [ "$?" -ne 0 ]; then
    echo "ERROR: BUILD FAILED"
    exit 1
  else
    echo "BUILD SUCCEEDED"
  fi
}

11
据我所知,出口1仅会使构建失败。我不希望构建失败,我希望它被标记为不稳定。
HNygard 2012年

1
另请参见stackoverflow.com/questions/36313216/…-简单的解决方案是if make "$@"; then echo "BUILD SUCCEEDED"; else rc=$?; echo "BUILD FAILED"; exit $rc; fi
Tripleee
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.