Gradle+Jenkins+Artifactory Pro:快照版本转正式版问题求助
解决Artifactory交互式晋升时快照版本重命名问题
看起来你已经走通了快照上传的流程,卡在了晋升时版本号的转换上——这很常见,因为addInteractivePromotion默认只是做制品复制,不会自动处理版本号的修改。下面我给你两种可行的解决方案,你可以根据自己的场景选择:
方案一:在Jenkins流水线中自定义晋升逻辑(推荐,灵活可控)
这种方法直接在你的脚本化流水线里添加版本重命名、上传的步骤,不需要修改Artifactory的配置。核心思路是:触发晋升后,先下载快照制品,重命名去掉-SNAPSHOT后缀,再上传到release-local仓库。
具体代码示例
在你现有的Jenkins流水线脚本中,修改addInteractivePromotion的onPromotion回调,加入自定义逻辑:
// 假设你的Artifactory服务器在Jenkins中配置的ID是'artifactory-server' def artifactoryServer = Artifactory.server 'artifactory-server' def buildInfo = Artifactory.newBuildInfo() // 配置交互式晋升 addInteractivePromotion( server: artifactoryServer, buildInfo: buildInfo, promotionName: "Snapshot to Release Promotion", comment: "Promote snapshot artifact to official release", targetRepo: "release-local", // 重点:在晋升触发后执行自定义逻辑 onPromotion: { promotionContext -> // 从构建信息中找到快照制品 def snapshotArtifact = buildInfo.modules[0].artifacts.find { artifact -> artifact.name.contains('-SNAPSHOT') } if (!snapshotArtifact) { error "No SNAPSHOT artifact found in the current build info!" } // 1. 提取并转换版本号 def snapshotFileName = snapshotArtifact.name // 处理普通快照(如project-1.0.1-SNAPSHOT.rpm) def releaseFileName = snapshotFileName.replace('-SNAPSHOT', '') // 如果是带时间戳的快照(如project-1.0.1-20240520.123456-1.rpm),用正则替换 // def releaseFileName = snapshotFileName.replaceAll('-\\d{8}\\.\\d{6}-\\d+', '').replace('-SNAPSHOT', '') // 2. 下载快照制品到Jenkins工作目录 def downloadSpec = """{ "files": [ { "pattern": "snapshot-local/${snapshotArtifact.path}", "target": "./downloaded-artifacts/" } ] }""" artifactoryServer.download(downloadSpec) // 3. 重命名制品 sh "mv ./downloaded-artifacts/${snapshotFileName} ./downloaded-artifacts/${releaseFileName}" // 4. 上传重命名后的正式制品到release-local def uploadSpec = """{ "files": [ { "pattern": "./downloaded-artifacts/${releaseFileName}", "target": "release-local/${snapshotArtifact.path.replace(snapshotFileName, releaseFileName)}" } ] }""" artifactoryServer.upload(uploadSpec, buildInfo) // 5. 发布更新后的构建信息到Artifactory artifactoryServer.publishBuildInfo(buildInfo) // 可选:如果不需要保留快照制品,可以删除原文件 // artifactoryServer.delete("snapshot-local/${snapshotArtifact.path}") } )
注意事项
- 确保Jenkins节点有Artifactory的下载、上传权限(如果要删除快照,还需要删除权限)
- 如果你的快照版本带时间戳(Gradle默认会生成这种格式),记得用注释里的正则替换逻辑
- 测试时可以先跳过删除快照的步骤,确保正式制品上传成功后再添加
方案二:用Artifactory用户插件处理重命名(适合多项目复用)
如果你的团队有多个项目需要同样的晋升逻辑,可以在Artifactory端编写一个用户插件,让晋升操作自动处理版本重命名。
插件代码示例
在Artifactory的$ARTIFACTORY_HOME/etc/plugins目录下创建一个promotion-rename.groovy文件,内容如下:
promotion { afterPromotion { promotionCtx -> def buildInfo = promotionCtx.buildInfo def targetRepo = promotionCtx.targetRepoKey def sourceRepo = promotionCtx.sourceRepoKey // 遍历所有制品,处理带SNAPSHOT的文件 buildInfo.modules.each { module -> module.artifacts.each { artifact -> def sourcePath = "${sourceRepo}/${artifact.path}" // 转换版本号,去掉SNAPSHOT和时间戳(如果有) def releasePath = artifact.path.replaceAll('-\\d{8}\\.\\d{6}-\\d+', '').replace('-SNAPSHOT', '') def targetPath = "${targetRepo}/${releasePath}" // 复制并重命名制品到目标仓库 repositories.copy(sourcePath, targetPath) // 可选:删除原快照制品 // repositories.delete(sourcePath) } } } }
然后重启Artifactory,之后触发Jenkins的交互式晋升时,Artifactory会自动完成版本重命名的操作。
注意事项
- 需要Artifactory管理员权限来安装和配置插件
- 插件会作用于所有晋升操作,如果你有部分项目不需要这个逻辑,需要添加条件判断(比如根据仓库或项目名过滤)
总结
两种方案都能解决你的问题:Jenkins端的方案更灵活,适合单个项目定制;Artifactory插件方案更适合团队统一管理。根据你的实际情况选择即可,测试时记得先验证制品的版本号和仓库路径是否正确哦!
内容的提问来源于stack exchange,提问作者dagra
相关产品推荐
相关产品推荐

