在 Jenkins Pipeline/Jenkinsfile 中获取 git 分支名称

Posted

技术标签:

【中文标题】在 Jenkins Pipeline/Jenkinsfile 中获取 git 分支名称【英文标题】:Get git branch name in Jenkins Pipeline/Jenkinsfile 【发布时间】:2017-07-12 00:25:00 【问题描述】:

我创建了一个 jenkins 管道,它正在从 scm 中提取管道脚本。 我将分支说明符设置为“all”,因此它建立在对任何分支的任何更改之上。

如何从 Jenkinsfile 访问导致此构建的分支名称?

我尝试过的所有内容都显示为 null,除了

sh(returnStdout: true, script: 'git rev-parse --abbrev-ref HEAD').trim()

总是master

【问题讨论】:

【参考方案1】:

使用多分支管道作业类型,而不是普通的管道作业类型。多分支管道作业确实具有描述分支的环境变量env.BRANCH_NAME

在我的脚本中..

stage('Build') 
    node 
        echo 'Pulling...' + env.BRANCH_NAME
        checkout scm
        
    

产量...

Pulling...master

【讨论】:

这实际上只是作业的名称,而不是 git 分支的名称。只要您的工作与您的分支机构同名,这将有效。 所有这些变量都在 Git 插件页面的环境变量下定义:plugins.jenkins.io/git 只要遵守上面提到的^^,它就可以完美运行。【参考方案2】:

如果您的管道有 jenkinsfile,请检查您在执行时是否在 environment variables 中看到您的分支名称。

您可以使用以下方式打印它们:

pipeline 
    agent any

    environment 
        DISABLE_AUTH = 'true'
        DB_ENGINE    = 'sqlite'
    

    stages 
        stage('Build') 
            steps 
                sh 'printenv'
            
        
    

但是,PR 91 表明分支名称仅在某些管道配置中设置:

Branch Conditional(见groovy script) parallel branches pipeline(由 OP 看到)

【讨论】:

谢谢,这很有帮助。看起来它不在我的环境变量中。是否可以公开导致构建的分支? repo 中的文件(Jenkinsfile)被期望提供硬编码的分支名称,这太荒谬了。这使得回购本身成为管理的灾难。这需要修复...【参考方案3】:

一位同事告诉我使用scm.branches[0].name,它奏效了。我将它包装到我的 Jenkinsfile 中的一个函数中:

def getGitBranchName() 
    return scm.branches[0].name

【讨论】:

试过了,得到了.. ...org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: 不允许使用方法 BRANCH_NAME 的脚本不起作用并且 env.BRANCH_NAME 返回 null...跨度> 如果您将共享库设置为全局,您将不会遇到安全问题。另一种方法是在Manage Jenkins > In Process Script Approval 上允许这些安全异常 您也可以将该方法列入白名单 获胜者。效果很好!没有外壳执行。最初不需要结帐任何东西。适用于不同的节点上下文。适用于普通项目。好东西。 这对我有用。如何找出scm 对象的属性?这个对象有任何文档吗?谢谢。【参考方案4】:

对于管道:

pipeline 
  environment 
     BRANCH_NAME = "$GIT_BRANCH.split("/")[1]"
  

【讨论】:

我已经调整了您的答案,使其适用于简单的管道以及不需要在这种情况下拆分 GIT_BRANCH 的多分支管道:BRANCH_NAME = "$GIT_BRANCH.split("/").size() > 1 ? GIT_BRANCH.split("/")[1] : GIT_BRANCH" 进一步改进@Romain 的评论:BRANCH_NAME = "$GIT_BRANCH.split('/').size() > 1 ? GIT_BRANCH.split('/')[1..-1].join('/') : GIT_BRANCH"【参考方案5】:

对我来说这很有效:(使用 Jenkins 2.150,使用简单的管道类型 - 不是多分支,我的分支说明符:'**')

echo 'Pulling... ' + env.GIT_BRANCH

输出:

Pulling... origin/myBranch

其中 myBranch 是功能分支的名称

【讨论】:

这个不行,结果拉null。仅当您指定的不仅仅是版本号时,此答案才可用,例如,您是否使用任何为您带来魔力的插件? @chrillelundmark 我在重试后编辑了我的答案......我没有安装插件来帮助我实现这个目的,否则我不知道我还应该指定什么......我猜那里一条评论中没有足够的字符来写下我所有的插件 当我的 jenkins 作业从 PR 触发时,我将 PR-45= 作为 env.GIT_BRANCH 的值。不是我所期望的 在 Windows 上使用 Jenkins 2.303.1 为我返回 null,简单的管道。【参考方案6】:

这适用于简单的管道类型 - 不是多分支。使用 Jenkins 2.150.1

environment FULL_PATH_BRANCH = "$sh(script:'git name-rev --name-only HEAD', returnStdout: true)" GIT_BRANCH = FULL_PATH_BRANCH.substring(FULL_PATH_BRANCH.lastIndexOf('/') + 1, FULL_PATH_BRANCH.length())

那就用env.GIT_BRANCH

【讨论】:

这对我在 macOS 从属设备上非常有用,但是在 Windows 从属设备上我总是在执行 environment FULL_PATH_BRANCH_WIN = "$bat(script:'@git name-rev --仅名称 HEAD', returnStdout: true)" GIT_BRANCH_WIN = FULL_PATH_BRANCH_WIN.substring(FULL_PATH_BRANCH_WIN.lastIndexOf('/') + 1, FULL_PATH_BRANCH_WIN.length()) org.codehaus.groovy.control.MultipleCompilationErrorsException:启动失败:WorkflowScript:234:意外令牌:名称@第 234 行,第 42 列。TH_BRANCH = “$sh(script:'git name-rev - 对我没用 FULL_PATH_BRANCH 在 Windows 上使用 Jenkins 2.303.1 为我返回 null,简单的管道。【参考方案7】:

切换到多分支管道允许我访问分支名称。不建议使用常规管道。

【讨论】:

是的,阅读github.com/jenkinsci/pipeline-model-definition-plugin/pull/91,你应该在BRANCH_NAME看到它。【参考方案8】:

要在 Jenkins 中获取 git 分支名称, 如果它是一个多分支管道,那么我们可以轻松地使用 env.GIT_BRANCH。 但如果是普通管道,我们可以使用 SCM 插件对象来检索分支名称。

以下代码适用于普通管道和多分支管道。

def branch_nem = scm.branches[0].name
if (branch_nem.contains("*/")) 
    branch_nem = branch_nem.split("\\*/")[1]
    
echo branch_nem

【讨论】:

【参考方案9】:

如果您使用构建参数作为分支说明符,则仅从 scm.branches 获取名称是不够的,例如$BRANCH。 您需要将该字符串扩展为真实姓名:

scm.branches.first().getExpandedName(env.getEnvironment())

注意getEnvironment() 必须是显式的getter,否则env 将查找名为environment 的环境变量。

不要忘记您需要批准这些方法才能从沙盒中访问它们。

【讨论】:

【参考方案10】:

FWIW 在 PR 构建中唯一对我有用的是 $CHANGE_BRANCH

(可能不适用于master,还没有看到)

【讨论】:

【参考方案11】:

这对我来说适用于非多分支管道,将 SCM Branch Specifier (blank for 'any') 设置为 */branch_name 或将其设置为 branch_name

BRANCH_NAME = "$GIT_BRANCH.split('/').size() > 1 ? GIT_BRANCH.split('/')[1..-1].join('/') : GIT_BRANCH"

【讨论】:

【参考方案12】:

我可能想使用env.CHANGE_BRANCH 来获取真正的分支名称,而不是 jenkins 工作/PR 名称。

【讨论】:

以上是关于在 Jenkins Pipeline/Jenkinsfile 中获取 git 分支名称的主要内容,如果未能解决你的问题,请参考以下文章

一个jenkins远程操作另一个jenkins进行构建

jenkins配置

如何记录jenkins构建次数

jenkins报错401k8s

如何获取jenkins的日志信息

Jenkins 四: 启动关闭以及重启jenkins