scm checkout之前的Jenkins Pipeline Git提交消息

时间:2017-10-20 06:31:10

标签: git jenkins jenkins-pipeline

我希望能够在实际checkout scm之前访问Jenkins管道中的提交消息,因为我有大量存储库(> 2GB)和许多分支(> 200),并且对于每个分支都是完整的repo再次被克隆,我想通过过滤显式"标记的提交消息来限制克隆的数量。 (例如[ci])。如果您知道一种可以解决我的问题的不同方法,请告诉我。

编辑:我使用脚本化的jenkins文件和多分支管道的共享库..所以我正在寻找一种以编程方式执行此操作的方法:)

2 个答案:

答案 0 :(得分:4)

由于我没有看到任何其他方式,我做了以下事情:

#!/usr/bin/env groovy

def getCommitMsg(branch, path_parent, path_mirror, url) {
    if (!(fileExists(path_mirror))) {
        echo "Directory $path_mirror doesn't exist, creating.."
        dir (path_parent) {
            bat("git clone --mirror $url mirror")
        }
    }
    dir (path_mirror) {
        bat("git fetch origin $branch:$branch")
        bat("git symbolic-ref HEAD refs/heads/$branch")
        return bat(script: "@git log -n 1 --pretty=format:'%%s'",
            returnStdout: true).trim().replaceAll("'","")
    }
}

def updateRepo(branch, path_parent, path_clone, url) {
    if (!(fileExists(path_clone))) {
        echo "Directory $path_clone doesn't exist, creating.."
        dir (path_parent) {
            bat("git clone --recurse-submodules $url clone")
        }
    }
    dir (path_clone) {
        bat("git pull")
    }
    dir (path_parent) {
        bat(script: "robocopy /MIR /NFL /NDL /NC /NS /NP " +
            path_clone + " " + path_parent + "\\" + branch.replaceAll("/","_"),
            returnStatus: true)
    }
}

node("some_label") {

    ws("workspace/${env.JOB_NAME}".replaceAll("%2F","_")) {

        def default_test = ["develop", "release", "feature/test"]
        def branch = env.BRANCH_NAME
        def path_current = bat(script: 'echo %CD%',
            returnStdout: true).split("\n")[2]        
        def path_parent = path_current.split("\\\\").dropRight(1).join("\\")
        def path_mirror = path_parent + "\\mirror"
        def path_clone = path_parent + "\\clone"
        def url = scm.userRemoteConfigs[0].url
        def commit = getCommitMsg(branch, path_parent, path_mirror, url)

        if (!(default_test.contains(branch)
            || commit.contains("[ci]"))) {
            echo "Branch should not be tested by default and commit message contains no [ci]-tag, aborting.."
            currentBuild.result = "FAILURE"
            return
        }

        stage("Checkout") {
            updateRepo(branch, path_parent, path_clone, url)
            checkout scm
        }

        stage("Build") {
            some stuff here
            }
        }

    }

}

这将解析镜像仓库中的提交消息,并减少我的bitbucket服务器上的带宽,因为repo只会在每个代理上克隆一次,然后复制到每个分支的其他目录。这对我来说是最有用的方法。如果您有任何疑问,请告诉我们:)

编辑:我现在正在解析Bitbucket REST API,代码如下所示:

// get commit hash
withCredentials([sshUserPrivateKey(credentialsId: 'SSH',
    keyFileVariable: 'SSHKEYFILE')]) {
    String commitHash = sh(script: """
        ssh-agent bash -c 'ssh-add ${env.SSHKEYFILE}; \
        git ls-remote ${url} refs/heads/${branch}'""",
        returnStdout: true).trim().split('\\s+')[0]

    echo("commitHash: ${commitHash}")
}

// create the curl url like this
String curlUrl = BBUrl + '/rest/api/1.0/projects/' + project + '/repos/' + repo + '/commits/' + commitHash

String commitMessage = null
withCredentials([usernameColonPassword(credentialsId: 'USERPASS',
    variable: 'USER_PASS')]) {

    String pwBase64 = "${env.USER_PASS}".bytes.encodeBase64().toString()
    String rawResponse = sh(script: """
        curl --request GET --url '${curlUrl}' \
        --header 'Authorization: Basic ${pwBase64}'""",
        returnStdout: true).trim()

    def rawMessage = readJSON(text: rawResponse)
    commitMessage = rawMessage.message
    echo("commitMessage: ${commitMessage}")
}

只需在安装了curl的Jenkins master上执行此操作,希望它有所帮助..

答案 1 :(得分:1)

您可以使用pre-scm-buildstep插件

https://wiki.jenkins.io/display/JENKINS/pre-scm-buildstep

  

此插件允许构建步骤在SCM签出之前运行,以便您   在工作区上执行任何构建步骤操作,(清理,添加一个   文件与SCM的一些设置等)或调用其他脚本   需要在从SCM退房之前运行。

基本上,你可以在SCM checkout / clone开始之前执行任何命令。