2014-05-02 157 views
2

我有一些现有的Maven项目。Maven构建和发布多个相互依赖的项目

它们是:

  1. AAA(插件)
  2. BBB(JAR)
  3. CCC(JAR)
  4. DDD(战争)
  5. EEE(战争)

项目ddd是为客户和eee是另一个

它们位于磁盘上的workspace/文件夹下的扁平结构中,并且在svn repo中有相同的结构。

这是该项目的依赖层次:

ddd (war)   
    aaa (plugin) 
    bbb (jar) 
    ccc (jar) 
     bbb (jar) 

eee (war) 
    ccc (jar) 
     bbb (jar) 

当只有war s为SNAPSHOT那儿的建筑并没有什么问题释放

否则,即

ddd  1.1-SNAPSHOT (war)   
    aaa  2.0   (plugin) 
    bbb  2.1-SNAPSHOT (jar) 
    ccc  1.3-SNAPSHOT (jar) 
    bbb 2.1-SNAPSHOT (jar) 

我必须做的,用于建筑物:

  1. bbb> mvn install
  2. ccc> mvn install
  3. ddd> mvn compile

和用于释放:

  1. bbb> mvn release:prepare release:perform
  2. ccc> mvn versions:use-releases
  3. ccc> svn ci -m "updated SNAPSHOT dependencies"
  4. ccc> mvn release:prepare release:perform
  5. ddd> mvn versions:use-releases
  6. ddd> svn ci -m "updated SNAPSHOT dependencies"
  7. ddd> mvn release:prepare release:perform

我试图与一个聚合,但

  • 上建筑物,它编译非快照依赖(AAA 2.0 - >编译AAA 2 。1 - 拍摄)
  • 上释放,它抱怨SCM,但我不希望聚合是在SVN

这就是我需要:

  • 单个命令建立
    • 订单快照依赖条件
    • 安装(或部署)每个快照依赖性
    • 构建(编译或包或安装...)根artifa CT
  • 单个命令发布
    • 订单快照依赖
    • 释放每个快照依赖
    • 发布根神器

这是我希望:

  • 批构建/发布脚本SVN
  • 放聚合
  • 项目之间共享版
  • 母公司成为一个汇聚太

这可能吗?

其他最佳实践? (也许詹金斯将帮助?)

我应该切换到Gradle?


更新

我看到你们大多数人都混淆聚合,所以我从这个问题,删除它。然而,

[...]您经常会看到父母和聚合器的项目。 [...]然而,虽然聚甲醛项目,聚合项目和父项目都不是相同的,不应该混淆。 POM项目可以继承 - 但不一定有 - 它聚合的任何模块。相反,POM项目可以合并不从其继承的项目。

A final note on Inheritance v. Aggregation

+2

你在'聚合器'下了解什么?您应该考虑真正与多模块构建工作,并根据您的真实结构更改SVN中的结构。版本共享是什么意思? – khmarbaise

+1

@khmarbaise多模块应该使用时,模块将*总是*一起发布,而不是作为一个简单的命令建立一个简单的。根据我的经验,*永远*很少是这种情况 –

+0

@NickHolt我没有说过用它作为捷径。它看起来越来越像一个多模块构建,而操作正试图绕过它。 – khmarbaise

回答

1

刚得到它在一个黑客的方式...但我不是满意。

如果有人会提供一个更好的方法来对maven执行自定义的递归发布过程,我会很乐意改变我的接受程度!

