在Jenkins Pipeline中获取自上次成功构建后的文件变更

在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...'
               
            }
        }
        // 定义其他模块的构建阶段
    }
}

参考

https://stackoverflow.com/questions/38084806/how-to-get-the-changes-since-the-last-successful-build-in-jenkins-pipeline

相关推荐
悠悠12138几秒前
微服务通信别只看性能:REST 与 gRPC 的 6 个选型判断和一次 502 故障复盘
运维·服务器
zx_741484812 小时前
【Linux入门】Shell 函数、正则表达式与文本处理:cut 与 awk
linux·运维·正则表达式
Zenova EdgeOS2 小时前
Linux dmesg 工业边缘实战:内核日志过滤、持久化与故障定位
linux·运维·边缘计算·工业边缘·dmesg·内核日志
wdfk_prog3 小时前
ROS教程08:从 TransportTCP::connect() 追到 TCPROS Connection Header、序列化与 Socket 数据传输
运维·缓存·docker·容器·ros
做运维的阿瑞3 小时前
Python 标准库汇总:分类速览与常用模块清单
linux·运维·python
日常筹谋记4 小时前
自动化仓储安全防护工况评估:明治传感器AS-33C技术适配性分析
大数据·运维·创业创新·业界资讯
Shadow(⊙o⊙)5 小时前
Linux进阶知识1.0
linux·运维·服务器
闲云自留地5 小时前
告别命令恐惧症,openEuler 基础操作 + 文本 + 网络管理实战
linux·运维·云计算
其实防守也摸鱼6 小时前
常见安全架构中 Shiro 的认证确认机制解析
运维·服务器·数据库·windows·github
^Rocky7 小时前
IT 疑难杂症诊疗室:复杂技术问题解决实录
运维·bug