常见问题:ivy:publish是如何工作的?

26
我完全不知道ant任务ivy:publish应该如何工作。
我希望先进行正常的构建,生成一堆jar文件,然后将这些jar文件推送到(本地)存储库。
我该如何指定从哪里检索已构建的jar文件,并且这些文件将如何最终进入存储库?
更新:
<target name="publish-local" description="--> Publish Local">
    <ivy:retrieve />
    <ivy:publish resolver="local" pubrevision="${release.version}" status="release" update="true" overwrite="true">
        <artifacts pattern="${dist.dir}/[organisation]-[module].[ext]" />
    </ivy:publish>
</target>

这真的有效,我之前没有包括retrieve。但我仍然有一些问题,假设我想发布3个jar文件,openscada-utils.jar、openscada-utils-sources.jar和openscada-utils-javadocs.jar作为openscada-utils-0.9.2.jar、openscada-utils-0.9.2-sources.jar和openscada-utils-0.9.2-javadocs.jar。对于实际的名称组装方式以及我在哪里可以指定它们应该获得哪些名称并不是完全清楚的。(使用上面的代码片段,这些jar文件总是只被称为utils.jar)。

更新1:

我让它(有点)工作了,但仍然感觉不太对。某种程度上所有教程都关注来自第三方项目的依赖项,但对我同样重要的一点是处理项目特定的依赖项。

我有一堆相互依赖的子项目。考虑到ivy:publish,我不清楚如何开始。

  1. 我如何处理第一个版本?我有一个公共的版本号,用于表示它们彼此之间属于一起(假设为0.9)。因此第一个修订版应该是0.9.0,但迄今为止我的项目中没有任何内容在我的存储库中。如何让Ivy分配此修订号。

  2. 在开发过程中,我想再次发布构建文件,但迄今为止不更改修订号。

  3. 如果我完成工作后,我想将其推送到共享存储库(并将修订号从0.9.0增加到0.9.1),推荐的方法是什么?

  4. 对于实际发布,我想制作带有依赖项和不带依赖项的分发版,某种程度上我想我可以使用不同的配置来实现。如何利用这一点?


仅供参考,根据这里的说明,“deliver”任务是由“publish”任务调用的。 - Johnny Hujol
4个回答

10

您需要指定 "resolver"。例如:

<ivy:publish resolver="local" pubrevision="1.0"/>

这受到模式的控制。这个页面对此进行了很好的解释。看起来你想要的是:

<artifacts pattern="${dist.dir}/[organisation]-[module]-[revision]-[type].[ext]" />

你需要在ivy.xml文件中将三个jar包标识为artifacts,类似于以下内容:
<publications>
    <artifact name="utils"/>
    <artifact name="utils" type="source"/>
    <artifact name="utils" type="javadocs"/>
</publications>

4

首先,您需要一个ivy.xml文件。

<ivy-module version="2.0">
    <info organisation="com.example.code" module="MyProject"
         revision="${project.revision}"/>
    <configurations>
        <conf name="runtime" description="" />
        ... other config elements here...
    </configurations>

    <publications defaultconf="runtime">
        <artifact name="MyProject" type="jar" ext="jar" conf="runtime" />
    </publications>

    <dependencies>
        ...
    </dependencies>
</ivy-module>

ivy.xml中的info元素和publications元素允许您在build.xml中跳过各种ivy元素上的属性。

请注意ivy.xml中的${project.revision}。该属性在build.xml中被赋值,但这似乎很好地工作。然后,修订版可以轻松地具有所需的任何值(例如夜间构建与本地构建)。

以下是设置build.xml文件的示例

<property name="project.revision" value="1.0.0"/>

...

<target name="ivy">
    <ivy:resolve />

    <!-- Possible ivy:report, ivy:retrieve and other
    elements for managing your dependencies go here -->

    <ivy:deliver conf="*(public)"/> 
</target>

<target name="publish" depends="clean, ivy, jar">
    <ivy:publish resolver="local">
        <!-- possible artifacts elements if your artifacts
        are not in standard location -->
    </ivy:publish>
</target>

...

好的参考资料 http://draconianoverlord.com/2010/07/18/publishing-to-maven-repos-with-ivy.html - Peter Lamberg

3

首先,你需要运行<ivy:deliver/>任务。这将创建一个可用于Ivy仓库的ivy.xml文件。

当你使用<ivy:publish>时,你需要通过resolver参数指定要发布到哪个仓库。这需要与你的ivy.settings.xml文件中的解析器名称匹配。

你不需要真正指定工件,而是指定一个模式来查找要发布的工件。你可以通过<ivy:publish>任务上的<artifacts>子任务来指定这个模式。例如,如果像我们一样构建位于${basedir}/target/archive目录下的所有内容,则可以将其指定为:

<ivy:publish resolver="public">
   <artifacts path="target/archive/[artifact].[ext]"/>
</ivy:publish>

如果您想更改文件的修订号,可以使用<ivy:publish>任务的pubrevision参数。这不会更新ivy.xml,但会将您的jars/wars发布到正确的修订号。我更喜欢使用<ivy:deliver>任务的pubrevision参数,并让它创建正确的ivy.xml文件。然后,<ivy:publish>将使用我ivy.xml文件中的修订号。
您不需要执行<ivy:retrieve>。毕竟,您正在运行构建以创建新的jars,它们应该在您的构建中的某个地方。否则,如果您没有创建jar或war,那么您要发布到Ivy存储库中的是什么?而且,您肯定不想检索已经在Ivy存储库中的内容,只是为了重新发布它。
我的理念一直是,发布是一个配置管理任务,不应该作为构建过程的一部分完成。因此,我们不使用<ivy:deliver><ivy:publish>
我们使用Artifactory作为我们的Ivy仓库(和Maven仓库)。我们使用Jenkins作为我们的持续构建服务器。
我让开发人员通过<ivy:makepom>任务将他们的ivy.xml文件制作成pom.xml文件。这个文件以及构建的jar/war被保存为归档的构件在Jenkins中。
当我们对特定的构建满意并希望将其放入我们的公共仓库时,我使用Jenkins的“推广构建”任务将特定的jar/war与其pom.xml推广到我们的Artifactory仓库中。我们使用mvn deploy:deploy-file任务来完成这个过程。

0

了解ivy在这里的作用非常重要。它不仅仅是将您的构件jar复制到ivy存储库中,还会生成相关的“.ivy.xml”文件,指定每个构件的所有依赖项。

在底层,ivy:retrieve任务实际上也会触发一个ivy:resolve。当发生ivy:resolve时,会将一个文件写入本地ivy缓存(位于user.home中的.ivy文件夹中),该文件指定了如何完成解析所需的所有模块的哪些版本。当遇到ivy:publish时,将从缓存中检索解析记录,并用于为您的构件生成ivy.xml。

我发现这样做的最大陷阱是需要在ant执行时同时加载ivy:resolveivy:publish任务的同一类加载器。确保这种情况发生的最简单方法是在taskdef任务上使用loaderRef。例如(请注意匹配的loaderRef标签):

<taskdef name="ivy-retrieve" 
     classname="org.apache.ivy.ant.IvyRetrieve" 
     classpathref="ivy.lib" 
     loaderRef="ivy.loader"/>
<taskdef name="ivy-publish" 
     classname="org.apache.ivy.ant.IvyPublish" 
     classpathref="ivy.lib" 
     loaderRef="ivy.loader"/>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接