【问题标题】:maven deploy changed artifacts onlymaven 仅部署更改的工件
【发布时间】:2010-12-24 00:52:18
【问题描述】:

我正在使用 maven 2.2 和 nexus 1.4.0

假设我有一个这样的 pom 结构(带有相应的版本)

parentproj, v1.0.1
 - childproj1, v1.0.2
 - childproj2, v1.0.7

childproj1 和 childproj2 代表应用程序的不同部分(例如 gui 和后端),我希望能够将它们的版本分开,以便我可以发布新版本的后端而不必发布新版本的 gui .

现在,要将这个结构部署到 Nexus,去 parentproj 说会很方便

mvn deploy -DperformRelease=true

这会将所有工件部署到 Nexus realease 存储库。这在我第一次部署时运行良好,但第二次遇到问题:假设我对 childproj1 进行了更新,因此我们现在拥有以下版本:

parentproj, v1.0.1
 - childproj1, v1.0.3
 - childproj2, v1.0.7

在这种情况下,Nexus 不会让我从 parentproj 执行 mvn deploy,因为它在 1.0.7 版本中已经有 childproj2 的副本。 Nexus 会说“资源,非法请求:ID='releases' 的存储库不允许更新工件。”这很好,我不想错误地更新现有版本。

但我想我想做的是能够告诉 maven 类似“仅部署那些版本尚未出现在发布存储库中的工件”。

有没有办法做到这一点,还是我必须自己部署每个项目?

【问题讨论】:

    标签: maven-2 deployment nexus


    【解决方案1】:

    根据我的经验,部署所有内容更容易,并且通常对所有组件使用相同的版本号。例如,如果我的团队正在开发版本 1.0.7,所有子模块的版本号都是 1.0.7-SNAPSHOT,直到我们发布,即使某些模块中没有代码更改。然后,当我们部署时,我们将部署整个应用程序。我认为与零散部署相比,它有几个优点。首先,如果您每个人都必须回滚到上一个稳定版本,您只需将所有模块回滚到 1.0.6——您不必记住后端是 1.0.3 而 GUI 是 1.0.6。其次,它确保所有组件都相互正确编译,并作为一个逻辑组进行了测试。

    抱歉,我知道这不是对您问题的具体答案,但是,至少在我的团队的情况下,稍微不同的想法很有用

    【讨论】:

    • 感谢您回答约翰,我们也在调查这种方法,它很可能是最终采用的方法。我同意版本一致性带来了很多价值,但我也担心对于大型项目,如果您必须升级整个平台以进行任何更改,构建过程可能会变得过于臃肿和耗时。
    • +1 建议在版本上(正确和正确)使用 SNAPSHOT 限定符来解决此问题。
    • 我不同意最后关于一起编译和测试的说法。如果您对 JAR 有固定版本依赖项,Maven 将使用这些 JAR 编译您的项目,因此您仍然可以将所有内容与 SNAPSHOT 或固定版本依赖项一起编译。至于测试,对于真正的单元测试,我认为应该模拟类依赖,尤其是 JAR 边界上的依赖。这意味着您的代码永远不会一起测试,除非您对已部署的应用程序运行某种功能/集成测试,然后 SNAPSHOT 或固定版本就不再重要了。
    【解决方案2】:

    我建议,如果您计划独立维护、构建和部署模块,您应该考虑为每个模块设置单独的 CI 和 mvn deploy 作业。拥有独立的mvn deploy 工作将为您提供您正在寻找的开箱即用的行为。这意味着不要使用聚合器 pom (parentprj) 来尝试构建和部署这些模块。

    如果您想从聚合器 pom 中执行所有操作,例如构建和部署,那么我建议您遵循 John 的回答并保持所有版本号同步。

    这仅取决于您的团队希望如何看待代码库。如果你想以真正的模块化方式保持东西,你应该像构建块一样使用你的 maven 模块,以不同的方式对待它们,直到你准备好将整个应用程序放在一起。如果您的应用程序本质上更加单一,请按此处理并保持同步。这并不意味着您仍然不能拆分单独的 maven 模块来维护基于代码的模块化,只要认识到它们在您的大型应用程序的上下文之外没有任何价值。

    做出此决定的一个好方法是问自己“任何其他项目/应用程序是否需要将此模块作为依赖项引用?”。如果是这样,最好的做法是独立构建、版本和部署它。如果没有,我认为使版本匹配没有任何缺陷。

    【讨论】:

      【解决方案3】:

      首先,我认为你应该区分父项目和聚合项目。父项目应该用于多个项目共有的设置,例如依赖的版本;应该使用聚合项目以便同时构建一组项目,例如一组罐子和包含它们的战争。

      这两种项目最好分开。父项目通常不会经常更改,当它发生变化时,通常最好发布所有依赖它的项目的新版本;聚合项目的唯一目的是推动一堆项目的构建,因此它的发布号可能会在它包含的一个项目需要发布时更改。

      将父级与聚合器分离后,您可以更好地选择是遵循 John Paulett 的建议并将所有内容保持在相同的版本号,还是仅在您真正需要发布时尝试更改每个项目的版本号它。第一个选项更简单且不易出错,但会导致您发布未更改的新版本库。例如,如果您需要发布补丁而不是完整版本,这可能是不可接受的。第二个选项更复杂且容易出错,但会导致您的版本号与软件的发展相匹配。 Maven 发布插件和 Jenkins 持续集成工具可能会有所帮助,我认为您应该检查一下。另外,看看您是否可以将 Maven 升级到至少 2.2.1 版和 Nexus 到更新的版本。

      【讨论】:

      【解决方案4】:

      显然,maven 没有解决这个需求,Nexus 或档案也没有。 目前,它只能通过构建管理器设置的额外技巧来解决,就像以前的帖子中建议的那样。

      在一个理想的世界里

      • pom 将包括
        .模块的发布版本和快照版本
        .文件的定义,如果更改,则证明使用快照版本是合理的
        .已发布模块的源代码控制管理系统参考

      • 依赖模块 poms 将在适当的依赖部分中添加快照版本信息旁边的发布版本信息,以便它链接到快照库(如果存在于 repo 中),否则链接到发布库

      • maven reactor 可以选择读取依赖层次结构和文件更改信息 (scm diff),以了解给定模块是在其发布版本还是快照版本中使用。

      • 默认情况下,发布插件会跳过模块的发布,但仍然可以根据文件更改和依赖信息与其发布版本一起使用。

      【讨论】:

        【解决方案5】:

        我建议您使用 Artifact Exists Maven 插件 (https://github.com/chonton/exists-maven-plugin)。这个奇妙的事情只需要在 parent.pom 中提及,并且会自动跳过所有发布工件的安装和部署阶段,这些工件已经存在于存储库(Nexus 或 Artifactory)中。并且仍然部署快照(这是可配置的)。

        示例:

          <plugin>
            <groupId>org.honton.chas</groupId>
            <artifactId>exists-maven-plugin</artifactId>
            <version>0.0.6</version>
            <executions>
              <execution>
                <goals>
                  <goal>remote</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
        
        </plugins>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-12-26
          • 1970-01-01
          • 2016-03-12
          • 1970-01-01
          • 2011-06-11
          • 2013-08-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多