Java ivy:publish 如何运作?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/353336/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 13:44:26  来源:igfitidea点击:

How does ivy:publish work?

javaantbuild-processbuild-automationivy

提问by Mauli

I'm completely at loss how the ant task ivy:publish is supposed to work.

我完全不知道 ant 任务 ivy:publish 应该如何工作。

I would expect that I do my normal build, which creates a bunch of jar files, then I would push those jars to the (local) repository.

我希望我进行正常的构建,这会创建一堆 jar 文件,然后我会将这些 jar 推送到(本地)存储库。

How can I specify from where to retrieve the built jars, and how would those end up in the repository?

我如何指定从哪里检索构建的 jars,以及它们将如何在存储库中结束?

Update:

更新:

<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>

this actually works, I didn't include the retrieve before.

这实际上有效,我之前没有包括检索。

But I still have some problems, suppose I want to publish 3 jars, openscada-utils.jar, openscada-utils-sources.jar and openscada-utils-javadocs.jar as openscada-utils-0.9.2.jar, openscada-utils-0.9.2-sources.jar and openscada-utils-0.9.2-javadocs.jar

但是我仍然有一些问题,假设我想发布 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

It isn't entirely clear to me, how the actual names are assembled, and where I can specify which names they should get. (Using the fragment above, the jars are always called only utils.jar).

我并不完全清楚,实际名称是如何组合的,以及我可以在哪里指定它们应该获得哪些名称。(使用上面的片段,罐子总是只被称为 utils.jar)。

Update 1:

更新 1:

I got it to work (a bit), but it still doesn't feel right. Somehow all tutorials focus on dependencies from 3rd party projects, but an equally important point for me is to handle project specific dependencies.

我让它工作(有点),但它仍然感觉不对。不知何故,所有教程都关注来自 3rd 方项目的依赖项,但对我来说同样重要的一点是处理项目特定的依赖项。

I have a bunch of sub projects which depend on each other in various ways. Considering ivy:publish it is not clear to me how to start.

我有一堆子项目,它们以各种方式相互依赖。考虑到 ivy:publish 我不清楚如何开始。

  1. How do I handle the first version? I have a common version number for all sub projects to indicate that they belong together (lets say 0.9). Therefore the first revision should be 0.9.0, but so far nothing of my projects is in my repository. How do I get Ivy to assign this revision number.

  2. In the course of developing I want to publish the built files again, without changing the revision number so far.

  3. If I'm finished with my work I want to push it to a shared repository (and increase the revision number lets say from 0.9.0 to 0.9.1), what is the recommended approach to do so?

  4. For an actual release, I want to make distributions with dependencies and without, somehow I guess I can use different configurations for that. How can I use that to my advantage?

  1. 我如何处理第一个版本?我有所有子项目的通用版本号,以表明它们属于一起(比方说 0.9)。因此,第一个修订版应该是 0.9.0,但到目前为止,我的存储库中没有任何项目。我如何让 Ivy 分配此修订号。

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

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

  4. 对于实际发布,我想制作具有依赖关系和不具有依赖关系的发行版,不知何故我想我可以为此使用不同的配置。我怎样才能利用它来发挥我的优势?

回答by sblundy

You need to specify the "resolver". Something like:

您需要指定“解析器”。就像是:

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

It's controlled by the pattern. This pagecovers it pretty well. It looks like you want yours to be:

它由模式控制。这个页面很好地涵盖了它。看起来你想要你的:

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

And you'll need to identify the three jars as artifacts in the ivy.xml file. Something like this:

并且您需要将这三个 jar 标识为 ivy.xml 文件中的工件。像这样的东西:

<publications>
    <artifact name="utils"/>
    <artifact name="utils" type="source"/>
    <artifact name="utils" type="javadocs"/>
</publications>

回答by Jared

It's important to realize what ivy is doing here. It is NOT simply copying your artifact jars into the ivy repository - it is also generating the relevant ".ivy.xml" files that specify all the dependents of each of your artifacts.

重要的是要意识到常春藤在这里做什么。它不是简单地将您的工件 jar 复制到 ivy 存储库中 - 它还会生成相关的“.ivy.xml”文件,这些文件指定了您的每个工件的所有依赖项。

Under the covers, the ivy:retrievetask is actually also triggering an ivy:resolve. When that ivy:resolve occurs, a file is written to your local ivy cache (in the .ivyfolder in user.home) that specifies how the resolution happened (which revisions of which modules were required to complete the resolution.) When ivy:publishis encountered, that resolution record is retrieved from cache and used to generate the ivy.xml for your artifacts.

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

The largest pitfall I've found in doing this is the requirement that the ivy:resolveand ivy:publishtasks both be loaded by the same classloader when they are executed by ant. The easiest way to make sure this happens is to use the loaderRef on your taskdef tasks. For example (note the matching loaderRef tags):