父POM:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>com.mycompany</groupId> 
    <artifactId>test-release-parent</artifactId> 
    <version>1-SNAPSHOT</version> 
    <packaging>pom</packaging> 

    <name>test-release-parent</name> 
    <description>This is the parent pom to test release procedure</description> 
    <inceptionYear>2014</inceptionYear> 

    <properties> 
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
     <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> 
     <svn.repository>http://svn.mycompany.com/repo1</svn.repository> 
     <web.projects>http://www2.mycompany.com/projects</web.projects> 
    </properties> 

    <scm> 
     <developerConnection>scm:svn:${svn.repository}/${project.artifactId}</developerConnection> 
     <url>${svn.repository}/${project.artifactId}</url> 
    </scm> 

    <distributionManagement> 
     <repository> 
      <id>ftp.mycompany.com</id> 
      <name>mycompany Maven Repository</name> 
      <url>ftp://ftp.mycompany.com/maven-repo</url> 
     </repository> 
    </distributionManagement> 

    <repositories> 
     <repository> 
      <id>www2.mycompany.com</id> 
      <name>mycompany Maven Repository</name> 
      <url>http://www2.mycompany.com/maven-repo</url> 
     </repository> 
    </repositories> 

    <pluginRepositories> 
     <pluginRepository> 
      <id>www2.mycompany.com</id> 
      <name>mycompany Maven Repository</name> 
      <url>http://www2.mycompany.com/maven-repo</url> 
     </pluginRepository> 
    </pluginRepositories> 

    <dependencyManagement> 
     <dependencies> 
      <dependency> 
       <groupId>commons-io</groupId> 
       <artifactId>commons-io</artifactId> 
       <version>2.4</version> 
      </dependency> 
      <dependency> 
       <groupId>commons-codec</groupId> 
       <artifactId>commons-codec</artifactId> 
       <version>1.9</version> 
      </dependency> 
     </dependencies> 
    </dependencyManagement> 

    <build> 
     <pluginManagement> 
      <plugins> 
       <plugin> 
        <groupId>org.apache.maven.plugins</groupId> 
        <artifactId>maven-scm-plugin</artifactId> 
        <version>1.9</version> 
       </plugin> 

       <plugin> 
        <groupId>org.codehaus.mojo</groupId> 
        <artifactId>versions-maven-plugin</artifactId> 
        <version>2.1</version> 
        <configuration> 
         <excludes> 
          <exclude>javax:javaee-api:*:*</exclude> 
          <exclude>org.eclipse.persistence:*:*:*</exclude> 
          <exclude>org.hibernate:hibernate-validator:*:*</exclude> 
         </excludes> 
         <rulesUri>http://www.mycompany.com/ruleset.xml</rulesUri> 
        </configuration> 
       </plugin> 

       <plugin> 
        <groupId>org.codehaus.gmaven</groupId> 
        <artifactId>gmaven-plugin</artifactId> 
        <version>1.5</version> 
       </plugin> 
      </plugins> 
     </pluginManagement> 

     <plugins> 
      <plugin> 
       <groupId>org.codehaus.gmaven</groupId> 
       <artifactId>gmaven-plugin</artifactId> 
       <configuration> 
        <source> 
         String releaseVersion = project.version.substring(0, project.version.indexOf("-")); 

         String nextVersion; 
         int index = releaseVersion.lastIndexOf("."); 
         if(index == -1) nextVersion = (releaseVersion.toInteger() + 1) + "-SNAPSHOT"; 
         else 
         { 
          String prefix = releaseVersion.substring(0, index); 
          String suffix = releaseVersion.substring(index + 1); 

          nextVersion = prefix + "." + (suffix.toInteger() + 1) + "-SNAPSHOT"; 
         } 

         ant.exec(failonerror: "true", dir: "${basedir}", executable: "cmd") 
         { 
          arg(value: "/c") 
          arg(value: "mvn") 
          arg(value: "validate") 
          arg(value: "-Prelease-align") 
          arg(value: "-Dversion.release=" + releaseVersion) 
          arg(value: "-Dversion.next=" + nextVersion) 
         } 

         ant.exec(failonerror: "true", dir: "${basedir}", executable: "cmd") 
         { 
          arg(value: "/c") 
          arg(value: "mvn") 
          arg(value: "initialize") 
          arg(value: "-Prelease-prepare") 
          arg(value: "-Dversion.release=" + releaseVersion) 
          arg(value: "-Dversion.next=" + nextVersion) 
         } 

         ant.exec(failonerror: "true", dir: "${basedir}", executable: "cmd") 
         { 
          arg(value: "/c") 
          arg(value: "mvn") 
          arg(value: "deploy") 
          arg(value: "-Prelease-perform") 
          arg(value: "-Dversion.release=" + releaseVersion) 
          arg(value: "-Dversion.next=" + nextVersion) 
         } 
        </source> 
       </configuration> 
      </plugin> 
     </plugins> 

     <extensions> 
      <extension> 
       <groupId>org.apache.maven.wagon</groupId> 
       <artifactId>wagon-ftp</artifactId> 
       <version>2.6</version> 
      </extension> 
     </extensions> 
    </build> 

    <profiles> 
     <profile> 
      <id>buildall</id> 
      <build> 
       <plugins> 
        <plugin> 
         <groupId>org.codehaus.gmaven</groupId> 
         <artifactId>gmaven-plugin</artifactId> 
         <executions> 
          <execution> 
           <phase>validate</phase> 
           <goals> 
            <goal>execute</goal> 
           </goals> 
           <configuration> 
            <source> 
             for(d in project.dependencies) 
             { 
              if(d.groupId == "com.mycompany" &amp;&amp; d.version.endsWith("-SNAPSHOT")) 
              { 
               println "installing " + d 
               ant.exec(failonerror: "true", dir: "${basedir}/../" + d.artifactId, executable: "cmd") 
               { 
                arg(value: "/c") 
                arg(value: "mvn") 
                arg(value: "install") 
                arg(value: "-Pbuildall") 
               } 
              } 
             } 
            </source> 
           </configuration> 
          </execution> 
         </executions> 
        </plugin> 
       </plugins> 
      </build> 
     </profile> 

     <profile> 
      <id>release-align</id> 
      <build> 
       <plugins> 
        <plugin> 
         <groupId>org.codehaus.mojo</groupId> 
         <artifactId>versions-maven-plugin</artifactId> 
         <executions> 
          <execution> 
           <id>initial-updates</id> 
           <phase>validate</phase> 
           <goals> 
            <goal>update-parent</goal> 
            <goal>use-releases</goal> 
            <goal>commit</goal> 
           </goals> 
          </execution> 
         </executions> 
        </plugin> 
       </plugins> 
      </build> 
     </profile> 

     <profile> 
      <id>release-prepare</id> 
      <build> 
       <plugins> 
        <plugin> 
         <groupId>org.codehaus.gmaven</groupId> 
         <artifactId>gmaven-plugin</artifactId> 
         <executions> 
          <execution> 
           <id>release-snapshots</id> 
           <phase>validate</phase> 
           <goals> 
            <goal>execute</goal> 
           </goals> 
           <configuration> 
            <source> 
             if(project.parent != null &amp;&amp; project.parent.groupId == "com.mycompany" &amp;&amp; project.parent.version.endsWith("-SNAPSHOT")) 
             { 
              println "releasing " + project.parent 

              String releaseVersion = project.parent.version.substring(0, project.parent.version.indexOf("-")); 

              String nextVersion; 
              int index = releaseVersion.lastIndexOf("."); 
              if(index == -1) nextVersion = (releaseVersion.toInteger() + 1) + "-SNAPSHOT"; 
              else 
              { 
               String prefix = releaseVersion.substring(0, index); 
               String suffix = releaseVersion.substring(index + 1); 

               nextVersion = prefix + "." + (suffix.toInteger() + 1) + "-SNAPSHOT"; 
              } 

              ant.exec(failonerror: "true", dir: "${basedir}/../" + project.parent.artifactId, executable: "cmd") 
              { 
               arg(value: "/c") 
               arg(value: "mvn") 
               arg(value: "validate") 
               arg(value: "-Prelease-align") 
               arg(value: "-Dversion.release=" + releaseVersion) 
               arg(value: "-Dversion.next=" + nextVersion) 
              } 

              ant.exec(failonerror: "true", dir: "${basedir}/../" + project.parent.artifactId, executable: "cmd") 
              { 
               arg(value: "/c") 
               arg(value: "mvn") 
               arg(value: "initialize") 
               arg(value: "-Prelease-prepare") 
               arg(value: "-Dversion.release=" + releaseVersion) 
               arg(value: "-Dversion.next=" + nextVersion) 
              } 

              ant.exec(failonerror: "true", dir: "${basedir}/../" + project.parent.artifactId, executable: "cmd") 
              { 
               arg(value: "/c") 
               arg(value: "mvn") 
               arg(value: "deploy") 
               arg(value: "-Prelease-perform") 
               arg(value: "-Dversion.release=" + releaseVersion) 
               arg(value: "-Dversion.next=" + nextVersion) 
              } 
             } 

             for(d in project.dependencies) 
             { 
              if(d.groupId == "com.mycompany" &amp;&amp; d.version.endsWith("-SNAPSHOT")) 
              { 
               println "releasing " + d 

               String releaseVersion = d.version.substring(0, d.version.indexOf("-")); 

               String nextVersion; 
               int index = releaseVersion.lastIndexOf("."); 
               if(index == -1) nextVersion = (releaseVersion.toInteger() + 1) + "-SNAPSHOT"; 
               else 
               { 
                String prefix = releaseVersion.substring(0, index); 
                String suffix = releaseVersion.substring(index + 1); 

                nextVersion = prefix + "." + (suffix.toInteger() + 1) + "-SNAPSHOT"; 
               } 

               ant.exec(failonerror: "true", dir: "${basedir}/../" + d.artifactId, executable: "cmd") 
               { 
                arg(value: "/c") 
                arg(value: "mvn") 
                arg(value: "validate") 
                arg(value: "-Prelease-align") 
                arg(value: "-Dversion.release=" + releaseVersion) 
                arg(value: "-Dversion.next=" + nextVersion) 
               } 

               ant.exec(failonerror: "true", dir: "${basedir}/../" + d.artifactId, executable: "cmd") 
               { 
                arg(value: "/c") 
                arg(value: "mvn") 
                arg(value: "initialize") 
                arg(value: "-Prelease-prepare") 
                arg(value: "-Dversion.release=" + releaseVersion) 
                arg(value: "-Dversion.next=" + nextVersion) 
               } 

               ant.exec(failonerror: "true", dir: "${basedir}/../" + d.artifactId, executable: "cmd") 
               { 
                arg(value: "/c") 
                arg(value: "mvn") 
                arg(value: "deploy") 
                arg(value: "-Prelease-perform") 
                arg(value: "-Dversion.release=" + releaseVersion) 
                arg(value: "-Dversion.next=" + nextVersion) 
               } 
              } 
             } 
            </source> 
           </configuration> 
          </execution> 
         </executions> 
        </plugin> 
        <plugin> 
         <groupId>org.codehaus.mojo</groupId> 
         <artifactId>versions-maven-plugin</artifactId> 
         <executions> 
          <execution> 
           <id>final-updates</id> 
           <phase>initialize</phase> 
           <goals> 
            <goal>update-parent</goal> 
            <goal>use-releases</goal> 
            <goal>set</goal> 
            <goal>commit</goal> 
           </goals> 
           <configuration> 
            <newVersion>${version.release}</newVersion> 
           </configuration> 
          </execution> 
         </executions> 
        </plugin> 
       </plugins> 
      </build> 
     </profile> 

     <profile> 
      <id>release-perform</id> 
      <build> 
       <plugins> 
        <plugin> 
         <groupId>org.apache.maven.plugins</groupId> 
         <artifactId>maven-deploy-plugin</artifactId> 
        </plugin> 

        <plugin> 
         <groupId>org.codehaus.mojo</groupId> 
         <artifactId>versions-maven-plugin</artifactId> 
         <executions> 
          <execution> 
           <id>set-next-snapshot</id> 
           <phase>deploy</phase> 
           <goals> 
            <goal>set</goal> 
            <goal>commit</goal> 
           </goals> 
           <configuration> 
            <newVersion>${version.next}</newVersion> 
           </configuration> 
          </execution> 
         </executions> 
        </plugin> 
        <plugin> 
         <groupId>org.apache.maven.plugins</groupId> 
         <artifactId>maven-scm-plugin</artifactId> 
         <executions> 
          <execution> 
           <id>checkin-release</id> 
           <phase>verify</phase> 
           <goals> 
            <goal>checkin</goal> 
            <goal>tag</goal> 
           </goals> 
          </execution> 
          <execution> 
           <id>checkin-snapshot</id> 
           <phase>deploy</phase> 
           <goals> 
            <goal>checkin</goal> 
           </goals> 
          </execution> 
         </executions> 
         <configuration> 
          <tag>${project.version}</tag> 
          <message>auto-generated by release process</message> 
         </configuration> 
        </plugin> 
       </plugins> 
      </build> 
     </profile> 
    </profiles> 
