如何确定Jenkins构建是否由合并到主分支的Pull Request触发

53次阅读
没有评论

问题描述

在使用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:可以是OPENCLOSE
  • 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的示例:

  1. 安装gitversion工具。
  2. 在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合并触发的。

请注意,这只是一个示例脚本,你可以根据实际需求进行修改和扩展。

正文完