Jenkins Pipeline Git 在 scm 签出之前提交消息



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

编辑:我正在使用脚本化的jenkins文件和带有多分支管道的共享库..所以我正在寻找一种以编程方式做到这一点的方法:)

由于我没有看到任何其他方法,因此我执行以下操作:

#!/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 服务器上的带宽,因为存储库只会在每个代理上克隆一次,然后复制到每个分支的其他目录。这对我来说是最有用的方法。如果您有任何疑问,请告诉我:)

编辑:我现在正在解析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 母版上执行此操作,希望对您有所帮助。

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

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

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

因此,基本上,您可以在SCM签出/克隆开始之前执行任何命令。

最新更新