</project> 

,这是一个项目POM使用另一个项目(弄平在工作区的结构)作为依赖性

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <parent> 
     <groupId>com.mycompany</groupId> 
     <artifactId>test-release-parent</artifactId> 
     <version>1-SNAPSHOT</version> 
    </parent> 

    <modelVersion>4.0.0</modelVersion> 
    <artifactId>test-release-project</artifactId> 
    <version>1.0.0-SNAPSHOT</version> 
    <packaging>jar</packaging> 

    <name>${project.artifactId}</name> 
    <description>maven project to test a release process</description> 
    <inceptionYear>2014</inceptionYear> 
    <url>${web.projects}/${project.artifactId}</url> 

    <repositories> 
     <repository> 
      <id>www2.mycompany.com</id> 
      <name>mycompany Maven Repository</name> 
      <url>http://www2.mycompany.com/maven-repo</url> 
     </repository> 
    </repositories> 

    <scm> 
     <developerConnection>scm:svn:${svn.repository}/${project.artifactId}/trunk</developerConnection> 
     <url>${svn.repository}/${project.artifactId}/trunk</url> 
    </scm> 

    <dependencies> 
     <dependency> 
      <groupId>commons-io</groupId> 
      <artifactId>commons-io</artifactId> 
     </dependency> 
     <dependency> 
      <groupId>commons-codec</groupId> 
      <artifactId>commons-codec</artifactId> 
     </dependency> 

     <dependency> 
      <groupId>com.mycompany</groupId> 
      <artifactId>test-release-dependency</artifactId> 
      <version>1.0.0-SNAPSHOT</version> 
     </dependency> 
    </dependencies> 
