简体   繁体   English

scm检出之前的Jenkins Pipeline Git提交消息

[英]Jenkins Pipeline Git commit message before scm checkout

I would like to be able to access the commit message in a Jenkins Pipeline before the actual checkout scm since I have huge repositories (>2GB) and many branches (>200) and for every branch the complete repo gets cloned again and I want to limit the amount of clones by filtering the commit messages for explicit "tags" (eg [ci] ). 我希望能够在实际checkout scm之前在Jenkins管道中访问提交消息,因为我有巨大的存储库(> 2GB)和许多分支(> 200),并且对于每个分支,完整的存储库都会再次克隆,我想通过过滤提交消息中的显式“标签”(例如[ci] )来限制克隆的数量。 If you know a different approach that would solve my issue, please let me know. 如果您知道可以解决我问题的其他方法,请告诉我。

Edit: I am using scripted jenkinsfiles and shared libraries with multibranch pipelines.. so I'm looking for a way to do that programmatically :) 编辑:我正在使用脚本化的jenkinsfiles和共享库与多分支管道..所以我正在寻找一种以编程方式执行此操作的方法:)

Since I did not see any other way I did the following: 由于没有其他方法,因此我执行了以下操作:

#!/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
            }
        }

    }

}

This will parse the commit message in a mirror repo and also reduce the bandwidth on my bitbucket server since the repo will only be cloned once on each agent and then copied to other directories for each branch. 这将解析镜像仓库中的提交消息,并且还减少了我的Bitbucket服务器上的带宽,因为该仓库仅在每个代理上克隆一次,然后复制到每个分支的其他目录中。 This was the most useful approach for me. 这对我来说是最有用的方法。 If you have questions, let me know :) 如果您有任何疑问,请告诉我:)

EDIT: I am parsing the Bitbucket REST API now, code looks like this: 编辑:我现在解析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}")
}

Just do that on a Jenkins master with curl installed, hope it helps.. 只需在安装了curl的Jenkins主服务器上执行此操作,希望对您有所帮助。

You can use pre-scm-buildstep plugin 您可以使用pre-scm-buildstep插件

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

This plugin allows build step to run before SCM checkouts so that you perform any build step action on the the workspace, (cleanup, add a file with some settings for the SCM, etc) or call other scripts that need to be run before checking out from the SCM. 此插件允许构建步骤在SCM检出之前运行,以便您在工作空间上执行任何构建步骤操作(清理,添加具有SCM某些设置的文件等)或调用其他需要在检出之前运行的脚本来自SCM。

So basically, you can execute any command before SCM checkout/clone starts. 因此,基本上,您可以在SCM检出/克隆开始之前执行任何命令。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM