如何在Maven中仅部署pom文件到快照库?

16

当运行mvn deploy命令且版本为SNAPSHOT版本时,我希望只部署POM文件而不是主要文件(JAR,WAR等)。

为什么?

我们有多个开发人员在多个Maven项目上工作。我们有一个Hudson服务器,每个Maven项目和版本都有一个作业(例如foo-1.2,foo-1.3)。每个作业都构建该项目并将其部署到Nexus服务器(成功后)。正在开发中的Maven项目使用版本中的-SNAPSHOT后缀标记。例如:1.2-SNAPSHOT,1.3-SNAPSHOT。

以下是一个开发人员由于此架构而遭受损失的示例场景。

假设有两个Maven项目:foo-core和foo-webapp,均为1.2-SNAPSHOT版本。

  • 开发人员A正在处理foo-core,进行了几次更改并编译了它。
  • 开发人员A接着开始处理foo-webapp。
  • 开发人员B开始处理和更改foo-core并提交他的工作并将其推送到SCM。
  • Hudson被SCM触发;构建foo-core并将其部署到Nexus中的快照存储库中。
  • 开发人员A在foo-webapp上运行mvn install。 Maven与Nexus检查,发现在Nexus中有一个更新版本的foo-core。它下载了它(填充了开发人员B的更改),然后编译失败,因为由开发者A所做的更改不在本地存储库中的jar文件中。下载覆盖了开发人员A安装的文件。

现有解决方案

我研究了maven-deploy-plugin,但是该插件部署了项目附加的所有工件。如果他们有一种方式来配置要部署哪些工件,这将非常好。

问题:是否有不需要编写基于maven-deploy-plugin的自己的部署插件的解决方法?

4个回答

23

基本上,将-Dfile参数中的构件改为pom.xml。执行命令,耶!现在mvn deploy不会出现任何问题。这是一个样例deploy命令:

$ mvn deploy:deploy-file -DpomFile=pom.xml -Dfile=./pom.xml -DgroupId=my.group.id -DartifactId=artifact-id -DrepositoryId=bigdata-upload-snapshots -Durl=http://maven.mymaven.com/content/repositories/snapshots/

前提是需要将该仓库添加到您的settings.xml文件中。

[编辑]: 我已在示例部署命令中提供了项目的-DgroupId-DartifactId参数,但它们不是必需的(请参阅Zac下面的评论)。


8
如果你正在使用“-DpomFile =”命令,那么你不需要使用groupId和artifactId;这些信息将会从POM文件中推断出来。 - Zac Thompson

2
我从未听说过这样的可能性,如果可能的话,我也会非常惊讶。由于 pom 和生成的 artifact 是某种单元,因此仅部署它们的一部分对我来说是没有意义的。
尽管如此,您应该考虑创建一个单独的 pom 项目,其中指定了您可能想要在 JAR/WAR 项目中使用的依赖项和插件,例如:
<groupId>foo.bar</groupId>
<artifactId>my-pom</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>

然后,您可以通过以下方式将该pom项目继承到您的JAR/WAR项目中:
<parent>
    <groupId>foo.bar</groupId>
    <artifactId>my-pom</artifactId>
    <version>1.0.0</version>
</parent>

这被称为项目继承。您可以独立于“子”工件更改和部署pom项目。
在阅读动机后编辑
据我理解,您想要防止maven从存储库中解析SNAPSHOT工件(以便本地版本不会被覆盖)。您是否尝试过使用mvn -nsu选项(参见mvn -help)?
-nsu,--no-snapshot-updates             Suppress SNAPSHOT updates

我从未尝试过,但发现了这个问题的报告。不过,由于这个问题还没有被评论,我会尝试一下。

我已经编辑了我的问题并添加了请求的动机,以更好地澄清我的问题。 - Asaf Mesika
我同意@FrVaBe的观点,不认为你所要求的可以实现,也不认为这是解决你情况的最佳方案。-nsu-o(离线)标志对于开发人员A避免问题很有用。但是,如果开发人员A正在从多模块项目的顶层构建代码,则不应该需要这样做,因为他本地版本的foo-core将优先于Hudson部署的新版本。最后,默认情况下,Maven仅在每个环境中每天查找一次快照更新,因此此情况每天最多会发生一次。 - ctrueden

1
这对我来说是有效的,仅适用于部署 pom 文件(例如与现有的 jar 文件一起):
(注意: 你需要同时指定打包方式,否则它将被上传为一个 .xml 文件,而这不是你想要的。)
mvn deploy:deploy-file \
-Dfile=pom.xml \
-Dpackaging=pom \
-DgroupId=com.mycompany.package \
-DartifactId=my-artifact \
-Dversion=2.0.1 \
-DrepositoryId=serverIdFromSettingsXMLForCredentials \
-Durl=http://repositoryserver/myrepo/

0

对于这些人所提出的问题,这并不完全是他们想要的答案。我的情况是我只想部署父POM。我在一个子模块中使用了spring-boot-thin-layout,这要求将父模块部署到Artifactory中。我在项目中添加了以下内容。它允许跳过install和/或deploy阶段。

在我的父POM中:

<properties>
    <disable.install>true</disable.install>
    <disable.deploy>true</disable.deploy>
    <enable.deployAtEnd>true</enable.deployAtEnd>
</properties>

<profiles>
    <profile>
        <id>deploy-parent</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <disable.install>true</disable.install>
            <disable.deploy>true</disable.deploy>
            <deployAtEnd>${enable.deployAtEnd}</deployAtEnd>
        </properties>
        <build>
            <finalName>${project.version}</finalName>
        </build>
    </profile>
</profiles>

在我的子POM或任何模块中,如果您不想与父级一起部署:

<properties>
    <maven.install.skip>${disable.install}</maven.install.skip>
    <maven.deploy.skip>${disable.deploy}</maven.deploy.skip>
    <deployAtEnd>${enable.deployAtEnd}</deployAtEnd>
</properties>

因此,当我在父POM上运行mvn deploy时,它将编译所有模块,不会在任何模块上运行安装操作,最后部署任何未被`


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