使用 IVY 将 SNAPSHOT 工件发布到 Maven - 有啥魔力?

Posted

技术标签:

【中文标题】使用 IVY 将 SNAPSHOT 工件发布到 Maven - 有啥魔力?【英文标题】:Publish SNAPSHOT artifacts to Maven using IVY - what's the magic?使用 IVY 将 SNAPSHOT 工件发布到 Maven - 有什么魔力? 【发布时间】:2012-01-20 06:17:04 【问题描述】:

我们的情况有点复杂……

在大多数情况下,我们一直在使用 IVY 和 ANT 来管理我们的构建和依赖项。现在该公司正朝着使用 Maven 的方向发展。我们有一组称为公共库的项目,供多个核心产品使用。

普通库使用 IVY 并发布到 IVY 存储库。我们还需要为我们的新 Maven 项目提供通用库。因此,当构建和发布公共库时,我修改了脚本以发布到 Maven(Artifactory)以及 IVY。以下是在发布已构建的 IVY 项目时调用的两个目标:

<target name="publish-ivyrepo" depends="load-ivysettings">
    <ivy:resolve file="ivy.xml"  /> 
    <ivy:publish 
        module="$ant.project.name"
        artifactspattern="$dist.dir/[artifact].[ext]" 
        resolver="integration" 
        pubrevision="$build.version" 
        status="integration"    
        overwrite="true"
        update="true"/>
</target>

<target name="publish-artifactory" depends="load-ivysettings">
    <ivy:resolve file="ivy.xml"  /> 
    <ivy:publish 
        module="$ant.project.name"
        artifactspattern="$dist.dir/[artifact].[ext]" 
        resolver="artifactory" 
        pubrevision="$build.version-SNAPSHOT" 
        status="integration"    
        overwrite="true"
        update="true"/>
</target>

这里是详细说明解析器的 IVY 设置:

<sftp name="integration" checkmodified="true" changingPattern=".*" host="host" user="ivy" userPassword="abc">
  <ivy pattern="$ivy.integration.default.root/$ivy.public.default.ivy.pattern"/>
  <artifact pattern="$ivy.integration.default.root/$ivy.public.default.artifact.pattern"/>
</sftp>
<url name="artifactory" checkmodified="false" changingPattern=".*" m2compatible="true">
  <ivy pattern="http://server/artifactory/libs-snapshot-local/$maven.default.ivy.pattern"/>
  <artifact pattern="http://server/artifactory/libs-snapshot-local/$maven.default.artifact.pattern"/>
</url>

我现在在 Artifactory 中看到了常见的库 jar,其中 SNAPSHOT 代替了唯一的时间戳。但是,源 jar 和 IVY xml 文件没有替换 SNAPSHOT。此外,没有生成 POM 文件(虽然我不知道这是否有必要。

所以这似乎没问题,尽管关于 POM 文件的需求以及 IVY xml 和源 jar 的版本命名存在一些问题。但是,当我现在继续指定从 Maven 项目之一到公共库项目的 SNAPSHOT 版本之一的依赖关系时,它抱怨它无法解决依赖关系:

缺少工件 com.smartstream.common_library:common_library_dao:jar:4.0.0.5-4-SNAPSHOT:compile

我尝试通过 POM 文件和 Maven 设置文件将存储库指定给 Artifactory,但收效甚微:

<repository>
    <id>test</id>
    <name>simple test</name>
    <url>http://server/artifactory/libs-snapshot</url>
    <releases>
        <enabled>false</enabled>
    </releases>
    <snapshots>
        <enabled>true</enabled>
    </snapshots>
</repository>

奇怪的是,如果我让 IVY 将一个版本发布到 Artifactory 的 libs-release-local 存储库中,而不是一个 SNAPSHOT,那么所有问题都如您所愿。此外,如果我将唯一时间戳指定为依赖版本的一部分(SNAPSHOT 的替代品),它也会解决它。所以这表明 Maven 项目能够解决 Artifactory,只是 SNAPSHOT 版本出了点问题。

在这个问题上,我一直在四处寻找,希望渺茫。如果您能提供任何见解,我们将不胜感激。

【问题讨论】:

【参考方案1】:

如果您已经打算迁移到 Maven,我建议您查看 Aether Ant Tasks,它是旧的(现在几乎已弃用)Maven Ant Tasks 的替代品。使用它将公开您的任务所需的所有必需的 Maven 依赖项处理功能..

【讨论】:

令人失望的是,Aether ANT 任务仍未正式发布,在 Maven Central 中不可用,似乎获得它们的唯一方法是编译 github 源代码。较旧的 Maven ANT 任务仅支持 Maven 2 ..... 这意味着,目前,ivy 是与 Maven 存储库交互的最佳非 Maven 方式:-) 很公平。我在 github 上创建了一个问题,项目请求发布。【参考方案2】:

