
本文介绍如何在 Groovy(尤其适用于 Jenkins Pipeline)中对固定版本字符串列表进行智能分组与模式匹配,精准识别形如 Version-2.3.0.0 的基础版本是否对应存在 Version-2.3.1.0 等非零第三位的“点发布”版本。
本文介绍如何在 groovy(尤其适用于 jenkins pipeline)中对固定版本字符串列表进行智能分组与模式匹配,精准识别形如 `version-2.3.0.0` 的基础版本是否对应存在 `version-2.3.1.0` 等非零第三位的“点发布”版本。
在 Jenkins Pipeline 的 Groovy 脚本中,常需对不可变的版本字符串列表(如 ["Version-2.5.0.0", "Version-2.4.1.0", ...])进行逻辑判断——例如:对每个以 .0.0 结尾的基础版本,检查是否存在同一主次版本下、第三位(修订号)大于 0 的“点发布”版本(如 2.4.1.0 对应 2.4.0.0)。直接使用 contains() 或拼接正则字符串进行匹配(如 "^Version-2.4.(.[1-9]+).0$") 是无效的,因为 List.contains() 不支持正则匹配,且字符串插值生成的正则未被实际编译执行。
正确解法是 先按主次版本(如 2.4)分组,再在每组内判断是否存在符合点发布特征的版本。以下为推荐实现:
def version_list = ["Version-2.2.0.0", "Version-2.2.1.0", "Version-2.1.1.0", "Version-2.1.0.0", "Version-2.3.0.0"]
// 步骤1:按前两位版本号分组(提取 "2.2"、"2.1" 等),注意统一格式(假设格式恒为 Version-X.Y.Z.W)
def verMap = version_list.groupBy { ver ->
def parts = ver.split('-')[1].split('\.') // 得到 ["2","2","0","0"]
"${parts[0]}.${parts[1]}" // 提取主版本+次版本
}
// 步骤2:对每组执行判定逻辑
verMap.each { versionKey, versionsInGroup ->
// 找出该主次版本下的最小版本(即 Z=0,W=0 的基础版,通常为根版本)
def baseVersion = versionsInGroup.min { it }
// 检查组内是否存在点发布:Z > 0 且 W == 0(常见约定),或更通用地:Z ≥ 1
boolean hasPointRelease = versionsInGroup.any {
it ==~ /^Version-d+.d+.[1-9]d*.d+$/
}
println "${baseVersion} ${hasPointRelease ? 'has a point release!' : 'has no point release'}"
}
✅ 输出示例:
Version-2.1.0.0 has a point release! Version-2.2.0.0 has a point release! Version-2.3.0.0 has no point release
关键说明与注意事项:
- 正则表达式 ==~ 是 Groovy 的全匹配操作符,等价于 Pattern.matches(...),必须确保完全匹配整串;而 =~ 返回 Matcher,需显式调用 find()。
-
分组依据需健壮:上述示例假设版本格式严格为 Version-X.Y.Z.W。若存在 Version-10.12.3.4 等多位数版本,建议改用正则提取:
ver.replaceAll(/^Version-(d+.d+)..*$/, '$1')
- 避免副作用:勿在 each{} 中修改原集合或依赖迭代顺序——Groovy 的 groupBy 和 any{} 均为无副作用函数式操作,安全可靠。
- Jenkins Pipeline 兼容性:所有语法(==~, groupBy, any)均兼容 Jenkins 内置 Groovy 2.4+,无需额外依赖。
该方案时间复杂度为 O(n),远优于嵌套遍历(O(n²)),且语义清晰、易于维护,是处理 Jenkins 版本过滤任务的专业实践。










