检测到 git 分支仅涉及特定路径
Detect that git branch touches only specific paths
背景
在我的项目中,bitbucket 上的拉取请求由 Jenkins 构建验证。构建和测试大约需要 50 分钟。这很好用。
问题
有些更改不会影响工作代码(前端相关)。因此,如果拉取请求仅涉及两个子目录之一,则没有必要进行构建和 运行 测试。目的是节省时间(更少的时间来发布次要的无害更改)和资源(不要为无用的工作占用构建机器)。
我不想拆分项目(可能的解决方案之一),因为前端的更改通常需要更改实际的后端代码,因此在这种情况下需要进行测试。
可能的解决方案
我找到了停止 Jenkins 构建的方法,并在获取新代码的第一步成功。
问题是如何询问 git 分支(更改)是否只涉及两个子目录。这可能需要这样的东西:
git diff master...featureBranch <some other options>
可能的替代方案
或者也许还有其他方法可以解决这个问题?使用 bitbucket
或 Jenkins
?
的某些功能
可能最简单的方法是使用 git log
或 git diff
,因为两者都可以采用转速范围和路径:
git log [<options>] [<revision range>] [[--] <path>…]
git diff [<options>] <commit> <commit> [--] [<path>…]
例如,要测试最新提交是否触及directory1 and/or directory2,您可以使用:
git log --oneline HEAD^..HEAD directory1 directory2
对于否定匹配,排除 pathspec 应该可以解决问题:
git log --oneline HEAD^..HEAD -- '.' ':(exclude)./directory1'
或与 diff 类似:
git diff HEAD^..HEAD '.' ':(exclude)directory'
解决git 特征:(exclude)directory'
(感谢@sbat)。
此功能的详细信息是 described here.
这是详细的实现方式(windows 平台的 Jenkins 管道):
// inside some step:
node('master') {
def diffStat = "undetermined"
try {
diffStat = bat (
returnStdout: true,
script: """@ECHO OFF
cd $repoDirecory
git diff ${PULL_REQUEST_TO_BRANCH} --shortstat -- "." ":(exclude)./FrontendA" ":(exclude)./FrontendB"
""").trim()
if (!diffStat) {
currentBuild.description = "Frontend only"
error("There is no significant changes, build is not required!")
}
} finally {
if (diffStat) {
echo diffStat
} else {
currentBuild.result = 'SUCCESS'
}
notifyBitbucket(commitSha1: PULL_REQUEST_FROM_HASH, ignoreUnverifiedSSLPeer: true)
}
}
因为没有来自 git diff --shortstat <....>
的退出代码,但是如果没有可见的变化,git
不会打印任何内容。因此,通过在 groovy 中使用 bat returnStdout: true
,git
的输出被分配给变量。然后在 groovy 脚本中可以根据变量 diffStat
是否为空来采取适当的操作。
现在如果只发现不重要的变化(diffStat
为空),报错,以后视为成功。 Bitbucket 将此构建视为成功(这是目标)。在 Jenkins 上,所有构建步骤都失败(红色),但这对我来说不是问题。
如果发现重大变化,Jenkins 会打印差异统计信息(真实示例):
6 files changed, 62 insertions(+), 48 deletions(-)
在Windows上有一个陷阱:不能使用'
(单引号字符),但是正如你在上面看到的"
(双引号)做的工作.
背景
在我的项目中,bitbucket 上的拉取请求由 Jenkins 构建验证。构建和测试大约需要 50 分钟。这很好用。
问题
有些更改不会影响工作代码(前端相关)。因此,如果拉取请求仅涉及两个子目录之一,则没有必要进行构建和 运行 测试。目的是节省时间(更少的时间来发布次要的无害更改)和资源(不要为无用的工作占用构建机器)。
我不想拆分项目(可能的解决方案之一),因为前端的更改通常需要更改实际的后端代码,因此在这种情况下需要进行测试。
可能的解决方案
我找到了停止 Jenkins 构建的方法,并在获取新代码的第一步成功。
问题是如何询问 git 分支(更改)是否只涉及两个子目录。这可能需要这样的东西:
git diff master...featureBranch <some other options>
可能的替代方案
或者也许还有其他方法可以解决这个问题?使用 bitbucket
或 Jenkins
?
可能最简单的方法是使用 git log
或 git diff
,因为两者都可以采用转速范围和路径:
git log [<options>] [<revision range>] [[--] <path>…]
git diff [<options>] <commit> <commit> [--] [<path>…]
例如,要测试最新提交是否触及directory1 and/or directory2,您可以使用:
git log --oneline HEAD^..HEAD directory1 directory2
对于否定匹配,排除 pathspec 应该可以解决问题:
git log --oneline HEAD^..HEAD -- '.' ':(exclude)./directory1'
或与 diff 类似:
git diff HEAD^..HEAD '.' ':(exclude)directory'
解决git 特征:(exclude)directory'
(感谢@sbat)。
此功能的详细信息是 described here.
这是详细的实现方式(windows 平台的 Jenkins 管道):
// inside some step:
node('master') {
def diffStat = "undetermined"
try {
diffStat = bat (
returnStdout: true,
script: """@ECHO OFF
cd $repoDirecory
git diff ${PULL_REQUEST_TO_BRANCH} --shortstat -- "." ":(exclude)./FrontendA" ":(exclude)./FrontendB"
""").trim()
if (!diffStat) {
currentBuild.description = "Frontend only"
error("There is no significant changes, build is not required!")
}
} finally {
if (diffStat) {
echo diffStat
} else {
currentBuild.result = 'SUCCESS'
}
notifyBitbucket(commitSha1: PULL_REQUEST_FROM_HASH, ignoreUnverifiedSSLPeer: true)
}
}
因为没有来自 git diff --shortstat <....>
的退出代码,但是如果没有可见的变化,git
不会打印任何内容。因此,通过在 groovy 中使用 bat returnStdout: true
,git
的输出被分配给变量。然后在 groovy 脚本中可以根据变量 diffStat
是否为空来采取适当的操作。
现在如果只发现不重要的变化(diffStat
为空),报错,以后视为成功。 Bitbucket 将此构建视为成功(这是目标)。在 Jenkins 上,所有构建步骤都失败(红色),但这对我来说不是问题。
如果发现重大变化,Jenkins 会打印差异统计信息(真实示例):
6 files changed, 62 insertions(+), 48 deletions(-)
在Windows上有一个陷阱:不能使用'
(单引号字符),但是正如你在上面看到的"
(双引号)做的工作.