如何获取git的最新提交信息并防止Jenkins构建,如果提交消息包含[ci skip]?

28

我尝试在 Jenkinsfile 中获取 git 提交信息并根据提交信息阻止构建。

env.GIT_COMMIT 在 Jenkinsfile 中不会返回提交的详细信息。

如何获取 git 的最新提交信息,并在提交信息中包含 [ci skip] 时阻止 Jenkins 构建?


3
尝试运行命令"git log -1"并使用grep筛选出相关文本。 - Amityo
@Amityo:谢谢,这真的很有帮助。我还需要一个问题……如果消息包含[ci skip]内容,如何在Jenkinsfile中防止Jenkins构建? - Yahwe Raj
问题已经创建,以提供GIT_COMMIT_MESSAGE,您可以投票以尽快获得它 https://issues.jenkins-ci.org/browse/JENKINS-52490 - ImranRazaKhan
5个回答

24

我遇到了同样的问题。我正在使用管道。我通过实现共享库来解决这个问题。

该库的代码如下:

// vars/ciSkip.groovy

def call(Map args) {
    if (args.action == 'check') {
        return check()
    }
    if (args.action == 'postProcess') {
        return postProcess()
    }
    error 'ciSkip has been called without valid arguments'
}

def check() {
    env.CI_SKIP = "false"
    result = sh (script: "git log -1 | grep '.*\\[ci skip\\].*'", returnStatus: true)
    if (result == 0) {
        env.CI_SKIP = "true"
        error "'[ci skip]' found in git commit message. Aborting."
    }
}

def postProcess() {
    if (env.CI_SKIP == "true") {
        currentBuild.result = 'NOT_BUILT'
    }
}

那么,在我的Jenkinsfile中:

pipeline {
  stages {
    stage('prepare') { steps { ciSkip action: 'check' } }
    // other stages here ...
  }
  post { always { ciSkip action: 'postProcess' } }
}

正如您所看到的,构建被标记为NOT_BUILT。如果您愿意,可以将其更改为ABORTED,但它不能设置为SUCCESS,因为构建结果只能变得更糟


19

如果在最后一个git日志中提供[ci skip],则构建将通过,但不会运行实际的构建代码(即第一个echo语句的替代品)。

node {
  checkout scm
  result = sh (script: "git log -1 | grep '\\[ci skip\\]'", returnStatus: true) 
  if (result != 0) {
    echo "performing build..."
  } else {
    echo "not running..."
  }
}

1
有关如何使用 sh 的更多信息,请参见:https://issues.jenkins-ci.org/browse/JENKINS-26133 - Mike Rylander

13

1
'^.\[ci skip\].$' 或者 '.\[ci skip\].' 可能更有意义。 - bias
这对于第一次构建不起作用,因为它将没有任何更改日志。 - Shrinivas Shukla
2
有没有办法将其限制为最近的提交消息?经过测试,如果最近的提交消息不匹配,但上一个提交匹配,则仍会跳过。 - Vala
@Thor84no,我也已经验证了你所报告的问题。不幸的是,在“when”内部的“changelog”匹配的不仅仅是最新的提交消息 :-( - BigGillyStyle
1
我刚刚在Jenkins 2.303.3上尝试了一下,它完全正常。它没有查看以前的提交记录。 - Mani
这个功能是由这个PR创建的:https://github.com/jenkinsci/pipeline-model-definition-plugin/pull/178。 - Mani

8
我认为你可以在多分支管道作业配置中轻松完成这个任务。 分支来源 > 附加行为 > 忽略包含特定消息的提交 多分支管道作业配置

当使用这种方法时,$CHANGE_ID 在 Jenkinsfile 中不可用。 - Idan Adar
2
@hakamairi,这个选项是否适用于多分支?因为我找不到它。 - ImranRazaKhan
你有这个的更新版本吗?在2021年的分支源代码部分似乎已经没有“高级行为”了。你可以添加行为,但是没有一个选项与提交消息相关。有任何想法吗? - Seth Lutske

6
截至今日,实现这一点非常容易。有趣的部分是名为MessageExclusionextension,其中excludedMessage接受正则表达式。
checkout([ $class: 'GitSCM', 
  branches: [[name: '*/master']], 
  doGenerateSubmoduleConfigurations: false, 
  extensions: [[
    $class: 'MessageExclusion', excludedMessage: '.*skip-?ci.*'
  ]], 
  submoduleCfg: [], 
  userRemoteConfigs: [[
    credentialsId: 'xxx', url: 'git@github.com:$ORG/$REPO.git'
  ]]
])

2
这些是内置类吗? - ntwrkguru
当我使用这个时,我观察到一个有趣的情况;我无法在我的Docker构建中使用git。还不确定它们之间有什么关系,但如果我使用普通的“checkout scm”,它可以工作。如果我使用这种方法,它就不行了。 - ntwrkguru

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接