我在这样做时发现的最大缺陷是要求ivy:resolveivy:publish任务在由 ant 执行时由同一个类加载器加载。确保这种情况发生的最简单方法是在 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"/>

回答by Peter Lamberg

First you need an ivy.xml file.

首先,您需要一个 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>

The info element and publications elements in ivy.xml allow you to skip various attributes on the ivy elements in build.xml.

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

Note the ${project.revision} in ivy.xml. The property is given value in build.xml, but this seems to work nicely. The revision can then easily have whatever value is required (eg. nightly builds vs. local builds).

注意ivy.xml 中的${project.revision}。该属性在 build.xml 中给出了值,但这似乎工作得很好。然后,修订版可以轻松获得所需的任何值(例如,每晚构建与本地构建)。

Here is a sample how you could set up your build.xml file

以下是如何设置 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>

...

回答by David W.

You're suppose to run the <ivy:deliver/>task first. This creates an ivy.xml file that can be used by the Ivy repository.

您应该先运行<ivy:deliver/>任务。这将创建一个可供 Ivy 存储库使用的 ivy.xml 文件。

When you use <ivy:publish>you specify which repository you want to publish to by specifying it in the resolverparameter. This needs to match the resolver name in your ivy.settings.xmlfile.

使用时,<ivy:publish>您可以通过在resolver参数中指定来指定要发布到的存储库。这需要与ivy.settings.xml文件中的解析器名称匹配。

You don't really specify the artifacts, but a pattern where to find the artifacts to publish. You specify this via the <artifacts>subtask on the <ivy:publish>task. For example, if you build everything under the ${basedir}/target/archivedirectory like we do, you can specify it as this:

您并没有真正指定工件,而是指定在哪里可以找到要发布的工件的模式。您可以通过<artifacts>任务上的子任务来指定它<ivy:publish>。例如,如果您${basedir}/target/archive像我们一样在目录下构建所有内容,则可以将其指定为:

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

If you want to change the revision number of your file, you can use the pubrevisionparameter of the <ivy:publish>task. This doesn't update the ivy.xml, but will publish your jars/wars to the correct revision. I prefer to use the pubrevisionparameter of the <ivy:deliver>task and let it create the correct ivy.xmlfile anyway. Then, <ivy:publish>will use the revision in my ivy.xmlfile.

如果要更改文件的修订号,可以使用任务的pubrevision参数<ivy:publish>。这不会更新ivy.xml,但会将您的 jars/wars 发布到正确的修订版。我更喜欢使用任务的pubrevision参数,<ivy:deliver>并让它创建正确的ivy.xml文件。然后,<ivy:publish>将在我的ivy.xml文件中使用修订版。

You don't need to do <ivy:retrieve>. After all, you're running a build to create new jars, and they should be SOMEWHERE in your build. Otherwise, if you're not creating a jar or war what are you trying to publish into your Ivy repository? And, you certainly don't want to retrieve something already in your Ivy repository just to republish it.

你不需要做<ivy:retrieve>。毕竟,您正在运行一个构建来创建新的 jar,它们应该在您的构建中的某个地方。否则,如果您不是在创建 jar 或 war,您想将什么发布到您的 Ivy 存储库中?而且,您当然不想为了重新发布而检索 Ivy 存储库中已有的内容。



My philosophy has always been that publishing is a CM task and shouldn't be done as part of the build procedure. Thus, we don't use <ivy:deliver>or <ivy:publish>.

我的理念一直是发布是一项 CM 任务,不应作为构建过程的一部分来完成。因此,我们不使用<ivy:deliver>or <ivy:publish>

We use Artifactory as our Ivy repository (and our Maven repository). We use Jenkinsas our continuous build server.

我们使用 Artifactory 作为我们的 Ivy 存储库(以及我们的 Maven 存储库)。我们使用Jenkins作为我们的持续构建服务器。

What I do is have the developers make a pom.xmlfile out of their ivy.xmlfile via the <ivy:makepom>task. This and the build jars/wars are saved as archived artifacts in Jenkins.

我所做的是让开发人员通过任务pom.xml从他们的ivy.xml文件中创建一个文件<ivy:makepom>。这和构建 jars/wars 被保存为 Jenkins 中的存档工件。

When we are happy with a particular build and want it in our public repository, I use Jenkin's Promote Build task to promote a particular jar/war with its pom.xml to our Artifactory repository. We use the mvn deploy:deploy-filetask to do that.

当我们对特定的构建感到满意并希望它在我们的公共存储库中时,我使用 Jenkin 的提升构建任务将带有 pom.xml 的特定 jar/war 提升到我们的 Artifactory 存储库。我们使用mvn deploy:deploy-file任务来做到这一点。