This is an automated email from the ASF dual-hosted git repository.
kwin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-release.git
The following commit(s) were added to refs/heads/master by this push:
new 9e0713b8 [MRELEASE-1109] Support CI friendly versions (#198)
9e0713b8 is described below
commit 9e0713b83d99723ebeb3e8347f3f69c69c585ed0
Author: Konrad Windszus <[email protected]>
AuthorDate: Sun Aug 20 16:28:20 2023 +0200
[MRELEASE-1109] Support CI friendly versions (#198)
---
.../release/phase/AbstractRewritePomsPhase.java | 150 ++++++++++++++-------
.../shared/release/transform/jdom2/JDomModel.java | 17 ++-
.../shared/release/transform/jdom2/JDomParent.java | 2 +-
.../phase/RewritePomsForReleasePhaseTest.java | 14 ++
.../release/transform/jdom2/JDomModelTest.java | 9 +-
.../release/transform/jdom2/JDomParentTest.java | 11 +-
.../expected-pom.xml | 39 ++++++
.../pom.xml | 39 ++++++
.../subproject1/expected-pom.xml | 28 ++++
.../subproject1/pom.xml | 28 ++++
10 files changed, 282 insertions(+), 55 deletions(-)
diff --git
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/AbstractRewritePomsPhase.java
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/AbstractRewritePomsPhase.java
index d17865ec..76747c56 100644
---
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/AbstractRewritePomsPhase.java
+++
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/AbstractRewritePomsPhase.java
@@ -23,12 +23,15 @@ import java.net.URI;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.TimeZone;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.ArtifactUtils;
@@ -89,6 +92,18 @@ public abstract class AbstractRewritePomsPhase extends
AbstractReleasePhase impl
*/
private String modelETL = JDomModelETLFactory.NAME;
+ /**
+ * Regular expression pattern matching Maven expressions (i.e. references
to Maven properties).
+ * The first group selects the property name the expression refers to.
+ */
+ private static final Pattern EXPRESSION_PATTERN =
Pattern.compile("\\$\\{(.+)\\}");
+
+ /**
+ * All Maven properties allowed to be referenced in parent versions via
expressions
+ * @see <a
href="https://maven.apache.org/maven-ci-friendly.html">CI-Friendly Versions</a>
+ */
+ private static final List<String> CI_FRIENDLY_PROPERTIES =
Arrays.asList("revision", "sha1", "changelist");
+
private long startTime = -1 * 1000;
protected AbstractRewritePomsPhase(
@@ -266,7 +281,7 @@ public abstract class AbstractRewritePomsPhase extends
AbstractReleasePhase impl
Properties properties = modelTarget.getProperties();
- String parentVersion = rewriteParent(project, modelTarget,
releaseDescriptor, simulate);
+ String parentVersion = rewriteParent(project, modelTarget, result,
releaseDescriptor, simulate);
String projectId = ArtifactUtils.versionlessKey(project.getGroupId(),
project.getArtifactId());
@@ -440,8 +455,29 @@ public abstract class AbstractRewritePomsPhase extends
AbstractReleasePhase impl
modelTarget.setVersion(version);
}
+ /**
+ * Extracts the Maven property name from a given expression.
+ * @param expression the expression
+ * @return either {@code null} if value is no expression otherwise the
property referenced in the expression
+ */
+ public static String extractPropertyFromExpression(String expression) {
+ Matcher matcher = EXPRESSION_PATTERN.matcher(expression);
+ if (!matcher.matches()) {
+ return null;
+ }
+ return matcher.group(1);
+ }
+
+ public static boolean isCiFriendlyVersion(String version) {
+ return
CI_FRIENDLY_PROPERTIES.contains(extractPropertyFromExpression(version));
+ }
+
private String rewriteParent(
- MavenProject project, Model targetModel, ReleaseDescriptor
releaseDescriptor, boolean simulate)
+ MavenProject project,
+ Model targetModel,
+ ReleaseResult result,
+ ReleaseDescriptor releaseDescriptor,
+ boolean simulate)
throws ReleaseFailureException {
String parentVersion = null;
if (project.hasParent()) {
@@ -458,7 +494,13 @@ public abstract class AbstractRewritePomsPhase extends
AbstractReleasePhase impl
throw new ReleaseFailureException("Version for parent '" +
parent.getName() + "' was not mapped");
}
} else {
- targetModel.getParent().setVersion(parentVersion);
+ if
(!isCiFriendlyVersion(targetModel.getParent().getVersion())) {
+ targetModel.getParent().setVersion(parentVersion);
+ } else {
+ logInfo(
+ result,
+ " Ignoring parent version update for CI friendly
expression " + parent.getVersion());
+ }
}
}
return parentVersion;
@@ -521,61 +563,73 @@ public abstract class AbstractRewritePomsPhase extends
AbstractReleasePhase impl
if (rawVersion.equals(originalVersion)) {
logInfo(result, " Updating " + artifactId + " to " +
mappedVersion);
coordinate.setVersion(mappedVersion);
- } else if (rawVersion.matches("\\$\\{.+\\}")) {
- String expression = rawVersion.substring(2,
rawVersion.length() - 1);
-
- if (expression.startsWith("project.")
- || expression.startsWith("pom.")
- || "version".equals(expression)) {
- if
(!mappedVersion.equals(getNextVersion(releaseDescriptor, projectId))) {
- logInfo(result, " Updating " + artifactId + " to
" + mappedVersion);
- coordinate.setVersion(mappedVersion);
- } else {
- logInfo(result, " Ignoring artifact version
update for expression " + rawVersion);
- }
- } else if (properties != null) {
- // version is an expression, check for properties to
update instead
-
- String propertyValue =
properties.getProperty(expression);
-
- if (propertyValue != null) {
- if (propertyValue.equals(originalVersion)) {
- logInfo(result, " Updating " + rawVersion + "
to " + mappedVersion);
- // change the property only if the property is
the same as what's in the reactor
- properties.setProperty(expression,
mappedVersion);
- } else if (mappedVersion.equals(propertyValue)) {
- // this property may have been updated during
processing a sibling.
- logInfo(
- result,
- " Ignoring artifact version update
for expression " + rawVersion
- + " because it is already
updated");
- } else if (!mappedVersion.equals(rawVersion)) {
- // WARNING: ${pom.*} prefix support and
${version} is about to be dropped in mvn4!
- //
https://issues.apache.org/jira/browse/MNG-7404
- //
https://issues.apache.org/jira/browse/MNG-7244
- if (mappedVersion.matches("\\$\\{project.+\\}")
- ||
mappedVersion.matches("\\$\\{pom.+\\}")
- || "${version}".equals(mappedVersion))
{
+ } else {
+ String property =
extractPropertyFromExpression(rawVersion);
+ if (property != null) {
+ if (property.startsWith("project.")
+ || property.startsWith("pom.")
+ || "version".equals(property)) {
+ if
(!mappedVersion.equals(getNextVersion(releaseDescriptor, projectId))) {
+ logInfo(result, " Updating " + artifactId + "
to " + mappedVersion);
+ coordinate.setVersion(mappedVersion);
+ } else {
+ logInfo(result, " Ignoring artifact version
update for expression " + rawVersion);
+ }
+ } else if (properties != null) {
+ // version is an expression, check for properties
to update instead
+ String propertyValue =
properties.getProperty(property);
+ if (propertyValue != null) {
+ if (propertyValue.equals(originalVersion)) {
+ logInfo(result, " Updating " + rawVersion
+ " to " + mappedVersion);
+ // change the property only if the
property is the same as what's in the reactor
+ properties.setProperty(property,
mappedVersion);
+ } else if
(mappedVersion.equals(propertyValue)) {
+ // this property may have been updated
during processing a sibling.
logInfo(
result,
- " Ignoring artifact version
update for expression " + mappedVersion);
- // ignore... we cannot update this
expression
+ " Ignoring artifact version
update for expression " + rawVersion
+ + " because it is already
updated");
+ } else if (!mappedVersion.equals(rawVersion)) {
+ // WARNING: ${pom.*} prefix support and
${version} is about to be dropped in mvn4!
+ //
https://issues.apache.org/jira/browse/MNG-7404
+ //
https://issues.apache.org/jira/browse/MNG-7244
+ if
(mappedVersion.matches("\\$\\{project.+\\}")
+ ||
mappedVersion.matches("\\$\\{pom.+\\}")
+ ||
"${version}".equals(mappedVersion)) {
+ logInfo(
+ result,
+ " Ignoring artifact version
update for expression " + mappedVersion);
+ // ignore... we cannot update this
expression
+ } else {
+ // the value of the expression
conflicts with what the user wanted to release
+ throw new ReleaseFailureException("The
artifact (" + key + ") requires a "
+ + "different version (" +
mappedVersion + ") than what is found ("
+ + propertyValue + ") for the
expression (" + rawVersion + ") in the "
+ + "project (" + projectId +
").");
+ }
+ }
+ } else {
+ if (CI_FRIENDLY_PROPERTIES.contains(property))
{
+ logInfo(
+ result,
+ " Ignoring artifact version
update for CI friendly expression "
+ + rawVersion);
} else {
- // the value of the expression conflicts
with what the user wanted to release
- throw new ReleaseFailureException("The
artifact (" + key + ") requires a "
- + "different version (" +
mappedVersion + ") than what is found ("
- + propertyValue + ") for the
expression (" + expression + ") in the "
- + "project (" + projectId + ").");
+ // the expression used to define the
version of this artifact may be inherited
+ // TODO needs a better error message, what
pom? what dependency?
+ throw new ReleaseFailureException(
+ "Could not find property resolving
version expression: " + rawVersion);
}
}
} else {
// the expression used to define the version of
this artifact may be inherited
// TODO needs a better error message, what pom?
what dependency?
- throw new ReleaseFailureException("The version
could not be updated: " + rawVersion);
+ throw new ReleaseFailureException(
+ "Could not find properties resolving
version expression : " + rawVersion);
}
+ } else {
+ // different/previous version not related to current
release
}
- } else {
- // different/previous version not related to current
release
}
} else if (resolvedSnapshotVersion != null) {
logInfo(result, " Updating " + artifactId + " to " +
resolvedSnapshotVersion);
diff --git
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomModel.java
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomModel.java
index d219b6cd..6198ee73 100644
---
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomModel.java
+++
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomModel.java
@@ -31,6 +31,7 @@ import org.apache.maven.model.Parent;
import org.apache.maven.model.Profile;
import org.apache.maven.model.Reporting;
import org.apache.maven.model.Scm;
+import org.apache.maven.shared.release.phase.AbstractRewritePomsPhase;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.Text;
@@ -178,7 +179,9 @@ public class JDomModel extends Model {
}
if (versionElement == null) {
- if (!version.equals(parentVersion)) {
+ // never add version when parent references CI friendly property
+ if (!(parentVersion != null &&
AbstractRewritePomsPhase.isCiFriendlyVersion(parentVersion))
+ && !version.equals(parentVersion)) {
// we will add this after artifactId, since it was missing but
different from the inherited version
Element artifactIdElement = project.getChild("artifactId",
project.getNamespace());
int index = project.indexOf(artifactIdElement);
@@ -189,7 +192,17 @@ public class JDomModel extends Model {
project.addContent(index + 2, versionElement);
}
} else {
- JDomUtils.rewriteValue(versionElement, version);
+ if
(AbstractRewritePomsPhase.isCiFriendlyVersion(versionElement.getTextNormalize()))
{
+ // try to rewrite property if CI friendly expression is used
+ String ciFriendlyPropertyName =
+
AbstractRewritePomsPhase.extractPropertyFromExpression(versionElement.getTextNormalize());
+ Properties properties = getProperties();
+ if (properties != null) {
+ properties.computeIfPresent(ciFriendlyPropertyName, (k, v)
-> version);
+ }
+ } else {
+ JDomUtils.rewriteValue(versionElement, version);
+ }
}
}
}
diff --git
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomParent.java
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomParent.java
index bbfc1ab7..bfda08fc 100644
---
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomParent.java
+++
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomParent.java
@@ -41,7 +41,7 @@ public class JDomParent extends Parent {
@Override
public String getVersion() {
- throw new UnsupportedOperationException();
+ return parent.getChildText("version", parent.getNamespace());
}
@Override
diff --git
a/maven-release-manager/src/test/java/org/apache/maven/shared/release/phase/RewritePomsForReleasePhaseTest.java
b/maven-release-manager/src/test/java/org/apache/maven/shared/release/phase/RewritePomsForReleasePhaseTest.java
index 138f4bfc..71515aed 100644
---
a/maven-release-manager/src/test/java/org/apache/maven/shared/release/phase/RewritePomsForReleasePhaseTest.java
+++
b/maven-release-manager/src/test/java/org/apache/maven/shared/release/phase/RewritePomsForReleasePhaseTest.java
@@ -320,6 +320,20 @@ public class RewritePomsForReleasePhaseTest extends
AbstractEditModeRewritingRel
assertTrue(comparePomFiles(reactorProjects));
}
+ // MRELEASE-1109
+ @Test
+ public void testRewritePomWithCiFriendlyReactor() throws Exception {
+ List<MavenProject> reactorProjects =
createReactorProjects("pom-with-parent-and-cifriendly-expressions");
+
+ ReleaseDescriptorBuilder builder =
+ createDescriptorFromProjects(reactorProjects,
"pom-with-parent-and-cifriendly-expressions");
+ builder.addReleaseVersion("groupId:artifactId", NEXT_VERSION);
+ builder.addReleaseVersion("groupId:subproject1", NEXT_VERSION);
+ phase.execute(ReleaseUtils.buildReleaseDescriptor(builder), new
DefaultReleaseEnvironment(), reactorProjects);
+
+ assertTrue(comparePomFiles(reactorProjects));
+ }
+
// MRELEASE-311
@Test
public void testRewritePomWithDependencyPropertyCoordinate() throws
Exception {
diff --git
a/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomModelTest.java
b/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomModelTest.java
index 43dec7e0..ebd0ec28 100644
---
a/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomModelTest.java
+++
b/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomModelTest.java
@@ -68,7 +68,14 @@ public class JDomModelTest {
model.setVersion(null);
assertNull(model.getVersion());
- // inherit from parent
+ // inherit from parent via CI friendly
+ content =
"<project><parent><version>${revision}</version></parent></project>";
+ projectElm = builder.build(new StringReader(content)).getRootElement();
+ model = new JDomModel(projectElm);
+ assertNull(model.getVersion());
+ model.setVersion("PARENT_VERSION");
+ assertNull(getVersion(projectElm));
+
// this business logic might need to moved.
content =
"<project><parent><version>PARENT_VERSION</version></parent></project>";
projectElm = builder.build(new StringReader(content)).getRootElement();
diff --git
a/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomParentTest.java
b/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomParentTest.java
index 5f2c88ee..036811ef 100644
---
a/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomParentTest.java
+++
b/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomParentTest.java
@@ -18,9 +18,11 @@
*/
package org.apache.maven.shared.release.transform.jdom2;
+import java.io.IOException;
import java.io.StringReader;
import org.jdom2.Element;
+import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.junit.Test;
@@ -44,9 +46,12 @@ public class JDomParentTest {
new JDomParent(null).getRelativePath();
}
- @Test(expected = UnsupportedOperationException.class)
- public void testGetVersion() {
- new JDomParent(null).getVersion();
+ @Test
+ public void testGetVersion() throws JDOMException, IOException {
+ String content = "<parent><version>1.0</version></parent>";
+ Element parentElm = builder.build(new
StringReader(content)).getRootElement();
+
+ assertEquals("1.0", new JDomParent(parentElm).getVersion());
}
@Test(expected = UnsupportedOperationException.class)
diff --git
a/maven-release-manager/src/test/resources/projects/rewrite-for-release/pom-with-parent-and-cifriendly-expressions/expected-pom.xml
b/maven-release-manager/src/test/resources/projects/rewrite-for-release/pom-with-parent-and-cifriendly-expressions/expected-pom.xml
new file mode 100644
index 00000000..c7504063
--- /dev/null
+++
b/maven-release-manager/src/test/resources/projects/rewrite-for-release/pom-with-parent-and-cifriendly-expressions/expected-pom.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ ~ Copyright 2005-2006 The Apache Software Foundation.
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>groupId</groupId>
+ <artifactId>artifactId</artifactId>
+ <version>${revision}</version>
+ <packaging>pom</packaging>
+
+ <scm>
+
<connection>scm:svn:file://localhost/tmp/scm-repo/tags/release-label</connection>
+
<developerConnection>scm:svn:file://localhost/tmp/scm-repo/tags/release-label</developerConnection>
+ <url>file://localhost/tmp/scm-repo/tags/release-label</url>
+ </scm>
+
+ <properties>
+ <revision>1.0-SNAPSHOT</revision>
+ </properties>
+
+ <modules>
+ <module>subproject1</module>
+ </modules>
+</project>
diff --git
a/maven-release-manager/src/test/resources/projects/rewrite-for-release/pom-with-parent-and-cifriendly-expressions/pom.xml
b/maven-release-manager/src/test/resources/projects/rewrite-for-release/pom-with-parent-and-cifriendly-expressions/pom.xml
new file mode 100644
index 00000000..0c9bd8b2
--- /dev/null
+++
b/maven-release-manager/src/test/resources/projects/rewrite-for-release/pom-with-parent-and-cifriendly-expressions/pom.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ ~ Copyright 2005-2006 The Apache Software Foundation.
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>groupId</groupId>
+ <artifactId>artifactId</artifactId>
+ <version>${revision}</version>
+ <packaging>pom</packaging>
+
+ <scm>
+ <connection>scm:svn:file://localhost/tmp/scm-repo/trunk</connection>
+
<developerConnection>scm:svn:file://localhost/tmp/scm-repo/trunk</developerConnection>
+ <url>file://localhost/tmp/scm-repo/trunk</url>
+ </scm>
+
+ <properties>
+ <revision>1.0-SNAPSHOT</revision>
+ </properties>
+
+ <modules>
+ <module>subproject1</module>
+ </modules>
+</project>
diff --git
a/maven-release-manager/src/test/resources/projects/rewrite-for-release/pom-with-parent-and-cifriendly-expressions/subproject1/expected-pom.xml
b/maven-release-manager/src/test/resources/projects/rewrite-for-release/pom-with-parent-and-cifriendly-expressions/subproject1/expected-pom.xml
new file mode 100644
index 00000000..7b2fa88c
--- /dev/null
+++
b/maven-release-manager/src/test/resources/projects/rewrite-for-release/pom-with-parent-and-cifriendly-expressions/subproject1/expected-pom.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ ~ Copyright 2005-2006 The Apache Software Foundation.
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>groupId</groupId>
+ <artifactId>artifactId</artifactId>
+ <version>${revision}</version>
+ </parent>
+
+ <artifactId>subproject1</artifactId>
+</project>
diff --git
a/maven-release-manager/src/test/resources/projects/rewrite-for-release/pom-with-parent-and-cifriendly-expressions/subproject1/pom.xml
b/maven-release-manager/src/test/resources/projects/rewrite-for-release/pom-with-parent-and-cifriendly-expressions/subproject1/pom.xml
new file mode 100644
index 00000000..7b2fa88c
--- /dev/null
+++
b/maven-release-manager/src/test/resources/projects/rewrite-for-release/pom-with-parent-and-cifriendly-expressions/subproject1/pom.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ ~ Copyright 2005-2006 The Apache Software Foundation.
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>groupId</groupId>
+ <artifactId>artifactId</artifactId>
+ <version>${revision}</version>
+ </parent>
+
+ <artifactId>subproject1</artifactId>
+</project>