从 ivy 发布到 Nexus 存储库已在此处得到解答:

how to publish 3rdparty artifacts with ivy and nexus

这个答案可能太全面了。相关部分的标题为“常春藤解决方案”。我在这里总结一下:

示例

ivy.xml

您需要一个发布部分来说明您正在发布一个 jar 并且它与 POM 相关联:

<ivy-module version='2.0'>
    <info organisation="com.myspotonontheweb" module="donaldduck"/>

    <publications>
        <artifact name="donaldduck" type="jar"/>
        <artifact name="donaldduck" type="pom"/>
    </publications>

    ..
    ..

</ivy-module>

注意事项:

另一个示例更复杂,演示如何将其他工件添加到 Maven 模块。

ivysettings.xml

我正在使用 ibiblio 解析器,并打开了 Maven 2 兼容性。根据我的经验,这是在 ivy 中配置 Maven 存储库的最佳方式。

<ivysettings>
    <settings defaultResolver="nexus-central"/>
    <credentials host="somehost" realm="Sonatype Nexus Repository Manager" username="????" passwd="????"/>
    <resolvers>
        <ibiblio name="nexus-central" root="http://somehost/nexus/content/repositories/central/" m2compatible="true"/>
        <ibiblio name="nexus-deploy" root="http://somehost/nexus/content/repositories/repo" m2compatible="true"/>
    </resolvers>
</ivysettings>

注意事项:

对于工件,凭据 realm 参数将为“工件领域”。

build.xml

最后是构建逻辑本身。

<target name="prepare" description="Generate POM">
    <ivy:deliver deliverpattern="$build.dir/ivy.xml" pubrevision="$publish.revision" status="release"/>
    <ivy:makepom ivyfile="$build.dir/ivy.xml" pomfile="$build.dir/donaldduck.pom"/>
</target>

<target name="publish" depends="init,build,prepare" description="Upload to Nexus">
    <ivy:publish resolver="nexus-deploy" pubrevision="$publish.revision" overwrite="true" publishivy="false" >
        <artifacts pattern="$build.dir/[artifact](-[classifier]).[ext]"/>
    </ivy:publish>
</target>

注意事项:

prepare 目标使用makepom 任务生成 POM。 ivy deliver 任务是可选的,但如果您的 ivy 文件中有任何动态修订(latest.integration、latest.release),建议您使用。 publish 目标发布到您的设置文件中定义的 nexus-deploy 解析器。 $publish.revision 属性在构建中的其他位置设置。我建议阅读有关 ivy 的 buildnumber 任务

关于工件的注意事项

Artifactory 好像有一些built-in support for ivy

【讨论】:

很好解释,帮助很大。但是,此解决方案仍然无法上传 pom.xml。为了实现这一点,我必须将&lt;artifact name="donaldduck" ext="pom" type="pom" /&gt; 添加到&lt;ivy:publish&gt; 目标的内部元素中。它在这里描述:[theholyjava.wordpress.com/2011/01/26/using-ivy-with-pom-xml/],但老实说我不明白这是如何工作的(奇怪的是,我将 pom 生成到一个子文件夹中,但不必在 &lt;artifact> 元素中声明这个子文件夹) 抱歉,格式错误,右方括号不应该是 URL 的一部分:theholyjava.wordpress.com/2011/01/26/using-ivy-with-pom-xml

以上是关于使用 IVY 将 SNAPSHOT 工件发布到 Maven - 有啥魔力?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Maven 元数据发布 Ivy SNAPSHOTS

Play 2.0 和 SNAPSHOT 依赖项

Nexus OOS 2 作为 ivy 工件的代理

如何使用 maven 从 ivy 存储库下载工件

Apache IVY 到 Maven:排除工件的错误?

如何解决模块 X 的多个工件被检索到 Apache Ivy 中的同一个文件?