java - Maven 构建和发布多个相互依赖的项目

标签 java maven release

我有一些现有的 Maven 项目。

它们是:

  1. aaa(插件)
  2. bbb( jar )
  3. ccc( jar )
  4. ddd( war )
  5. eee( war )

项目 ddd 是给一个客户的,eee 是给另一个客户的

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

这是项目的依赖层次结构:

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

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

只有warSNAPSHOT时,构建和发布都没有问题

否则,即

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

我必须做的,为了 build :

  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 “更新的 SNAPSHOT 依赖项”
  4. ccc> mvn release:prepare release:perform
  5. ddd> mvn versions:use-releases
  6. ddd> svn ci -m "更新的 SNAPSHOT 依赖项"
  7. ddd> mvn release:prepare release:perform

我尝试使用聚合器,但是

  • 在构建时,它编译非 SNAPSHOT 依赖项(aaa 2.0 -> 编译 aaa 2.1-SNAPSHOT)
  • 发布时,它提示 scm,但我不希望聚合器在 svn 中

这是我需要的:

  • 单命令构建
    • 订购 SNAPSHOT 依赖项
    • 安装(或部署)每个 SNAPSHOT 依赖项
    • 构建(编译或打包或安装...)根 Artifact
  • 单一命令发布
    • 订购 SNAPSHOT 依赖项
    • 释放每个 SNAPSHOT 依赖项
    • 发布根 Artifact

这是我想要的:

  • 批量构建/发布脚本
  • 将聚合器放在 svn 中
  • 项目间的版本共享
  • parent 也成为聚合者

这可能吗?

替代最佳实践? (也许 Jenkins 会有所帮助?)

我应该切换到 Gradle 吗??


更新

我看到你们中的大多数人将 parentaggregator 混淆了,所以我从这个问题中删除了它。然而,

[...] You will often see projects that are both parents and aggregators. [...] However, although both POM projects, an aggregator project and a parent project are not one in the same and should not be confused. A POM project may be inherited from - but does not necessarily have - any modules that it aggregates. Conversely, a POM project may aggregate projects that do not inherit from it.

来自 A final note on Inheritance v. Aggregation

最佳答案

只是以一种 hacky 的方式得到它...但我满意。

如果有人能提供更好的方法来在 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>在当前项目和install在所有拥有和引用的快照上(父级和依赖项)

mvn groovy:execute

执行所有拥有和引用快照的发布

背后的想法:

  • 程序发布:
    1. 如果存在则更新父版本
    2. 如果存在则更新快照依赖
    3. 如果父级拥有并且快照
      • 发布( parent )
    4. 对于每个拥有的和快照的依赖
      • 发布(依赖)
    5. 更新父版本(现在必须存在)
    6. 更新拥有的和快照依赖项(现在必须存在)
    7. 设置项目发布版本(即从 1.0.0-SNAPSHOT 到 1.0.0)
    8. 提交对 scm 的更改
    9. scm 上的标签卡住
    10. 执行所有 Maven 生命周期阶段直到部署
    11. 设置项目的下一个版本(即从 1.0.0 到 1.0.1-SNAPSHOT)
    12. 再次提交对 scm 的更改

关于java - Maven 构建和发布多个相互依赖的项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23425860/

相关文章:

java - 确定给定的时间戳是否在 postgresql 中的同一天

java - java并发中的alien方法难懂

objective-c - 在 getter 方法中保留和自动释放

scala - Maven SBT 依赖 Artifact ?

maven - 如何自定义Maven发布插件的标签格式?

android - 如何在不签名的情况下创建 apk 版本

java - XMLMultiPageEditor部分文档

java - FatWire ContentServer 和网络服务

java - Maven 继承不适用于pluginManagement

hibernate - 非法参数异常 : Not an entity - distributed model definitions in hibernate/jpa and Maven