使用Groovy确定Jenkins中的上游Git更改

时间:2018-01-30 17:54:53

标签: git groovy jenkins-pipeline

我们的CI / CD流程有多个存储库,可以触发单个下游作业来测试整个产品。

我知道当前的Jenkins构建我可以使用currentBuild.changeSets获取scm更改列表,然后我可以查看这些changeSet的所有items来确定提交消息,提交ID等

然而,从下游工作的角度来看,在完成Jenkins测试后,我希望能够提及所有已发生的上游变化。

Jenkins测试作业不允许并发构建。这意味着多个上游版本可能会触发单个Jenkins测试作业。

我认为我可以利用Reason来确定上游工作,但我真的不知道如何从那里去做更改工作。

    def upstreamChanges = ''

    def causes = currentBuild.rawBuild.causes

    if(causes && causes.upstreamCauses) { // upstream cause visibility
       def upstreamCauses = causes.upstreamCauses

        for (int i = 0; i < upstreamCauses.size; i++) {
            upstreamChanges += upstreamCauses[i].shortDescription
        }
    }

这至少给了我原因描述,但我宁愿让实际的currentBuild.changeSets可供我使用。

编辑: 我基本上需要一种方法来获取所有上游Build对象,如果我有那些​​我可以使用该构建的changeSets。

1 个答案:

答案 0 :(得分:1)

这很痛苦,弄清楚,不妨分享解决方案。

首先我们检查所有上游更改并添加它们,如果没有返回任何内容,我们会尝试获取currentBuild.changeSets或默认没有新的更改。

这里可能还有改进的空间......

 /**
 * The max commit message length
 */
final static int MAX_COMMIT_MSG_LEN = 100

 /**
 * Build the list of Changes triggering this Jenkins build, including any upstreams Jenkins jobs <br/>
 * @param s Current build object, it's a 'this' call from the pipeline
 * @return A string with all the changes in the current and upstream build, 'no new changes' is returned if empty
 */
static buildChangeList(s) {
    def changes = ''

    Run<?, ?> cur = s.currentBuild.rawBuild
    Cause.UpstreamCause upc = cur.getCause(Cause.UpstreamCause.class)
    while (upc != null) {
        Job<?, ?> p = (Job<?, ?>) Jenkins.getActiveInstance().getItemByFullName(upc.getUpstreamProject())
        if (p == null) {
            s.echo 'There is a break in the build linkage, could not retrieve upstream build information'
            break
        }
        cur = p.getBuildByNumber(upc.getUpstreamBuild());
        if (cur == null) {
            s.echo 'There is a break in the build linkage, could not retrieve upstream build information'
            break
        }
        changes += "\nJenkins Trigger Job - $upc.upstreamProject"
        changes +=  retrieveChangeSet(cur.changeSets)

        upc = cur.getCause(Cause.UpstreamCause.class)
    }

    if (!changes) { // no upstream changes at all, see if current build has any changes
        def currentBuildChanges = retrieveChangeSet(s.currentBuild.changeSets)

        changes = currentBuildChanges ?: '\n - No new changes'  // if no current build changes, use default message
    }
    return changes
}

/**
 * Retrieve all the change sets available. Include the git author, commit message and commit id
 * @param changeSets The changeSet object from Jenkins
 * @return A string with all the changes found within the change set
 */
static retrieveChangeSet(changeSets) {
    def changes = ''

    for (int i = 0; i < changeSets.size(); i++) {   // iterate through all the available change sets
        for (int j = 0; j < changeSets[i].items.length; j++) { // iterate through all the items of a single changeset
            def entry = changeSets[i].items[j]
            def commitmsg = entry.msg.take(MAX_COMMIT_MSG_LEN)
            changes += "\n[${entry.author}] - ${commitmsg}  -  Commit ${entry.commitId}"
        }
    }
    return changes
}

编辑:如果您在运行上述代码时遇到问题,则可能是导入问题。

import hudson.model.*
import hudson.util.*
import jenkins.model.*
import hudson.FilePath
import hudson.node_monitors.*
import java.time.LocalDateTime