我怎样才能限制Jenkins构建步骤为仅给定的变更集?

5w9g7ksd  于 2023-01-16  发布在  Jenkins
关注(0)|答案(3)|浏览(179)

我正在使用Jenkins声明性管道,并且我试图仅在仅在指定目录中进行更改的情况下执行特定的构建阶段。
所以我的目录层次结构看起来像这样:

root
 ├─ some-directory
 |   ├─ sub-directory
 |   |   └─ file-1
 |   ├─ file-1
 |   └─ file-2
 ├─ another-directory
 |   ├─ file-1
 |   └─ file-2
 ├─ file-x
 └─ file-y

这是当前代码:

stage ("Deploy branches") {
    agent any

    when { 
        allOf {
            not { branch 'master' }
            changeset "some-directory/**"
        }
    }

    steps {
        // do stuff
    }
}

无论何时"some-directory"中的内容发生更改,还是"some-directory"之外的内容发生更改,都会部署此步骤。我希望在除了"some-directory"的内容之外没有其他内容发生更改时运行此步骤。
以下是the Jenkins docs对"changeset"指令的说明:
变更集
如果生成的SCM变更集包含一个或多个与给定字符串或Glob匹配的文件,则执行该阶段。示例:当{变更集"**/*. js "}
默认情况下,路径匹配不区分大小写,可以使用caseSensitive参数将其关闭,例如:当{变更集glob:"自述文件. *",区分大小写:真}
"如果变更集 * 包含 * 一个或多个与给定字符串或glob匹配的文件。"表示管道按设计工作,但我需要的是
"如果变更集中的文件 * 仅 * 匹配给定的字符串或glob。"
不幸的是,我在文档或互联网上找不到任何相关信息。
你有什么建议我怎么才能做到这一点?

avwztpqn

avwztpqn1#

我相信changeset不能做你正在努力实现的事情;但是它可以被expression替换来计算Git diff并进行相关的过滤。我也遇到过类似的问题,它对我来说工作得很好。
以下内容应适用于您的用例:

stage ("Deploy branches") {
    agent any

    when { 
        allOf {
            not { branch 'master' }
            changeset "some-directory/**"
            expression {  // there are changes in some-directory/...
                sh(returnStatus: true, script: 'git diff  origin/master --name-only | grep --quiet "^some-directory/.*"') == 0
            }
            expression {   // ...and nowhere else.
                sh(returnStatus: true, script: 'git diff origin/master --name-only | grep --quiet --invert-match "^some-directory/.*"') == 1
            }
        }
    }

    steps {
        // do stuff
    }
}

(this硬编码与origin/master的比较,这是我的用例;如果这还不够复杂,可以使用包含拉取请求的目标分支的Jenkins变量。)

xj3cbfub

xj3cbfub2#

一些旧的jenkins管道版本不支持***when***语句。
您也可以检查以下更改:

def rc = sh(
  script: "git status -s ${dir} | grep -q ${dir}",
  returnStatus: true
)
if(!rc) {
  doSomething(dir)
}
igetnqfo

igetnqfo3#

我们无法使用when { changeset "**/*.js" },因为管道线是动态生成的,不可能在script {}中使用when {}。您将收到以下错误:
java.lang.NoSuchMethodError:在步骤中未找到此类DSL方法"when
我们创建了一个 Package 器函数,通过使用与changeset声明相同的实现来检查更改。

import org.jenkinsci.plugins.pipeline.modeldefinition.when.impl.ChangeSetConditional

def caseSensitive = false

def hasChanges(String pattern) {
    def changeLogSets = currentBuild.changeSets
    def conditional = new ChangeSetConditional(pattern)

    for (set in changeLogSets) {
        def entries = set.items
        for (entry in entries) {
            if (conditional.changeSetMatches(entry, pattern, caseSensitive)) {
                return true;
            }
        }
    }

    return false;
}

用法:

script {
  for (library in libraries) {
    def changesFound = hasChanges("${library.path}/**");
  
    if (changesFound) {
      // do stuff
    }
  }
}

相关问题