詹金斯,如何检查对另一份工作的回归

时间:2015-10-29 11:54:23

标签: jenkins jenkins-plugins

当您设置Jenkins作业时,如果最新版本比前一版本更差,各种测试结果插件将显示回归。

我们Jenkins的许多项目都有很多工作,我们希望避免设置“每个分支的工作”。因此,目前我们正在使用参数化构建来使用单个作业构建不同的开发分支。

但这意味着当我构建一个新分支时,任何回归都是根据之前的构建来衡量的,这可能是针对不同的分支。我真正想要的是测量功能分支中的回归与最新版本的分支。

我认为我们应该在参数化的'branches'构建旁边建立一个单独的'master'构建。但我还是看不出如何比较工作之间的结果。有没有可以提供帮助的插件?

更新

我已经开始在Script Console中进行试验,看看我是否可以编写一个构建后的脚本...我已经设法在我的参数化作业中获得最新版本的master分支...我无法弄清楚如何尽管从构建对象获得测试结果。

我需要的数据在JSON中可用 http://<jenkins server>/job/<job name>/<build number>/testReport/api/json?pretty=true

...如果我能够了解这个数据结构,那就太棒了!

我尝试使用JsonSlurper通过HTTP加载json,但我得到403,我想因为我的脚本没有auth会话。

我想我可以从磁盘加载xml测试结果并在我的脚本中解析它们,当Jenkins已经完成此操作时,它似乎有点愚蠢。

1 个答案:

答案 0 :(得分:5)

我最终使用Groovy Postbuild Plugin

中的Groovy脚本设法实现了我想要的一切

我使用脚本控制台http://<jenkins>/script进行了大量探索,Jenkins API class docs也很方便。

每个人的使用都会有所不同,因为你必须深入了解构建插件才能获得所需的信息,但这里有一些我的代码可能有所帮助。

首先获得您想要的构建:

def getProject(projectName) {
    // in a postbuild action use `manager.hudson`
    // in the script web console use `Jenkins.instance`
    def project = manager.hudson.getItemByFullName(projectName)
    if (!project) {
        throw new RuntimeException("Project not found: $projectName")
    }
    project
}

// CloudBees folder plugin is supported, you can use natural paths:
project = getProject('MyFolder/TestJob')

build = project.getLastCompletedBuild()

主要的测试结果(jUnit等)似乎可以直接在构建中使用:

result = build.getTestResultAction()
// eg
failedTestNames = result.getFailedTests().collect{ test ->
    test.getFullName()
}

要从Violations插件或Cobertura代码覆盖中获取更专业的结果,您必须寻找特定的构建操作。

// have a look what's available:
build.getActions()

您会看到以下内容列表:

[hudson.plugins.git.GitTagAction@2b4b8a1c,
 hudson.scm.SCMRevisionState$None@40d6dce2,
 hudson.tasks.junit.TestResultAction@39c99826,
 jenkins.plugins.show_build_parameters.ShowParametersBuildAction@4291d1a5]

这些是实例,@符号前面的部分是类名,因此我使用它来制作此方法以获取特定操作:

def final VIOLATIONS_ACTION = hudson.plugins.violations.ViolationsBuildAction
def final COVERAGE_ACTION = hudson.plugins.cobertura.CoberturaBuildAction

def getAction(build, actionCls) {
    def action = build.getActions().findResult { act ->
        actionCls.isInstance(act) ? act : null
    }
    if (!action) {
        throw new RuntimeException("Action not found in ${build.getFullDisplayName()}: ${actionCls.getSimpleName()}")
    }
    action
}

violations = getAction(build, VIOLATIONS_ACTION)

// you have to explore a bit more to find what you're interested in:
pylint_count = violations?.getReport()?.getViolations()?."pylint"

coverage = getAction(build, COVERAGE_ACTION)?.getResults()
// if you println it looks like a map but it's really an Enum of Ratio objects
// convert to something nicer to work with:
coverage_map = coverage.collectEntries { key, val -> [key.name(), val.getPercentageFloat()] }

通过这些构建模块,我能够整合一个构建后的脚本,比较两个不相关的&#39;构建作业,然后使用Groovy Postbuild插件的帮助程序方法来设置构建状态。

希望这有助于其他人。