</project> 

只需运行

mvn <some-phase> -Pbuildall 

到当前项目执行<some-phase>,执行上所有拥有和引用快照(父母和依赖性)

mvn groovy:execute 

执行释放全资和引用的快照

背后的想法:

  • 程序发布:
    1. 更新父版本(如果存在)
    2. 更新快照依赖性是否存在
    3. 如果父拥有和快照
      • 释放(父)
    4. 每个拥有和快照依赖性
      • 释放(依赖性)
    5. 更新父版本(现在必须存在)
    6. 更新owne d和快照依赖(现在必须存在)
    7. 集项目发行版本(即从1.0.0-快照1.0.0)
    8. 提交修改到SCM供应链管理
    9. 标签冻结执行所有的Maven生命周期相直到部署
    10. 项目集下一版本(即从1.0.0到1.0.1-SNAPSHOT)
    11. 提交修改到SCM再次
+0

我已经做了类似的事情,但将它作为一个单独的脚本进行了外化(顺便说一句,它也是常规)。我实际上已经尝试了类似于你所做的一些事情,但发现它非常缓慢和越野车。因为无法并行智能构建或使用持续集成服务器并行构建功能,所以速度较慢。版本插件也很慢。 Buggy,因为版本/发布插件有时会有更新版本的问题正确(你必须分叉,因为pom正在改变)。 –

