在Jenkins Pipeline中获取自上次成功构建后的文件变更
背景
最近调整了一下项目的流水线,希望可以根据代码文件的变更自动识别修改的模块,从而进行相应服务的构建打包部署,简单记录一下。
具体实现
我们的项目是基于Maven多模块的,随着业务的发展,微服务模块的数量也从几个扩展到了十几个,以前无脑构建所有服务的情况可能效率就会非常低了,所以需要获取文件变更动态构建修改的微服务模块。
一开始,我使用的是Git命令,获取上次成功构建的GIT_COMMIT,然后进行比较获取对应的文件变更,但是这种情况对于Merge Request的场景好像不适用,因为原分支多次push之后再MR,Git命令也就只能获取最后的一次提交,之前的变更就捞不到,所以结果不是很准确。当然肯定有其他Git命令可以实现,我对于Git本身也不是那么熟练,后面就尝试去找其他的方式。我这边也贴一下具体的Pipeline脚本
groovy
pipeline {
agent any
environment {
// 定义其他环境变量
}
stages {
stage('Detect Changes') {
steps {
script {
// 获取上次成功构建的GIT_COMMIT,这里假设你的Jenkins配置了Git
def lastSuccessfulCommit = sh(
script: "git rev-parse HEAD^1",
returnStdout: true
).trim()
// 获取自上次成功构建以来发生变动的文件列表
def changedFiles = sh(
script: "git diff --name-only $lastSuccessfulCommit HEAD",
returnStdout: true
).trim()
// 解析文件路径,决定需要构建的模块
def buildModules = []
if (changedFiles.contains("module1")) {
buildModules += 'module1'
}
if (changedFiles.contains("module2")) {
buildModules += 'module2'
}
// 将需要构建的模块列表存储在环境变量中以便后续使用
env.BUILD_MODULES = buildModules.join(',')
echo "Modules to be built: ${env.BUILD_MODULES}"
}
}
}
// 其他阶段
stage('Build Modules') {
when {
expression {
return env.BUILD_MODULES.contains('module1')
}
}
steps {
echo 'Building module1...'
}
}
// 定义其他模块的构建阶段
}
}
后面去Google搜索了一下其他人的做法,发现Jenkins本身是支持获取上一次的变更文件列表的,参考了stackoverflow上面的写法,具体实现如下
groovy
pipeline {
agent any
environment {
// 定义其他环境变量
}
stages {
stage('Detect Changes') {
steps {
script {
def changedFiles = "Changes:\n"
build = currentBuild
while(build != null && build.result != 'SUCCESS') {
changedFiles += "In ${build.id}:\n"
for (changeLog in build.changeSets) {
for(entry in changeLog.items) {
for(file in entry.affectedFiles) {
changedFiles += "* ${file.path}\n"
}
}
}
build = build.previousBuild
}
echo changedFiles
// 解析文件路径,决定需要构建的模块
def buildModules = []
if (changedFiles.contains("module1")) {
buildModules += 'module1'
}
if (changedFiles.contains("module2")) {
buildModules += 'module2'
}
// 将需要构建的模块列表存储在环境变量中以便后续使用
env.BUILD_MODULES = buildModules.join(',')
echo "Modules to be built: ${env.BUILD_MODULES}"
}
}
}
// 其他阶段
stage('Build Modules') {
when {
expression {
return env.BUILD_MODULES.contains('module1')
}
}
steps {
echo 'Building module1...'
}
}
// 定义其他模块的构建阶段
}
}