Artifactory + Jenkins:从自由式构建发布到 Maven 存储库

Artifactory + Jenkins: Publishing to a maven repository from a freestyle build

我有一个基于使用 SBT 的 Scala 项目的 Jenkins 自由式构建。我正在尝试使用 Jenkins Artifactory plugin 将生成的工件发布到 Artifactory 存储库,特别是托管在 artifactoryonline.com 的存储库。但是,我正在努力寻找一个合理的配置。我倾向于怀疑我遗漏了什么,但我无能为力,我发现的 none 文档似乎详细介绍了这个用例,我是厌倦了浏览 Artifactory 插件源代码。任何帮助都表示赞赏。

场景如下。我愿意:

  1. 使用 SBT 构建一个自由风格的 Jenkins 项目,独立于版本号,这样当前项目版本(在 pom/ivy 工件中编码)是隐式和自动的。
  2. 将工件和构建信息发布到在 Jenkins 中配置的工件存储库(未在我的 SCM 的 build.sbt 中配置)

以下是我尝试过的方法。

方法 1:自由式 + 通用 Artifactory 集成

第一种方法是使用自由式构建,然后使用 Generic-Artifactory 集成。对于 "Published Artifacts",我将其设置为

target/scala-2.11/*=>com.mycompany/my-module_2.11

构建成功,jar和sources-jar和javadoc-jar和ivy文件和POM文件都在该目录下生成。但是,发布失败,209 冲突。 Artifactory 日志不喜欢目标路径:

Sending HTTP error code 409: The target deployment path 'com/mycompany/my-module_2.11/my-module_2.11-1.0.6.pom' does not match the POM's expected path prefix 'com/mycompany/my-module_2.11/1.0.6'. Please verify your POM content for correctness and make sure the source path is a valid Maven repository root path.

我可以让 209 错误消失,通过不使用标准的 maven-2 路径(其中,除其他外,需要为此 repo 禁用 POM 一致性检查),这表明我必须更新所有下游能够使用此 repo 的配置。

我可以更新插件的目标路径设置以包含版本号:

target/scala-2.11/*=>com.mycompany/my-module_2.11/1.0.6

但这意味着我已经为每个版本修改了我的 Jenkins 构建,这似乎违背了目的。我无法想象这是使用这些工具的正确方法。

方法 2:自由式 + Artifactory Maven

在这种情况下,我坚持使用自由式 SBT 构建。在 "Build Environment" 下,我选择了 "Maven3-Artifactory Integration"。我针对我的全局工件存储库配置了插件,检查 "Deploy artifacts to Artifactory",并将 "Include Patterns" 设置为

target/scala-2.11/*

我 运行 生成了工件(包括 target/scala-2.11 目录中的 POM 和 ivy.xml 文件),但在部署方面似乎没有发生任何事情的文物。 Artifactory 日志中没有任何内容,没有新构建,控制台输出或 Jenkins 日志中也没有任何内容表明它曾尝试将任何工件部署到我的存储库。

方法 3:自由式 + Artifactory Ivy

在这种情况下,我坚持使用自由式构建,但在 "Build Environment" 下,我选择了 "Ant/Ivy-Artifactory Integration." 我选择了全局配置的 Artifactory 存储库,检查 "Publish artifacts to Artifactory" 和 "Use Maven Compatible Patterns"。我将我的 SBT 项目配置为 "publishLocal"(根据插件说明),并设置以下路径 screenshot of ivy configuration。构建的项目和工件被部署到 ~/.ivy2/local,但显然没有被插件拦截,也没有任何东西被推送到我配置的 Artifactory 仓库(也许这个插件与自由风格不兼容?)

我修改了 SBT 构建以执行 "publish" 而不是 "publishLocal",希望插件能够启动并拦截 Ivy 发布,但是因为我的 built.sbt 没有配置使用 publishTo 存储库目标,我自然会得到一个错误 "Repository for publishing is not specified".

方法 4:虚拟 Maven 构建

下一个方法:跳过泛型,使用完整的 maven。我在 Jenkins 中设置了一个新构建,这是一个 Maven 项目。它有一个运行我的 SBT 构建的预构建步骤,生成 pom 工件以及二进制和源 jar。然后,我将构建步骤配置为使用我的 SBT 构建生成的 POM。不幸的是,jenkins/maven 插件的 "Root POM" 参数不接受通配符,所以我处理它的唯一方法是指定完整(版本化)路径:

target/scala-2.11/my-resource_2.11-1.0.6.pom

所以,这是不幸的和站不住脚的,因为我不愿意在每次增加版本号时更新我的​​ Jenkins 构建。尽管如此,我还是想看看这种方法是否有效,所以我继续前进。我针对全局配置的 Artifactory 添加了 post-构建步骤 "Deploy Artifacts to Artifactory"。对于 Maven 目标 "help:help",没有任何内容被推送,因此 Maven 拦截器没有任何内容可以拦截并推送到我的人工制品(无论如何,这是我对它如何工作的理解)。所以我再次尝试,将构建步骤中的 Maven 目标替换为 "deploy"。这一次,拦截器将我的大部分(全部?)依赖项推送到我的 Artifactory 服务器。但是,在推送所有依赖项之后,它显然无法尝试编译我的 "maven" 项目。我没有深入研究这个问题,但我认为这是因为生成的 POM 文件没有指定任何构建指令。

结论

再次感谢您的帮助。看起来这应该是一个相当主流的用例,而且 Artifactory 插件的文档明确指出支持自由式构建 + Maven 部署,但我显然遗漏了一些东西。任何帮助是极大的赞赏!谢谢。

这是一个很好的问题!

选择 "Approach 1" 才是正确的选择。如果您不想在路径中包含版本,它会使路径与 Maven 不兼容,这可能没问题,但您需要配置存储库(如您所知和所做的)。 是的,评论中的解决方案也是一个有效的技巧。