+0

@AdamGent最后,我用Java编写了我自己的发布工具,它使用命令行maven调用,仅用于* effective-pom * s和* clean deploy *,没有发布/无关的插件。 * versions-maven-plugin *和* maven-release-plugin *所做的所有工作实际上都是由Java代码执行的。但是,当我有空闲时,我会检查gradle并最终迁移我的所有项目。我对maven依赖管理非常满意,但构建/发布生命周期令人非常失望。 –

+0

是的释放插件是...可怕的。我们也计划杀死它。尽管Maven遇到了所有问题,但我仍然更喜欢Gradle。这听起来很愚蠢,如果不是因为Maven是如此声明性的(即XML),我就不能编写一个外部工具来完成所有依赖/发布的东西。我做的一件事,我不知道你是否确实在释放它们之前检查上游依赖关系是否实际发生了变化(这实际上是相当诀窍)。 –

0

您还没有提到,在你的父POM你正在使用的“模块”标签。我建议你应该使用它 - 这样你可以指定项目的构建过程的排队。

要解决您当前的问题,请创建单独的模块/项目。在pom中指定配置文件以触发蚂蚁操作。这应该做的伎俩。

你会呼吁父目录mvn命令如下,即:

mvn clean install -Pdeploy 
+0

是的,我提到(在前面的问题修订中)父母“没有定义任何模块”,我写道我不希望父母也成为一个聚合器。最后说明,使用maven的ant任务来调用递归maven? –

