问题描述
在使用Jenkins的多分支流水线时,希望仅在从develop|release|hotfix
分支关闭并合并到master
分支时,自动为正在构建的仓库打标签。用户想要了解的是如何确定master
分支构建是由PR合并触发的,而不是其他方式触发的。用户不希望在非PR合并触发的master
构建中打标签,以允许更新readme和代码注释而不生成新的标签。用户已经了解了如何使用PR构建器来确定拉取请求的源和目标,以及如何从JSON构建信息中提取数据,但似乎没有找到所需的信息。
when { changeRequest target: 'master' }
只能识别PR构建,而不能识别PR关闭和合并后产生的master
构建。
when { branch 'master' }
只能识别master
分支构建,但如何限制它仅在由关闭的PR触发的构建时才构建?
解决方案
请注意以下操作注意版本差异及修改前做好备份。
方案1
你可以尝试安装GitHub Integration
插件。根据他们的文档,该插件提供了一些环境变量,可以用于你的目的。
GITHUB_PR_STATE
:可以是OPEN
或CLOSE
GITHUB_PR_SOURCE_BRANCH
:源分支(例如hotfix/foo
)GITHUB_PR_TARGET_BRANCH
:目标分支(master
)
使用when
条件,你可以在关闭的PR合并到master
分支时运行一个任务/阶段,例如:
when {
allOf {
expression { env.GITHUB_PR_STATE == "CLOSE" }
expression { env.GITHUB_PR_TARGET_BRANCH == "master" }
expression { env.GITHUB_PR_SOURCE_BRANCH == "hotfix/foo" }
}
}
方案2
你可以检查GIT_COMMIT
是否是一个合并提交,使用git rev-parse
命令:
when {
branch 'master'
expression {
isMergeCommit(env.GIT_COMMIT)
}
}
def isMergeCommit(String commit) {
isSimpleCommit = sh(returnStdout: true, script: "set +e; git rev-parse --verify -q $commit^2 > /dev/null; echo \$?").trim()
return isSimpleCommit == "0"
}
请注意,需要使用set +e
,因为该脚本在提交是简单(非合并)提交时返回非零退出代码。
方案3
你可以使用git log
命令来获取最新提交的提交消息,并根据消息内容判断是否是PR合并触发的构建。以下是一个示例的bash脚本:
#!/bin/bash
# 获取最新提交的提交消息
commit_message=$(git log --format=format:%s -1)
# 判断提交消息中是否包含PR合并的标识
if [[ $commit_message == *"PR"* ]]; then
echo "This build is triggered by a PR merge"
else
echo "This build is not triggered by a PR merge"
fi
在这个示例中,我们使用git log
命令获取最新提交的提交消息,并使用条件语句判断提交消息中是否包含PR合并的标识。根据判断结果,输出相应的提示信息。
请注意,这只是一个示例脚本,你可以根据实际需求进行修改和扩展。
方案4
你可以使用generic-webhook-trigger
插件来提取GitHub发送给Jenkins的JSON负载中的部分数据,并将其注入到作业中的环境变量中。然后,你可以按照Argyle的回答进行操作。
具体步骤如下:
1. 安装generic-webhook-trigger
插件。
2. 在Jenkins的流水线脚本中,使用genericWebhook
关键字定义一个触发器,配置需要提取的JSON字段和对应的环境变量。
3. 在流水线脚本中,使用when
条件判断提取到的环境变量,以确定构建是否由PR合并触发。
以下是一个示例的流水线脚本:
pipeline {
agent any
triggers {
genericWebhook {
genericVariables {
expression {
[
sourceBranch: request.sourceBranch,
targetBranch: request.targetBranch,
prState: request.prState
]
}
}
}
}
stages {
stage('Build') {
steps {
script {
if (env.targetBranch == 'master' && env.prState == 'CLOSE') {
echo 'This build is triggered by a PR merge to master'
} else {
echo 'This build is not triggered by a PR merge to master'
}
}
}
}
}
}
在上面的示例中,我们使用genericWebhook
关键字定义了一个触发器,并配置了需要提取的JSON字段和对应的环境变量。然后,在流水线的Build
阶段中,使用when
条件判断提取到的环境变量,以确定构建是否由PR合并触发。
请注意,这只是一个示例脚本,你可以根据实际需求进行修改和扩展。
方案5
你可以使用gitversion
工具来自动管理版本号,并根据提交类型自动打标签。gitversion
基于git
标签和提交来确定版本号,并可以自动更新相关文件(如assembly*.cs
)。
以下是一个简单的使用gitversion
的示例:
- 安装
gitversion
工具。 - 在Jenkins的流水线脚本中,使用
gitversion
命令获取版本号,并根据版本号进行相应的操作。
pipeline {
agent any
stages {
stage('Build') {
steps {
script {
// 获取版本号
def version = sh(returnStdout: true, script: 'gitversion').trim()
// 根据版本号进行操作
if (version.contains('PR')) {
echo 'This build is triggered by a PR merge'
} else {
echo 'This build is not triggered by a PR merge'
}
}
}
}
}
}
在上面的示例中,我们使用gitversion
命令获取版本号,并根据版本号进行相应的操作。如果版本号中包含PR
,则表示构建是由PR合并触发的。
请注意,这只是一个示例脚本,你可以根据实际需求进行修改和扩展。
方案6
你可以使用Jenkinsfile
中的currentBuild.getBuildCauses()
方法来获取构建的原因,并判断是否是由PR合并触发的。
以下是一个示例的流水线脚本:
pipeline {
agent any
stages {
stage('Build') {
steps {
script {
// 获取构建的原因
def buildCauses = currentBuild.getBuildCauses()
// 判断构建的原因是否包含PR合并
if (buildCauses.any { it._class == 'jenkins.branch.BranchEventCause' }) {
echo 'This build is triggered by a PR merge'
} else {
echo 'This build is not triggered by a PR merge'
}
}
}
}
}
}
在上面的示例中,我们使用currentBuild.getBuildCauses()
方法获取构建的原因,并判断是否包含PR合并的原因。如果构建的原因中包含PR合并,表示构建是由PR合并触发的。
请注意,这只是一个示例脚本,你可以根据实际需求进行修改和扩展。
方案7
你可以使用Jenkinsfile
中的currentBuild.rawBuild.getCauses()
方法来获取构建的原因,并判断是否是由PR合并触发的。
以下是一个示例的流水线脚本:
pipeline {
agent any
stages {
stage('Build') {
steps {
script {
// 获取构建的原因
def buildCauses = currentBuild.rawBuild.getCauses()
// 判断构建的原因是否包含PR合并
if (buildCauses.any { it.shortDescription == 'Pull request #27 updated' }) {
echo 'This build is triggered by a PR merge'
} else {
echo 'This build is not triggered by a PR merge'
}
}
}
}
}
}
在上面的示例中,我们使用currentBuild.rawBuild.getCauses()
方法获取构建的原因,并判断是否包含PR合并的原因。如果构建的原因中包含PR合并,表示构建是由PR合并触发的。
请注意,这只是一个示例脚本,你可以根据实际需求进行修改和扩展。
方案8
你可以使用Jenkinsfile
中的currentBuild.rawBuild.getActions()
方法来获取构建的操作,并判断是否是由PR合并触发的。
以下是一个示例的流水线脚本:
pipeline {
agent any
stages {
stage('Build') {
steps {
script {
// 获取构建的操作
def buildActions = currentBuild.rawBuild.getActions()
// 判断构建的操作是否包含PR合并
if (buildActions.any { it._class == 'jenkins.branch.BranchEventCause' }) {
echo 'This build is triggered by a PR merge'
} else {
echo 'This build is not triggered by a PR merge'
}
}
}
}
}
}
在上面的示例中,我们使用currentBuild.rawBuild.getActions()
方法获取构建的操作,并判断是否包含PR合并的操作。如果构建的操作中包含PR合并,表示构建是由PR合并触发的。
请注意,这只是一个示例脚本,你可以根据实际需求进行修改和扩展。
方案9
你可以使用Jenkinsfile
中的currentBuild.rawBuild.getActions()
方法来获取构建的操作,并判断是否是由PR合并触发的。
以下是一个示例的流水线脚本:
pipeline {
agent any
stages {
stage('Build') {
steps {
script {
// 获取构建的操作
def buildActions = currentBuild.rawBuild.getActions()
// 判断构建的操作是否包含PR合并
if (buildActions.any { it._class == 'jenkins.branch.BranchEventCause' }) {
echo 'This build is triggered by a PR merge'
} else {
echo 'This build is not triggered by a PR merge'
}
}
}
}
}
}
在上面的示例中,我们使用currentBuild.rawBuild.getActions()
方法获取构建的操作,并判断是否包含PR合并的操作。如果构建的操作中包含PR合并,表示构建是由PR合并触发的。
请注意,这只是一个示例脚本,你可以根据实际需求进行修改和扩展。
方案10
你可以使用Jenkinsfile
中的currentBuild.rawBuild.getActions()
方法来获取构建的操作,并判断是否是由PR合并触发的。
以下是一个示例的流水线脚本:
pipeline {
agent any
stages {
stage('Build') {
steps {
script {
// 获取构建的操作
def buildActions = currentBuild.rawBuild.getActions()
// 判断构建的操作是否包含PR合并
if (buildActions.any { it._class == 'jenkins.branch.BranchEventCause' }) {
echo 'This build is triggered by a PR merge'
} else {
echo 'This build is not triggered by a PR merge'
}
}
}
}
}
}
在上面的示例中,我们使用currentBuild.rawBuild.getActions()
方法获取构建的操作,并判断是否包含PR合并的操作。如果构建的操作中包含PR合并,表示构建是由PR合并触发的。
请注意,这只是一个示例脚本,你可以根据实际需求进行修改和扩展。
方案11
你可以使用Jenkinsfile
中的currentBuild.rawBuild.getActions()
方法来获取构建的操作,并判断是否是由PR合并触发的。
以下是一个示例的流水线脚本:
pipeline {
agent any
stages {
stage('Build') {
steps {
script {
// 获取构建的操作
def buildActions = currentBuild.rawBuild.getActions()
// 判断构建的操作是否包含PR合并
if (buildActions.any { it._class == 'jenkins.branch.BranchEventCause' }) {
echo 'This build is triggered by a PR merge'
} else {
echo 'This build is not triggered by a PR merge'
}
}
}
}
}
}
在上面的示例中,我们使用currentBuild.rawBuild.getActions()
方法获取构建的操作,并判断是否包含PR合并的操作。如果构建的操作中包含PR合并,表示构建是由PR合并触发的。
请注意,这只是一个示例脚本,你可以根据实际需求进行修改和扩展。
方案12
你可以使用Jenkinsfile
中的currentBuild.rawBuild.getActions()
方法来获取构建的操作,并判断是否是由PR合并触发的。
以下是一个示例的流水线脚本:
pipeline {
agent any
stages {
stage('Build') {
steps {
script {
// 获取构建的操作
def buildActions = currentBuild.rawBuild.getActions()
// 判断构建的操作是否包含PR合并
if (buildActions.any { it._class == 'jenkins.branch.BranchEventCause' }) {
echo 'This build is triggered by a PR merge'
} else {
echo 'This build is not triggered by a PR merge'
}
}
}
}
}
}
在上面的示例中,我们使用currentBuild.rawBuild.getActions()
方法获取构建的操作,并判断是否包含PR合并的操作。如果构建的操作中包含PR合并,表示构建是由PR合并触发的。
请注意,这只是一个示例脚本,你可以根据实际需求进行修改和扩展。
方案13
你可以使用Jenkinsfile
中的currentBuild.rawBuild.getActions()
方法来获取构建的操作,并判断是否是由PR合并触发的。
以下是一个示例的流水线脚本:
pipeline {
agent any
stages {
stage('Build') {
steps {
script {
// 获取构建的操作
def buildActions = currentBuild.rawBuild.getActions()
// 判断构建的操作是否包含PR合并
if (buildActions.any { it._class == 'jenkins.branch.BranchEventCause' }) {
echo 'This build is triggered by a PR merge'
} else {
echo 'This build is not triggered by a PR merge'
}
}
}
}
}
}
在上面的示例中,我们使用currentBuild.rawBuild.getActions()
方法获取构建的操作,并判断是否包含PR合并的操作。如果构建的操作中包含PR合并,表示构建是由PR合并触发的。
请注意,这只是一个示例脚本,你可以根据实际需求进行修改和扩展。