如何识别变更集所属代码仓库并过滤共享库变更?
Jenkins流水线过滤共享库变更集问题
我可以通过以下代码获取构建的所有变更集:
@NonCPS def sendChangeLogs() { def commitMessages = "" def formatter = new SimpleDateFormat('yyyy-MM-dd HH:mm') def changeLogSets = currentBuild.changeSets for (int i = 0; i < changeLogSets.size(); i++) { def entries = changeLogSets[i].items for (int j = 0; j < entries.length; j++) { def entry = entries[j] commitMessages = commitMessages + "${entry.author} ${entry.commitId}:\n${formatter.format(new Date(entry.timestamp))}: *${entry.msg}*\n" } } }
但目前遇到一个问题:我使用了Jenkins共享库,当前获取的变更集中包含了流水线所用共享库的变更。我想要按代码仓库过滤变更集,排除共享库的变更,但仅通过文件路径过滤并不足够。而且查看ChangeLogSet.Entry的API文档,发现该类并没有仓库相关的属性可以直接使用。
解决方案:通过SCM来源标识过滤
虽然ChangeLogSet.Entry本身没有仓库字段,但可以从changeLogSets的父对象入手——每个ChangeLogSet实例对应一个SCM仓库的变更,我们可以通过识别SCM的URL或名称来区分主项目和共享库的变更。
方法1:通过SCM URL关键词过滤
修改代码,在遍历changeLogSets时先判断当前仓库是否为共享库,再决定是否处理其下的变更条目:
@NonCPS def sendChangeLogs() { def commitMessages = "" def formatter = new SimpleDateFormat('yyyy-MM-dd HH:mm') // 定义共享库仓库的URL关键词,根据实际情况修改 def sharedLibRepoKeyword = "jenkins-shared-lib" def changeLogSets = currentBuild.changeSets for (int i = 0; i < changeLogSets.size(); i++) { def changeLogSet = changeLogSets[i] // 获取当前变更集对应的SCM仓库URL def scmUrl = changeLogSet.scm?.userRemoteConfigs?.first()?.url // 如果是共享库仓库,跳过处理 if (scmUrl?.contains(sharedLibRepoKeyword)) { continue } def entries = changeLogSet.items for (int j = 0; j < entries.length; j++) { def entry = entries[j] commitMessages = commitMessages + "${entry.author} ${entry.commitId}:\n${formatter.format(new Date(entry.timestamp))}: *${entry.msg}*\n" } } return commitMessages }
方法2:通过主项目SCM URL精准匹配
如果需要只保留主项目的变更,可以先获取主项目的SCM URL,再过滤出对应变更集:
@NonCPS def sendChangeLogs() { def commitMessages = "" def formatter = new SimpleDateFormat('yyyy-MM-dd HH:mm') // 获取当前流水线主项目的SCM URL def mainRepoUrl = currentBuild.project.scm.userRemoteConfigs.first().url def changeLogSets = currentBuild.changeSets for (int i = 0; i < changeLogSets.size(); i++) { def changeLogSet = changeLogSets[i] def scmUrl = changeLogSet.scm?.userRemoteConfigs?.first()?.url // 仅处理主项目的变更集 if (scmUrl == mainRepoUrl) { def entries = changeLogSet.items for (int j = 0; j < entries.length; j++) { def entry = entries[j] commitMessages = commitMessages + "${entry.author} ${entry.commitId}:\n${formatter.format(new Date(entry.timestamp))}: *${entry.msg}*\n" } } } return commitMessages }
注意事项
- 必须保留
@NonCPS注解,避免Jenkins流水线的CPS序列化问题 - 如果共享库是全局配置加载的,可调整识别逻辑(比如通过仓库名称)
- 测试时可先打印
changeLogSet.scm的内容,确认能正确获取SCM配置信息
内容的提问来源于stack exchange,提问作者red888
相关产品推荐
相关产品推荐