+0

对不起,我一定是错过了我的推理..是的 - 以递归的方式使用maven - 威胁蚂蚁在这种情况下作为独立于平台的批处理程序。 –

+0

是一个很好的解决方案,但是是一种反模式:它包含了pom中的外部参考。如果maven不能处理这种简单的情况,我认为最好切换... –

0

更改根据您的依赖在SVN结构:

在家长,你必须定义模块列表和模块之间的依赖关系必须在适当的模块中定义。

parent (pom.xml) 
+-- aaa (plugin) 
+-- bbb (jar) 
+-- ccc (jar) 
+-- ddd (war) 
+-- eee (war) 

版本应该是以后像3.0快照所有的模块,可以简单的发布/从根位置部署等相同。

如果这不是你应该去的方式,你应该通过詹金斯单独发布所有这些项目。

+0

我不能对齐版本,我不能让父母成为一个聚合器(就像我写的)。所以詹金斯似乎是这样... –

1

您可以切换到摇篮,但它可能是更容易继续使用Maven有一些小的修改:

  • 添加<modules>parent POM在您指定的所有子模块。
  • 将父母版本设置为与您的父母版本相同,例如, 1.0.0-SNAPSHOT
  • 即得到由其他建立包括项目,即bbbccc添加到您的父POM的<dependencyManagement>部分,将其版本是${project.version},并删除在dddeee其具体版本。
  • 同样,将aaa插件添加到父pom的<pluginsManagement>部分,将其版本设置为${project.version},并从其他项目中删除特定版本。

现在,您可以一次构建并释放所有构建,例如,通过使用maven-release-plugin

+0

我很抱歉,但你指出了我写的**我不想在我的问题**。 –

0

现在有可能你的模块粒度太细,但是我个人认为单独构建是构建你系统的方式,这就是为什么。

亲本 pom的主要工作是代表下一个版本。该版本可能是涉及几个内部模块的功能版本,也可能是只有单个模块发生更改的错误修复版本。

鉴于这种循环是这样的:

  1. 修改 POM的版本对应于下一个“版本”。
  2. 更新作为版本的一部分被修改的模块版本。
  3. 更新模块以使用修改后的快照亲本并进行更改。
  4. 将父级中的模块版本更新为其发布版本,并发布父级
  5. 更新每个模块使用发布的 pom并释放模块。

这种方法的好处是,如果未修改模块,则使用以前发布的模块版本(从您的发行版回购中获得,因此不能100%保证),而不进行重建(这将会发生采用多模块方法)减少回归测试开销。

如果每个版本随模块数量变化而变成负担,可能是时候查看您的模块结构了,但是这种方法的好处是,您可以通过系统中的所有模块版本来降低回归测试的努力,并使其易于快速发布。

+0

我不同意“父母的主要工作是代表下一个版本”。你的周期似乎是正确的,但它需要比我更多的手工工作。作为最后一点,我不能回顾我的模块结构,因为有一个共同的基础(罐子和插件),可以在不同的高级项目(不同的客户供应)上重复使用,因此为不同的客户对齐版本是合同自杀 –

1

从条形图的人创造了一个詹金斯插件:“Maven的级联发布插件”

https://github.com/barchart/barchart-jenkins-cascade-plugin/wiki/User-Manual

这需要你创建管理中,其他项目是为了一个单独的“布局”项目发布:

Root layout: 
<project> 
    <modules> 
    <module>a</module> 
    <module>ant</module> 
    <module>fish</module> 
    <module>fish/salmon</module> 
    <module>fish/shark</module> 
</modules> 

该项目仍然需要在颠覆,似乎,但你可以把它放在一个单独的存储库,并与svn:externals例如链接的实际项目。然后Jenkins的插件会发布一个模块,它需要首先发布的模块。

如释放fish/shark -> 1.0,它可能需要释放:

  • 一个 - > 1.1
  • 鱼/鲑鱼 - > 1.2
  • 鱼/鲨鱼 - > 1.0
+0

IMO从理论上讲,这是最好的方法。实际上,我必须进行调查,不过谢谢你指出。 –