我有一些现有的 Maven 项目。
它们是:
- aaa(插件)
- bbb( jar )
- ccc( jar )
- ddd( war )
- eee( war )
项目 ddd
是给一个客户的,eee
是给另一个客户的
它们位于磁盘上 workspace/
文件夹下的平面结构中,并且在 svn repo 中有完全相同的结构。
这是项目的依赖层次结构:
ddd (war)
aaa (plugin)
bbb (jar)
ccc (jar)
bbb (jar)
eee (war)
ccc (jar)
bbb (jar)
只有war
是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)
我必须做的,为了 build :
bbb> mvn install
ccc> mvn install
ddd> mvn compile
并发布:
bbb> mvn release:prepare release:perform
ccc> mvn versions:use-releases
ccc> svn ci -m “更新的 SNAPSHOT 依赖项”
ccc> mvn release:prepare release:perform
ddd> mvn versions:use-releases
ddd> svn ci -m "更新的 SNAPSHOT 依赖项"
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 吗??
更新
我看到你们中的大多数人将 parent 与 aggregator 混淆了,所以我从这个问题中删除了它。然而,
[...] 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.
最佳答案
只是以一种 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" && 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 && project.parent.groupId == "com.mycompany" && 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" && 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
执行所有拥有和引用快照的发布
背后的想法:
- 程序发布:
- 如果存在则更新父版本
- 如果存在则更新快照依赖
- 如果父级拥有并且快照
- 发布( parent )
- 对于每个拥有的和快照的依赖
- 发布(依赖)
- 更新父版本(现在必须存在)
- 更新拥有的和快照依赖项(现在必须存在)
- 设置项目发布版本(即从 1.0.0-SNAPSHOT 到 1.0.0)
- 提交对 scm 的更改
- scm 上的标签卡住
- 执行所有 Maven 生命周期阶段直到部署
- 设置项目的下一个版本(即从 1.0.0 到 1.0.1-SNAPSHOT)
- 再次提交对 scm 的更改
关于java - Maven 构建和发布多个相互依赖的项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23425860/