我有一些现有的Maven项目。
他们是:
项目ddd
适用于客户,eee
适用于其他
它们位于磁盘上workspace/
文件夹下的扁平结构中,并且svn repo中的结构完全相同。
这是项目的依赖层次结构:
ddd (war)
aaa (plugin)
bbb (jar)
ccc (jar)
bbb (jar)
eee (war)
ccc (jar)
bbb (jar)
当只有war
s SNAPSHOT
s时,构建和发布没有问题
否则,即
ddd 1.1-SNAPSHOT (war)
aaa 2.0 (plugin)
bbb 2.1-SNAPSHOT (jar)
ccc 1.3-SNAPSHOT (jar)
bbb 2.1-SNAPSHOT (jar)
我必须这样做,以建立:
bbb> mvn install
ccc> mvn install
ddd> mvn compile
和发布:
bbb> mvn release:prepare release:perform
ccc> mvn versions:use-releases
ccc> svn ci -m "updated SNAPSHOT dependencies"
ccc> mvn release:prepare release:perform
ddd> mvn versions:use-releases
ddd> svn ci -m "updated SNAPSHOT dependencies"
ddd> mvn release:prepare release:perform
我尝试使用聚合器,但
这就是我需要的:
这是我不想要的:
这可能吗?
替代最佳做法? (也许詹金斯会帮忙?)
更新
我发现大多数人将父与聚合器混淆,所以我将其从此问题中删除了。然而,
[...]您经常会看到父项和聚合器都是项目。 [...]然而,尽管POM项目,聚合器项目和父项目都不是同一个项目,但不应混淆。 POM项目可以从 - 但不一定 - 继承 - 它聚合的任何模块。相反,POM项目可能会聚合不从中继承的项目。
答案 0 :(得分:1)
您可以切换到Gradle,但通过一些小修改可能更容易继续使用Maven:
<modules>
pom中添加parent
。1.0.0-SNAPSHOT
。bbb
和ccc
)添加到父pom的<dependencyManagement>
部分,将其版本设置为${project.version}
,并在ddd
和eee
。aaa
插件添加到父pom的<pluginsManagement>
部分,将其版本设置为${project.version}
,然后从其他项目中删除特定版本。现在,您可以一次性构建和发布所有构建版本,例如使用maven-release-plugin。
答案 1 :(得分:1)
来自barchart的人创建了一个Jenkins插件:“Maven Cascade Release Plugin”
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>
这个项目似乎仍然需要在Subversion中,但您可以将它放在一个单独的存储库中,并将实际项目与svn:externals
链接起来。然后Jenkins的插件将发布一个模块,它需要首先释放哪些模块。
要发布fish/shark -> 1.0
,可能需要发布:
答案 2 :(得分:1)
只是以一种愚蠢的方式得到它...但我不满意。
如果有人会提供更好的方法在maven上执行自定义递归发布过程,我会很高兴改变我的接受度!
父母:
<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
执行发布所有拥有和引用的快照
背后的想法:
答案 3 :(得分:0)
你还没有提到你父POM中你正在使用&#34; modules&#34;标签。我建议你应该使用它 - 这样你就可以为项目的构建过程指定一行。
要解决当前问题,请创建单独的模块/项目。在pom中指定配置文件以触发ant操作。这应该可以解决问题。
您可以在父目录上调用mvn命令,如下所示:
mvn clean install -Pdeploy
答案 4 :(得分:0)
根据您的依赖关系更改SVN中的结构:
在父级中,您必须定义模块列表,并且必须在相应的模块中定义模块之间的依赖关系。
parent (pom.xml)
+-- aaa (plugin)
+-- bbb (jar)
+-- ccc (jar)
+-- ddd (war)
+-- eee (war)
对于所有模块(例如3.0-SNAPSHOT)的版本应该相同,之后您可以从根位置简单地发布/部署等。
如果这不是你要去的方式,你应该通过Jenkins分别发布所有这些项目。
答案 5 :(得分:0)
现在你的模块可能太精细了,但我个人认为单独的构建是构建系统的方法,这就是原因。
父 pom的主要工作是代表下一个版本。该版本可能是一个涉及多个内部模块的功能版本,也可能是一个错误修复版本,其中只有一个模块发生更改。
鉴于此,周期如下:
这种方法的好处在于,在未修改模块的情况下,您使用之前发布的模块版本(从您的发布回购中获取,因此不是100%保证)而不进行重建(这可能发生在多个模块上) - 模块方法)减少回归测试开销。
如果随每个版本更改的模块数量成为负担,可能是时候审查您的模块结构,但是这种方法的好处是 parent pom对齐您的所有模块版本系统允许减少回归测试工作并使快速小型发布变得容易。