如何将 Jenkins 构建步骤限制为仅给定的变更集?

Fre*_*red 5 pipeline changeset jenkins jenkins-pipeline

我正在使用 Jenkins 声明性管道,并且仅当仅在指定目录中进行更改时,我才尝试执行特定的构建阶段。

所以我的目录层次结构看起来像这样:

root
 ?? some-directory
 |   ?? sub-directory
 |   |   ?? file-1
 |   ?? file-1
 |   ?? file-2
 ?? another-directory
 |   ?? file-1
 |   ?? file-2
 ?? file-x
 ?? file-y
Run Code Online (Sandbox Code Playgroud)

这是当前的代码:

stage ("Deploy branches") {
    agent any

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

    steps {
        // do stuff
    }
}
Run Code Online (Sandbox Code Playgroud)

每当“某个目录”中的某些内容发生更改时,以及“某个目录”之外的某些内容发生更改时,都会进行部署。如果仅更改“某个目录”的内容,我希望此步骤运行。

这是Jenkins 文档对“changeset”指令的描述:

变更集

如果构建的 SCM 变更集包含一个或多个与给定字符串或 glob 匹配的文件,则执行该阶段。示例:当{变更集“**/*.js”}

默认情况下,路径匹配不区分大小写,这可以使用 caseSensitive 参数关闭,例如:when { changeset glob: "ReadMe.*", caseSensitive: true }

“如果变更集包含一个或多个与给定字符串或全局匹配的文件。” 意味着管道按设计工作,但我想要的是

“如果变更集中的文件匹配给定的字符串或 glob。”

不幸的是,我在文档或互联网上的其他地方找不到任何关于此的信息。

你对我如何使这成为可能有什么建议吗?

小智 5

我相信这changeset无法实现您想要实现的目标;但它可以被替换为expression计算 Git diff 并进行相关过滤。我有一个类似的问题,它对我来说效果很好。

\n

以下内容应该适用于您的用例:

\n
stage ("Deploy branches") {\n    agent any\n\n    when { \n        allOf {\n            not { branch \'master\' }\n            changeset "some-directory/**"\n            expression {  // there are changes in some-directory/...\n                sh(returnStatus: true, script: \'git diff  origin/master --name-only | grep --quiet "^some-directory/.*"\') == 0\n            }\n            expression {   // ...and nowhere else.\n                sh(returnStatus: true, script: \'git diff origin/master --name-only | grep --quiet --invert-match "^some-directory/.*"\') == 1\n            }\n        }\n    }\n\n    steps {\n        // do stuff\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

(这对与 的比较进行了硬编码origin/master,这是我的用例;如果那个 \xe2\x80\x99s 不够复杂,则可以使用一些包含拉取请求的目标分支的 Jenkins 变量。)

\n