diff --git a/maven-release-api/pom.xml b/maven-release-api/pom.xml index 76f248212..543900c35 100644 --- a/maven-release-api/pom.xml +++ b/maven-release-api/pom.xml @@ -52,6 +52,10 @@ org.apache.maven maven-settings + + org.apache.maven.scm + maven-scm-api + org.eclipse.aether aether-api diff --git a/maven-release-api/src/main/java/org/apache/maven/shared/release/config/ReleaseDescriptor.java b/maven-release-api/src/main/java/org/apache/maven/shared/release/config/ReleaseDescriptor.java index 6ca7c0f01..26a078d80 100644 --- a/maven-release-api/src/main/java/org/apache/maven/shared/release/config/ReleaseDescriptor.java +++ b/maven-release-api/src/main/java/org/apache/maven/shared/release/config/ReleaseDescriptor.java @@ -426,6 +426,13 @@ public interface ReleaseDescriptor */ String getProjectVersionPolicyId(); + /** + * Get the (optional) config for the VersionPolicy implementation used to calculate the project versions. + * + * @return The parsed XML of the provided config (an instance of XmlPlexusConfiguration) or null. + */ + Object getProjectVersionPolicyConfig(); + /** * Get the role-hint for the release Strategy implementation. * diff --git a/maven-release-api/src/main/java/org/apache/maven/shared/release/policy/version/VersionPolicyRequest.java b/maven-release-api/src/main/java/org/apache/maven/shared/release/policy/version/VersionPolicyRequest.java index 4001b8714..9c771089f 100644 --- a/maven-release-api/src/main/java/org/apache/maven/shared/release/policy/version/VersionPolicyRequest.java +++ b/maven-release-api/src/main/java/org/apache/maven/shared/release/policy/version/VersionPolicyRequest.java @@ -20,6 +20,8 @@ */ import org.apache.maven.artifact.repository.metadata.Metadata; +import org.apache.maven.scm.provider.ScmProvider; +import org.apache.maven.scm.repository.ScmRepository; /** *

VersionPolicyRequest class.

@@ -33,6 +35,12 @@ public class VersionPolicyRequest private Metadata metaData; + private ScmRepository scmRepository; + private ScmProvider scmProvider; + private String workingDirectory; + + private String config; + /** *

Getter for the field version.

* @@ -76,5 +84,93 @@ public VersionPolicyRequest setMetaData( Metadata metaData ) this.metaData = metaData; return this; } - + + /** + *

Getter for the field scmRepository.

+ * + * @return a {@link ScmRepository} object + */ + public ScmRepository getScmRepository() + { + return scmRepository; + } + + /** + *

Setter for the field scmRepository.

+ * + * @param scmRepository The {@link ScmRepository} where the history can be retrieved. + * @return a {@link org.apache.maven.shared.release.policy.version.VersionPolicyRequest} object + */ + public VersionPolicyRequest setScmRepository( ScmRepository scmRepository ) + { + this.scmRepository = scmRepository; + return this; + } + + /** + *

Getter for the field scmProvider.

+ * + * @return a {@link ScmProvider} object + */ + public ScmProvider getScmProvider() + { + return scmProvider; + } + + /** + *

Setter for the field scmProvider.

+ * + * @param scmProvider The {@link ScmProvider} where the history can be retrieved. + * @return a {@link org.apache.maven.shared.release.policy.version.VersionPolicyRequest} object + */ + public VersionPolicyRequest setScmProvider( ScmProvider scmProvider ) + { + this.scmProvider = scmProvider; + return this; + } + + /** + *

Getter for the field workingDirectory.

+ * + * @return the {@link String} that contains the workingDirectory (can be null or empty). + */ + public String getWorkingDirectory() + { + return workingDirectory; + } + + /** + *

Setter for the field workingDirectory.

+ * + * @param workingDirectory The {@link String} that contains the workingDirectory (can be null or empty). + * @return a {@link org.apache.maven.shared.release.policy.version.VersionPolicyRequest} object + */ + public VersionPolicyRequest setWorkingDirectory( String workingDirectory ) + { + this.workingDirectory = workingDirectory; + return this; + } + + /** + *

Getter for the field config.

+ * + * @return the {@link String} that contains the config (can be null or empty). + */ + public String getConfig() + { + return config; + } + + /** + *

Setter for the field config.

+ * + * @param config The {@link String} that contains the config (can be null or empty). + * @return a {@link org.apache.maven.shared.release.policy.version.VersionPolicyRequest} object + */ + public VersionPolicyRequest setConfig( String config ) + { + this.config = config; + return this; + } + } diff --git a/maven-release-api/src/main/java/org/apache/maven/shared/release/versions/VersionParseException.java b/maven-release-api/src/main/java/org/apache/maven/shared/release/versions/VersionParseException.java index 8d24cb112..010c8c4b3 100644 --- a/maven-release-api/src/main/java/org/apache/maven/shared/release/versions/VersionParseException.java +++ b/maven-release-api/src/main/java/org/apache/maven/shared/release/versions/VersionParseException.java @@ -34,4 +34,14 @@ public VersionParseException( String message ) { super( message ); } + + /** + *

Constructor for VersionParseException.

+ * + * @param message a {@link java.lang.String} object + */ + public VersionParseException( String message, Exception e ) + { + super( message, e ); + } } diff --git a/maven-release-manager/pom.xml b/maven-release-manager/pom.xml index 98345bc11..7488a60dc 100644 --- a/maven-release-manager/pom.xml +++ b/maven-release-manager/pom.xml @@ -191,7 +191,6 @@ org.eclipse.sisu org.eclipse.sisu.plexus - test diff --git a/maven-release-manager/src/main/java/org/apache/maven/shared/release/config/PropertiesReleaseDescriptorStore.java b/maven-release-manager/src/main/java/org/apache/maven/shared/release/config/PropertiesReleaseDescriptorStore.java index fdacb6d2d..9d3246c00 100644 --- a/maven-release-manager/src/main/java/org/apache/maven/shared/release/config/PropertiesReleaseDescriptorStore.java +++ b/maven-release-manager/src/main/java/org/apache/maven/shared/release/config/PropertiesReleaseDescriptorStore.java @@ -269,6 +269,10 @@ public void write( BuilderReleaseDescriptor config, File file ) { properties.setProperty( "projectVersionPolicyId", config.getProjectVersionPolicyId() ); } + if ( config.getProjectVersionPolicyConfig() != null ) + { + properties.setProperty( "projectVersionPolicyConfig", config.getProjectVersionPolicyConfig().toString() ); + } if ( config.getProjectNamingPolicyId() != null ) { properties.setProperty( "projectNamingPolicyId", config.getProjectNamingPolicyId() ); diff --git a/maven-release-manager/src/main/java/org/apache/maven/shared/release/config/ReleaseDescriptorBuilder.java b/maven-release-manager/src/main/java/org/apache/maven/shared/release/config/ReleaseDescriptorBuilder.java index 6940d31da..5b81f7032 100644 --- a/maven-release-manager/src/main/java/org/apache/maven/shared/release/config/ReleaseDescriptorBuilder.java +++ b/maven-release-manager/src/main/java/org/apache/maven/shared/release/config/ReleaseDescriptorBuilder.java @@ -401,6 +401,18 @@ public ReleaseDescriptorBuilder setProjectVersionPolicyId( String projectVersion return this; } + /** + *

setProjectVersionPolicyConfig.

+ * + * @param setProjectVersionPolicyConfig a {@link java.lang.String} object + * @return a {@link org.apache.maven.shared.release.config.ReleaseDescriptorBuilder} object + */ + public ReleaseDescriptorBuilder setProjectVersionPolicyConfig( String setProjectVersionPolicyConfig ) + { + releaseDescriptor.setProjectVersionPolicyConfig( setProjectVersionPolicyConfig ); + return this; + } + /** *

setPushChanges.

* diff --git a/maven-release-manager/src/main/java/org/apache/maven/shared/release/config/ReleaseUtils.java b/maven-release-manager/src/main/java/org/apache/maven/shared/release/config/ReleaseUtils.java index 3847b52d0..2d24e35c2 100644 --- a/maven-release-manager/src/main/java/org/apache/maven/shared/release/config/ReleaseUtils.java +++ b/maven-release-manager/src/main/java/org/apache/maven/shared/release/config/ReleaseUtils.java @@ -156,6 +156,10 @@ public static void copyPropertiesToReleaseDescriptor( Properties properties, Rel { builder.setProjectVersionPolicyId( properties.getProperty( "projectVersionPolicyId" ) ); } + if ( properties.containsKey( "projectVersionPolicyConfig" ) ) + { + builder.setProjectVersionPolicyConfig( properties.getProperty( "projectVersionPolicyConfig" ) ); + } if ( properties.containsKey( "projectNamingPolicyId" ) ) { builder.setProjectNamingPolicyId( properties.getProperty( "projectNamingPolicyId" ) ); diff --git a/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/AbstractMapVersionsPhase.java b/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/AbstractMapVersionsPhase.java index 97617f35a..6f7b4d2ad 100644 --- a/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/AbstractMapVersionsPhase.java +++ b/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/AbstractMapVersionsPhase.java @@ -24,6 +24,11 @@ import org.apache.maven.artifact.ArtifactUtils; import org.apache.maven.project.MavenProject; +import org.apache.maven.scm.manager.NoSuchScmProviderException; +import org.apache.maven.scm.provider.ScmProvider; +import org.apache.maven.scm.repository.ScmRepository; +import org.apache.maven.scm.repository.ScmRepositoryException; +import org.apache.maven.settings.Settings; import org.apache.maven.shared.release.ReleaseExecutionException; import org.apache.maven.shared.release.ReleaseResult; import org.apache.maven.shared.release.config.ReleaseDescriptor; @@ -31,8 +36,11 @@ import org.apache.maven.shared.release.policy.PolicyException; import org.apache.maven.shared.release.policy.version.VersionPolicy; import org.apache.maven.shared.release.policy.version.VersionPolicyRequest; +import org.apache.maven.shared.release.scm.ScmRepositoryConfigurator; import org.apache.maven.shared.release.util.ReleaseUtil; import org.apache.maven.shared.release.versions.VersionParseException; +import org.codehaus.plexus.component.annotations.Component; +import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.components.interactivity.Prompter; import org.codehaus.plexus.components.interactivity.PrompterException; import org.codehaus.plexus.util.StringUtils; @@ -67,9 +75,16 @@ * @author Brett Porter * @author Robert Scholte */ +@Component( role = ReleasePhase.class, hint = "map-release-versions" ) public abstract class AbstractMapVersionsPhase extends AbstractReleasePhase { + /** + * Tool that gets a configured SCM repository from release configuration. + */ + @Requirement + private ScmRepositoryConfigurator scmRepositoryConfigurator; + /** * Component used to prompt for input. */ @@ -275,14 +290,14 @@ else if ( releaseDescriptor.isBranchCreation() ) { suggestedVersion = resolveSuggestedVersion( baseVersion, - releaseDescriptor.getProjectVersionPolicyId() ); + releaseDescriptor ); } catch ( VersionParseException e ) { if ( releaseDescriptor.isInteractive() ) { suggestedVersion = - resolveSuggestedVersion( "1.0", releaseDescriptor.getProjectVersionPolicyId() ); + resolveSuggestedVersion( "1.0", releaseDescriptor ); } else { @@ -347,9 +362,10 @@ private String getContextString( ReleaseDescriptor releaseDescriptor ) return "new development"; } - private String resolveSuggestedVersion( String baseVersion, String policyId ) + private String resolveSuggestedVersion( String baseVersion, ReleaseDescriptor releaseDescriptor ) throws PolicyException, VersionParseException { + String policyId = releaseDescriptor.getProjectVersionPolicyId(); VersionPolicy policy = versionPolicies.get( policyId ); if ( policy == null ) { @@ -357,6 +373,31 @@ private String resolveSuggestedVersion( String baseVersion, String policyId ) } VersionPolicyRequest request = new VersionPolicyRequest().setVersion( baseVersion ); + + if ( releaseDescriptor.getProjectVersionPolicyConfig() != null ) + { + request.setConfig( releaseDescriptor.getProjectVersionPolicyConfig().toString() ); + } + request.setWorkingDirectory( releaseDescriptor.getWorkingDirectory() ); + + if ( scmRepositoryConfigurator != null && releaseDescriptor.getScmSourceUrl() != null ) + { + try + { + ScmRepository repository = scmRepositoryConfigurator + .getConfiguredRepository( releaseDescriptor, new Settings() ); + + ScmProvider provider = scmRepositoryConfigurator + .getRepositoryProvider( repository ); + + request.setScmRepository( repository ); + request.setScmProvider( provider ); + } + catch ( ScmRepositoryException | NoSuchScmProviderException e ) + { + getLogger().warn( "Next Version will NOT be based on the version control: {}", e.getMessage() ); + } + } return convertToSnapshot ? policy.getDevelopmentVersion( request ).getVersion() : policy.getReleaseVersion( request ).getVersion(); } diff --git a/maven-release-manager/src/main/mdo/release-descriptor.mdo b/maven-release-manager/src/main/mdo/release-descriptor.mdo index 0a1d8cd55..a752ff695 100644 --- a/maven-release-manager/src/main/mdo/release-descriptor.mdo +++ b/maven-release-manager/src/main/mdo/release-descriptor.mdo @@ -488,6 +488,15 @@ The role-hint for the VersionPolicy implementation used to calculate the project versions. + + projectVersionPolicyConfig + 3.0.0+ + DOM + + The optional config string for the VersionPolicy implementation used to calculate the project versions. + The format of this depends on the specific VersionPolicy that is used. + + projectNamingPolicyId 3.0.0+ diff --git a/maven-release-manager/src/test/java/org/apache/maven/shared/release/config/PropertiesReleaseDescriptorStoreTest.java b/maven-release-manager/src/test/java/org/apache/maven/shared/release/config/PropertiesReleaseDescriptorStoreTest.java index 27e03d982..a45861c72 100644 --- a/maven-release-manager/src/test/java/org/apache/maven/shared/release/config/PropertiesReleaseDescriptorStoreTest.java +++ b/maven-release-manager/src/test/java/org/apache/maven/shared/release/config/PropertiesReleaseDescriptorStoreTest.java @@ -367,6 +367,9 @@ private ReleaseDescriptorBuilder createReleaseConfigurationForWriting() builder.addReleaseVersion( "groupId:artifactId", "1.0" ); builder.addDevelopmentVersion( "groupId:artifactId", "1.1-SNAPSHOT" ); + // The actual kind of string you will get when setting the projectVersionPolicyConfig + builder.setProjectVersionPolicyConfig("bar"); + IdentifiedScm scm = new IdentifiedScm(); scm.setId( "id-write" ); scm.setConnection( "connection-write" ); diff --git a/maven-release-plugin/pom.xml b/maven-release-plugin/pom.xml index aa20fa24f..74e0a7239 100644 --- a/maven-release-plugin/pom.xml +++ b/maven-release-plugin/pom.xml @@ -95,6 +95,12 @@ ${project.version} true
+ + org.apache.maven.release + maven-release-ccsemver-policy + ${project.version} + true + junit diff --git a/maven-release-plugin/src/it/projects/prepare/ccsemver-policy/pom.xml b/maven-release-plugin/src/it/projects/prepare/ccsemver-policy/pom.xml new file mode 100644 index 000000000..5c809f1eb --- /dev/null +++ b/maven-release-plugin/src/it/projects/prepare/ccsemver-policy/pom.xml @@ -0,0 +1,83 @@ + + + + 4.0.0 + org.apache.maven.plugin.release.it + ccsemver-policy + 1.0-SNAPSHOT + + scm:dummytags|nul + scm:dummytags|nul + + + + + org.apache.maven.plugins + maven-release-plugin + @project.version@ + + true + true + false + false + + ci(Release): + ci(Release): Version @{releaseLabel} + v@{project.version} + + CCSemVerVersionPolicy + + + + + + + + + + + ^v([0-9]+(?:\.[0-9]+(?:\.[0-9]+)?)?)$ + + ^[a-zA-Z]+!(?:\([a-zA-Z0-9_-]+\))?: .*$ + ^BREAKING CHANGE:.*$ + + + ^feat(?:\([a-zA-Z0-9_-]+\))?: .*$ + + + + + + + org.apache.maven.its.release + maven-scm-provider-dummy + 1.0 + + + org.apache.maven.release + maven-release-ccsemver-policy + @project.version@ + + + + + + diff --git a/maven-release-plugin/src/it/projects/prepare/ccsemver-policy/verify.groovy b/maven-release-plugin/src/it/projects/prepare/ccsemver-policy/verify.groovy new file mode 100644 index 000000000..476b00fec --- /dev/null +++ b/maven-release-plugin/src/it/projects/prepare/ccsemver-policy/verify.groovy @@ -0,0 +1,39 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +File buildLog = new File( basedir, 'build.log' ) +assert buildLog.exists() +assert 1 == buildLog.getText().count("[INFO] From SCM tag with version 1.2.3 doing a MINOR version increase based on commit messages to version 1.3.0") +assert 1 == buildLog.getText().count("[INFO] Full run would be commit 1 files with message: 'ci(Release): Version v1.3.0'") + +// The pom based version is NOT related to what the actual version will be. +File pomXml = new File( basedir, 'pom.xml' ) +assert pomXml.exists() +assert new XmlSlurper().parse( pomXml ).version.text() == "1.0-SNAPSHOT" + +// The actual version is based upon the tags and commit messages. +File pomXmlTag = new File( basedir, 'pom.xml.tag' ) +assert pomXmlTag.exists() +assert new XmlSlurper().parse( pomXmlTag ).version.text() == "1.3.0" + +// The next development version should be standard +File pomXmlNext = new File( basedir, 'pom.xml.next' ) +assert pomXmlNext.exists() +assert new XmlSlurper().parse( pomXmlNext ).version.text() == "1.3.1-SNAPSHOT" diff --git a/maven-release-plugin/src/it/setup/maven-scm-provider-dummy/src/main/java/org/apache/maven/scm/provider/dummy/DummyTagsScmProvider.java b/maven-release-plugin/src/it/setup/maven-scm-provider-dummy/src/main/java/org/apache/maven/scm/provider/dummy/DummyTagsScmProvider.java new file mode 100644 index 000000000..dfa218106 --- /dev/null +++ b/maven-release-plugin/src/it/setup/maven-scm-provider-dummy/src/main/java/org/apache/maven/scm/provider/dummy/DummyTagsScmProvider.java @@ -0,0 +1,115 @@ +package org.apache.maven.scm.provider.dummy; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import javax.inject.Named; +import javax.inject.Singleton; + +import org.apache.maven.scm.ChangeSet; +import org.apache.maven.scm.CommandParameters; +import org.apache.maven.scm.ScmFileSet; +import org.apache.maven.scm.ScmResult; +import org.apache.maven.scm.command.changelog.ChangeLogScmRequest; +import org.apache.maven.scm.command.changelog.ChangeLogScmResult; +import org.apache.maven.scm.command.changelog.ChangeLogSet; +import org.apache.maven.scm.command.status.StatusScmResult; +import org.apache.maven.scm.provider.AbstractScmProvider; +import org.apache.maven.scm.provider.ScmProviderRepository; + +import java.util.Arrays; +import java.util.Date; + +/** + * A dummy SCM provider used to provide commit messages and tags for testing the Conventional Commits Version Policy. + * + * @plexus.component role="org.apache.maven.scm.provider.ScmProvider" role-hint="dummytags" + * @author Niels Basjes + */ +@Singleton +@Named( "dummytags" ) +public class DummyTagsScmProvider + extends AbstractScmProvider +{ + + public String getScmType() + { + return "dummytags"; + } + + public ScmProviderRepository makeProviderScmRepository( String scmSpecificUrl, char delimiter ) + { + return new DummyScmProviderRepository(); + } + + @Override + protected StatusScmResult status( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters ) + { + return new StatusScmResult( "", "", "", true ); + } + + private ChangeSet changeSet(String comment, String... tags) + { + ChangeSet changeSet = new ChangeSet(); + changeSet.setComment( comment ); + changeSet.setAuthor( "Someone " ); + changeSet.setTags( Arrays.asList( tags ) ); + return changeSet; + } + + @Override + public ChangeLogScmResult changeLog(ChangeLogScmRequest request) + { + Date from = new Date( 39817800000L ); + Date to = new Date( 1644768534785L ); + ChangeLogSet changeLogSet = new ChangeLogSet( + Arrays.asList( + changeSet( "Commit 19" ), + changeSet( "Commit 18" ), + changeSet( "Commit 17" ), + changeSet( "Commit 16" ), + changeSet( "Commit 15", "tag 1", "tag 2" ), + changeSet( "feat(it): This is a new feature." ), // For Conventional Commits. + changeSet( "Commit 13" ), + changeSet( "Commit 12", "tag 3" ), + changeSet( "Commit 11" ), + changeSet( "Commit 10" ), + changeSet( "Commit 9" ), + changeSet( "Commit 8" ), + changeSet( "Commit 7" ), + changeSet( "Commit 6", "tag 4" ), + changeSet( "Commit 5" ), + changeSet( "Commit 4" ), + changeSet( "Commit 3" ), + changeSet( "Commit 2", "v1.2.3" ), // For Conventional Commits. + changeSet( "Commit 1" ), + changeSet( "Commit 0" ) + ), from, to + ); + + ScmResult scmResult = new ScmResult( + "No command", + "Special for CCSemVer testing", + "No command output", + true + ); + return new ChangeLogScmResult( changeLogSet, scmResult ); + } + +} diff --git a/maven-release-plugin/src/main/java/org/apache/maven/plugins/release/BranchReleaseMojo.java b/maven-release-plugin/src/main/java/org/apache/maven/plugins/release/BranchReleaseMojo.java index 7e67b80eb..cca4bcbf8 100644 --- a/maven-release-plugin/src/main/java/org/apache/maven/plugins/release/BranchReleaseMojo.java +++ b/maven-release-plugin/src/main/java/org/apache/maven/plugins/release/BranchReleaseMojo.java @@ -30,6 +30,7 @@ import org.apache.maven.shared.release.ReleaseExecutionException; import org.apache.maven.shared.release.ReleaseFailureException; import org.apache.maven.shared.release.config.ReleaseDescriptorBuilder; +import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration; /** * Branch a project in SCM, using the same steps as the release:prepare goal, creating a branch instead of @@ -200,6 +201,14 @@ public class BranchReleaseMojo @Parameter( defaultValue = "default", property = "projectVersionPolicyId" ) private String projectVersionPolicyId; + /** + * Optional config for the VersionPolicy implementation used to calculate the project versions. + * + * @since 3.0.0-M7 + */ + @Parameter( property = "projectVersionPolicyConfig" ) + private XmlPlexusConfiguration projectVersionPolicyConfig; + /** * The role-hint for the {@link org.apache.maven.shared.release.policy.naming.NamingPolicy} * implementation used to calculate the project names. @@ -260,6 +269,10 @@ public void execute() config.setDefaultDevelopmentVersion( developmentVersion ); config.setSuppressCommitBeforeTagOrBranch( suppressCommitBeforeBranch ); config.setProjectVersionPolicyId( projectVersionPolicyId ); + if ( projectVersionPolicyConfig != null ) + { + config.setProjectVersionPolicyConfig( projectVersionPolicyConfig.toString() ); + } config.setProjectNamingPolicyId( projectBranchNamingPolicyId ); config.setScmBranchCommitComment( scmBranchCommitComment ); config.setPinExternals( pinExternals ); diff --git a/maven-release-plugin/src/main/java/org/apache/maven/plugins/release/PrepareReleaseMojo.java b/maven-release-plugin/src/main/java/org/apache/maven/plugins/release/PrepareReleaseMojo.java index a7bc0f126..b00282631 100644 --- a/maven-release-plugin/src/main/java/org/apache/maven/plugins/release/PrepareReleaseMojo.java +++ b/maven-release-plugin/src/main/java/org/apache/maven/plugins/release/PrepareReleaseMojo.java @@ -34,6 +34,7 @@ import org.apache.maven.shared.release.ReleaseFailureException; import org.apache.maven.shared.release.ReleasePrepareRequest; import org.apache.maven.shared.release.config.ReleaseDescriptorBuilder; +import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration; /** * Prepare for a release in SCM. Steps through several phases to ensure the POM is ready to be released and then @@ -240,6 +241,14 @@ public class PrepareReleaseMojo @Parameter( defaultValue = "default", property = "projectVersionPolicyId" ) private String projectVersionPolicyId; + /** + * Optional config for the VersionPolicy implementation used to calculate the project versions. + * + * @since 3.0.0-M7 + */ + @Parameter( property = "projectVersionPolicyConfig" ) + private XmlPlexusConfiguration projectVersionPolicyConfig; + /** * The role-hint for the {@link org.apache.maven.shared.release.policy.naming.NamingPolicy} * implementation used to calculate the project branch and tag names. @@ -382,6 +391,10 @@ protected void prepareRelease( boolean generateReleasePoms ) config.setSuppressCommitBeforeTagOrBranch( suppressCommitBeforeTag ); config.setWaitBeforeTagging( waitBeforeTagging ); config.setProjectVersionPolicyId( projectVersionPolicyId ); + if ( projectVersionPolicyConfig != null ) + { + config.setProjectVersionPolicyConfig( projectVersionPolicyConfig.toString() ); + } config.setProjectNamingPolicyId( projectTagNamingPolicyId ); config.setScmDevelopmentCommitComment( scmDevelopmentCommitComment ); config.setScmReleaseCommitComment( scmReleaseCommitComment ); diff --git a/maven-release-plugin/src/main/java/org/apache/maven/plugins/release/UpdateVersionsMojo.java b/maven-release-plugin/src/main/java/org/apache/maven/plugins/release/UpdateVersionsMojo.java index 60f657dfd..c72590040 100644 --- a/maven-release-plugin/src/main/java/org/apache/maven/plugins/release/UpdateVersionsMojo.java +++ b/maven-release-plugin/src/main/java/org/apache/maven/plugins/release/UpdateVersionsMojo.java @@ -29,6 +29,7 @@ import org.apache.maven.shared.release.ReleaseFailureException; import org.apache.maven.shared.release.ReleaseUpdateVersionsRequest; import org.apache.maven.shared.release.config.ReleaseDescriptorBuilder; +import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration; /** * Update the POM versions for a project. This performs the normal version updates of the release:prepare @@ -93,6 +94,14 @@ public class UpdateVersionsMojo @Parameter( defaultValue = "default", property = "projectVersionPolicyId" ) private String projectVersionPolicyId; + /** + * Optional config for the VersionPolicy implementation used to calculate the project versions. + * + * @since 3.0.0-M7 + */ + @Parameter( property = "projectVersionPolicyConfig" ) + private XmlPlexusConfiguration projectVersionPolicyConfig; + @Override public void execute() throws MojoExecutionException, MojoFailureException @@ -104,7 +113,10 @@ public void execute() config.setScmUseEditMode( useEditMode ); config.setUpdateDependencies( updateDependencies ); config.setProjectVersionPolicyId( projectVersionPolicyId ); - + if ( projectVersionPolicyConfig != null ) + { + config.setProjectVersionPolicyConfig( projectVersionPolicyConfig.toString() ); + } config.addOriginalScmInfo( ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() ), project.getScm() ); diff --git a/maven-release-plugin/src/site/apt/usage.apt.vm b/maven-release-plugin/src/site/apt/usage.apt.vm index 8353bc6ce..0068e9847 100644 --- a/maven-release-plugin/src/site/apt/usage.apt.vm +++ b/maven-release-plugin/src/site/apt/usage.apt.vm @@ -5,6 +5,7 @@ Brett Porter John Tolentino Robert Scholte + Niels Basjes ------ 2011-11-10 ------ @@ -151,3 +152,131 @@ mvn -Dusername=your_scm_username release:prepare ... +------------------- + +* Automatically calculating the released version + + The Release Plugin automatically calculates the version that is released and the next development version + (i.e. the next SNAPSHOT). If nothing is configured this is done by the default VersionPolicy which compares + and increments versions for a common java versioning scheme. + + It is possible to select a different VersionPolicy by specifying its id. + ++------------------- + + ... + + + + org.apache.maven.plugins + maven-release-plugin + ${project.version} + + CCSemVerVersionPolicy + + + + ... + + ... + ++------------------- + + There are 4 VersionPolicies bundled with the Release Plugin: + + * default: \ + This compares and increments versions for a common java versioning scheme. + + * OddEvenVersionPolicy: \ + A version policy that proposes even version numbers only for releases and odd numbers for development. + + * SemVerVersionPolicy: \ + A version policy that enforce SemVer format and upgrades minor element for next development version. + + * CCSemVerVersionPolicy (since 3.0.0-M7): \ + A version policy that enforces the SemVer format and uses Conventional Commits to determine the next version. + +* CCSemVerVersionPolicy + + The CCSemVerVersionPolicy is different in the sense that it goes beyond the project version specified in the pom.xml + and tries to analyze the SCM history and from the tags and commit messages it calculates the next version. + For this a few additional configuration options are available. + + The calculation works as follows: + + * It tries to find the previously released version by searching for the previous release tag. + Here the configured <<>> regex is used to locate and extract (the regex MUST have exactly + 1 capture group) the correct value. + If no matching tags are found the project version from the pom.xml is used as the fallback reference point. + + * By default it assumes that only a patch release (i.e. <<>> ) is needed. + + * If any of the commit messages since the previous release tag match any of the of <<>> regexes then + it assumes the next release is a minor release (i.e. <<>> ). + + * If any of the commit messages since the previous release tag match any of the of <<>> regexes then + it assumes the next release is a major release (i.e. <<<+1.0.0>>> ). + + The next development version is always calculated as the release version and then <<>>. + + When doing <<>> the details about the found tags, commit messages and the used patterns + are output to the console. + + The default configuration assumes a version tag that is just the version (i.e. something like <<<1.2.3>>>) and + the rules from the {{{https://www.conventionalcommits.org/en/v1.0.0/}Conventional Commits v1.0.0}} are followed. + + If you want a different tag format this will usually result in setting it both when creating the tag and + for finding it again: + ++------------------- + + v@{project.version} + CCSemVerVersionPolicy + + ^v([0-9]+\.[0-9]+\.[0-9]+)$ + + ++------------------- + + If either the minor or major rules are specified then all default rules (both minor and major) are dropped + in favour of the configuration. + ++-------+ + + ... + + + + org.apache.maven.plugins + maven-release-plugin + ${project.version} + + v@{project.version} + + CCSemVerVersionPolicy + + + + + + + + + + + ^v([0-9]+\.[0-9]+\.[0-9]+)$ + + ^[a-zA-Z]+!(?:\([a-zA-Z0-9_-]+\))?: .*$ + ^BREAKING CHANGE:.*$ + + + ^feat(?:\([a-zA-Z0-9_-]+\))?: .*$ + + + + + + ... + + ... + ++-------+ diff --git a/maven-release-policies/maven-release-ccsemver-policy/pom.xml b/maven-release-policies/maven-release-ccsemver-policy/pom.xml new file mode 100644 index 000000000..29b4831c5 --- /dev/null +++ b/maven-release-policies/maven-release-ccsemver-policy/pom.xml @@ -0,0 +1,120 @@ + + + + + 4.0.0 + + + org.apache.maven.release + maven-release + 3.0.0-M7-SNAPSHOT + ../../pom.xml + + + maven-release-ccsemver-policy + + Maven Release Conventional Commits SemVer Policy + + A version policy that enforces the SemVer format and uses Conventional Commits to determine the next version. + + + + + + ${project.parent.groupId} + maven-release-api + ${project.parent.version} + + + + org.semver + api + 0.9.33 + + + + org.apache.maven.scm + maven-scm-api + ${scmVersion} + + + + org.slf4j + slf4j-api + + + + javax.inject + javax.inject + provided + + + + org.eclipse.sisu + org.eclipse.sisu.inject + provided + + + + org.codehaus.plexus + plexus-component-annotations + true + + + + junit + junit + test + + + + org.slf4j + slf4j-simple + test + + + + + + + + org.codehaus.modello + modello-maven-plugin + + + + xpp3-reader + java + + + + + 3.0.0 + false + + src/main/mdo/ccsemver-config.mdo + + + + + + + + \ No newline at end of file diff --git a/maven-release-policies/maven-release-ccsemver-policy/src/main/java/org/apache/maven/shared/release/policy/ccsemver/CCSemVerVersionPolicy.java b/maven-release-policies/maven-release-ccsemver-policy/src/main/java/org/apache/maven/shared/release/policy/ccsemver/CCSemVerVersionPolicy.java new file mode 100644 index 000000000..60f1722c4 --- /dev/null +++ b/maven-release-policies/maven-release-ccsemver-policy/src/main/java/org/apache/maven/shared/release/policy/ccsemver/CCSemVerVersionPolicy.java @@ -0,0 +1,175 @@ +package org.apache.maven.shared.release.policy.ccsemver; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import javax.inject.Named; +import javax.inject.Singleton; + +import org.apache.maven.scm.ScmException; +import org.apache.maven.shared.release.policy.version.VersionPolicy; +import org.apache.maven.shared.release.policy.version.VersionPolicyRequest; +import org.apache.maven.shared.release.policy.version.VersionPolicyResult; +import org.apache.maven.shared.release.versions.VersionParseException; +import org.eclipse.sisu.Description; +import org.semver.Version; +import org.semver.Version.Element; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +/** + * Uses SemVer combined with the tags and commit messages to increase the version. + */ +@Singleton +@Named( "CCSemVerVersionPolicy" ) +@Description( "A VersionPolicy following the SemVer rules and looks at " + + "the commit messages following the Conventional Commits convention." ) +public class CCSemVerVersionPolicy implements VersionPolicy +{ + protected Logger logger = LoggerFactory.getLogger( CCSemVerVersionPolicy.class ); + + public VersionPolicyResult getReleaseVersion( VersionPolicyRequest request ) + throws VersionParseException + { + VersionRules versionRules = new VersionRules( request.getConfig() ); + try + { + return getReleaseVersion( + request, + versionRules, + new CommitHistory( request, versionRules ) ); + } + catch ( ScmException e ) + { + throw new VersionParseException( "Unable to obtain the information from the SCM history", e ); + } + } + + public VersionPolicyResult getReleaseVersion( VersionPolicyRequest request, + VersionRules versionRules, + CommitHistory commitHistory ) + throws VersionParseException + { + boolean usingTag = false; + + String versionString = request.getVersion(); // The current version in the pom + Version version; + + logger.debug( "--------------------------------------------------------" ); + logger.debug( "Determining next ReleaseVersion" ); + logger.debug( "VersionRules: \n{}", versionRules ); + logger.debug( "Pom version : {}", versionString ); + + logger.debug( "Commit History : \n{}", commitHistory ); + + Element maxElementSinceLastVersionTag = versionRules.getMaxElementSinceLastVersionTag( commitHistory ); + + List commitHistoryTags = commitHistory.getTags(); + if ( commitHistoryTags.size() == 1 ) + { + // Use the latest tag we have + versionString = commitHistoryTags.get( 0 ); + usingTag = true; + logger.debug( "Version from tags : {}", versionString ); + } + else + { + logger.debug( "Version from tags : NOT FOUND" ); + } + + if ( maxElementSinceLastVersionTag == null ) + { + logger.debug( "Step from commits : No SCM version tags found" ); + } + else + { + logger.debug( "Step from commits : {}", maxElementSinceLastVersionTag.name() ); + } + + try + { + version = Version.parse( versionString ); + } + catch ( IllegalArgumentException e ) + { + throw new VersionParseException( e.getMessage() ); + } + + logger.debug( "Current version : {}", version ); + + + // If we have a version from the tag we use that + the calculated update. + // If only have the version from the current pom version with -SNAPSHOT removed. + if ( maxElementSinceLastVersionTag != null ) + { + version = version.next( maxElementSinceLastVersionTag ); + } + + Version releaseVersion = version.toReleaseVersion(); + logger.debug( "Next version : {}", releaseVersion ); + logger.debug( "--------------------------------------------------------" ); + + if ( usingTag ) + { + logger.info( "From SCM tag with version {} " + + "doing a {} version increase based on commit messages to version {}", + versionString, maxElementSinceLastVersionTag, releaseVersion ); + } + else + { + if ( maxElementSinceLastVersionTag == null ) + { + logger.info( "From project.version {} (because we did not find any valid SCM tags) " + + "going to version {} (because we did not find any minor/major commit messages).", + versionString, releaseVersion ); + } + else + { + logger.info( "From project.version {} (because we did not find any valid SCM tags) " + + "doing a {} version increase based on commit messages to version {}", + versionString, maxElementSinceLastVersionTag, releaseVersion ); + } + } + + VersionPolicyResult result = new VersionPolicyResult(); + result.setVersion( releaseVersion.toString() ); + return result; + } + + public VersionPolicyResult getDevelopmentVersion( VersionPolicyRequest request ) + throws VersionParseException + { + Version version; + try + { + version = Version.parse( request.getVersion() ); + } + catch ( IllegalArgumentException e ) + { + throw new VersionParseException( e.getMessage() ); + } + + version = version.next( Element.PATCH ); + VersionPolicyResult result = new VersionPolicyResult(); + result.setVersion( version + "-SNAPSHOT" ); + return result; + } +} diff --git a/maven-release-policies/maven-release-ccsemver-policy/src/main/java/org/apache/maven/shared/release/policy/ccsemver/CommitHistory.java b/maven-release-policies/maven-release-ccsemver-policy/src/main/java/org/apache/maven/shared/release/policy/ccsemver/CommitHistory.java new file mode 100644 index 000000000..4ae661f93 --- /dev/null +++ b/maven-release-policies/maven-release-ccsemver-policy/src/main/java/org/apache/maven/shared/release/policy/ccsemver/CommitHistory.java @@ -0,0 +1,187 @@ +package org.apache.maven.shared.release.policy.ccsemver; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import org.apache.maven.scm.ChangeSet; +import org.apache.maven.scm.ScmException; +import org.apache.maven.scm.ScmFileSet; +import org.apache.maven.scm.command.changelog.ChangeLogScmRequest; +import org.apache.maven.scm.command.changelog.ChangeLogScmResult; +import org.apache.maven.scm.provider.ScmProvider; +import org.apache.maven.scm.repository.ScmRepository; +import org.apache.maven.shared.release.policy.version.VersionPolicyRequest; +import org.apache.maven.shared.release.versions.VersionParseException; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.stream.Collectors; + +/** + * Helper class to manage the commit history of the SCM repository. + */ +public class CommitHistory +{ + private final List changes = new ArrayList<>(); + private final List tags = new ArrayList<>(); + private String string; + + public List getChanges() + { + return changes; + } + + public void addChanges( String change ) + { + this.changes.add( change ); + } + + public void addChanges( List changes ) + { + this.changes.addAll( changes ); + } + + public List getTags() + { + return tags; + } + + public void addTags( List tags ) + { + if ( tags != null ) + { + tags.forEach( this::addTags ); + } + } + + public void addTags( String tag ) + { + if ( tag != null && !tag.isEmpty() ) + { + this.tags.add( tag ); + } + } + + public String getLastVersionTag() + { + if ( tags.size() != 1 ) + { + return null; + } + return tags.get( 0 ); + } + + public CommitHistory() + { + // Default constructor which results in an empty history. + } + + public CommitHistory( VersionPolicyRequest request, VersionRules versionRules ) + throws ScmException, VersionParseException + { + ScmRepository scmRepository = request.getScmRepository(); + ScmProvider scmProvider = request.getScmProvider(); + String workingDirectory = request.getWorkingDirectory(); + + if ( scmRepository == null || scmProvider == null || workingDirectory == null ) + { + // We do not have a commit history so the changes and tags will remain empty + return; + } + + ChangeLogScmRequest changeLogRequest = new ChangeLogScmRequest( + scmRepository, + new ScmFileSet( new File( workingDirectory ) ) + ); + + List logLines = new ArrayList<>(); + + int limit = 0; + while ( getTags().isEmpty() ) + { + limit += 100; // Read the repository in incremental steps of 100 + changeLogRequest.setLimit( null ); + changeLogRequest.setLimit( limit ); + changes.clear(); + + ChangeLogScmResult changeLog = scmProvider.changeLog( changeLogRequest ); + + logLines.clear(); + logLines.add( "Commit history:" ); + for ( ChangeSet changeSet : changeLog.getChangeLog().getChangeSets() ) + { + List changeSetTags = changeSet.getTags(); + logLines.add( "-- Comment: \"" + changeSet.getComment() + "\"" ); + logLines.add( " Tags : " + changeSetTags ); + List versionTags = changeSetTags + .stream() + .map( tag -> + { + Matcher matcher = versionRules.getTagPattern().matcher( tag ); + if ( matcher.find() ) + { + return matcher.group( 1 ); + } + return null; + } + ) + .filter( Objects::nonNull ) + .collect( Collectors.toList() ); + + if ( !versionTags.isEmpty() ) + { + // Found the previous release tag + if ( versionTags.size() > 1 ) + { + throw new VersionParseException( "Most recent commit with tags has multiple version tags: " + + versionTags ); + } + logLines.add( "-- Version tags: " + versionTags ); + addTags( versionTags ); + break; // We have the last version tag + } + else + { + addChanges( changeSet.getComment() ); + } + } + if ( changeLog.getChangeLog().getChangeSets().size() < limit ) + { + // Apparently there are simply no more commits. + break; + } + } + + StringBuilder sb = new StringBuilder(); + for ( String logLine: logLines ) + { + sb.append( logLine ).append( '\n' ); + } + string = sb.toString(); + } + + @Override + public String toString() + { + return string; + } +} diff --git a/maven-release-policies/maven-release-ccsemver-policy/src/main/java/org/apache/maven/shared/release/policy/ccsemver/VersionRules.java b/maven-release-policies/maven-release-ccsemver-policy/src/main/java/org/apache/maven/shared/release/policy/ccsemver/VersionRules.java new file mode 100644 index 000000000..0c005a581 --- /dev/null +++ b/maven-release-policies/maven-release-ccsemver-policy/src/main/java/org/apache/maven/shared/release/policy/ccsemver/VersionRules.java @@ -0,0 +1,175 @@ +package org.apache.maven.shared.release.policy.ccsemver; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import org.apache.maven.shared.release.policy.ccsemver.config.ProjectVersionPolicyConfig; +import org.apache.maven.shared.release.policy.ccsemver.config.io.xpp3.CCSemverVersionPolicyConfigXpp3Reader; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.semver.Version; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static java.nio.charset.StandardCharsets.UTF_8; + +/** + * The set of rules that determine from the commit history what the next version should be. + */ +public class VersionRules +{ + private static final Logger LOGGER = LoggerFactory.getLogger( VersionRules.class ); + + private final Pattern tagPattern; + + private final List majorUpdatePatterns = new ArrayList<>(); + private final List minorUpdatePatterns = new ArrayList<>(); + + public VersionRules( String config ) + { + int patternFlags = Pattern.MULTILINE | Pattern.DOTALL | Pattern.UNIX_LINES; + + // The default assumes then entire tag is what we need + String tagRegex = "^(\\d+\\.\\d+\\.\\d+)$"; + + // https://www.conventionalcommits.org/en/v1.0.0/ + majorUpdatePatterns.add( Pattern.compile( "^[a-zA-Z]+!(?:\\([a-zA-Z\\d_-]+\\))?: .*$", patternFlags ) ); + majorUpdatePatterns.add( Pattern.compile( "^BREAKING CHANGE:.*$", patternFlags ) ); + minorUpdatePatterns.add( Pattern.compile( "^feat(?:\\([a-zA-Z\\d_-]+\\))?: .*$", patternFlags ) ); + + if ( config != null && !config.trim().isEmpty() ) + { + ByteArrayInputStream inputStream = new ByteArrayInputStream( config.getBytes( UTF_8 ) ); + CCSemverVersionPolicyConfigXpp3Reader configReader = new CCSemverVersionPolicyConfigXpp3Reader(); + try + { + ProjectVersionPolicyConfig semverConfig = configReader.read( inputStream ); + + String semverConfigVersionTag = semverConfig.getVersionTag(); + if ( semverConfigVersionTag != null && !semverConfigVersionTag.trim().isEmpty() ) + { + tagRegex = semverConfigVersionTag; + } + + if ( !semverConfig.getMajorRules().isEmpty() || !semverConfig.getMinorRules().isEmpty() ) + { + majorUpdatePatterns.clear(); + for ( String majorRule : semverConfig.getMajorRules() ) + { + majorUpdatePatterns.add( Pattern.compile( majorRule, patternFlags ) ); + } + minorUpdatePatterns.clear(); + for ( String minorRule : semverConfig.getMinorRules() ) + { + minorUpdatePatterns.add( Pattern.compile( minorRule, patternFlags ) ); + } + } + } + catch ( IOException | XmlPullParserException e ) + { + throw new IllegalArgumentException( "Unable to load the CCSemverVersionPolicyConfig: ", e ); + } + } + tagPattern = Pattern.compile( tagRegex, Pattern.MULTILINE ); + } + + public Version.Element getMaxElementSinceLastVersionTag( CommitHistory commitHistory ) + { + boolean needMinorUpdate = false; + for ( String change : commitHistory.getChanges() ) + { + if ( isMajorUpdate( change ) ) + { + LOGGER.debug( "MAJOR: \"{}\"", change ); + return Version.Element.MAJOR; + } + else + if ( isMinorUpdate( change ) ) + { + LOGGER.debug( "MINOR: \"{}\"", change ); + needMinorUpdate = true; + } + } + + if ( needMinorUpdate ) + { + return Version.Element.MINOR; + } + if ( commitHistory.getLastVersionTag() != null ) + { + LOGGER.debug( "PATCH: Tag {}", commitHistory.getLastVersionTag() ); + return Version.Element.PATCH; + } + return null; + } + + public boolean isMajorUpdate( String input ) + { + return matchesAny( majorUpdatePatterns, input ); + } + + public boolean isMinorUpdate( String input ) + { + return matchesAny( minorUpdatePatterns, input ); + } + + private boolean matchesAny( List patterns, String input ) + { + for ( Pattern pattern : patterns ) + { + Matcher matcher = pattern.matcher( input ); + if ( matcher.find() ) + { + return true; + } + } + return false; + } + + public Pattern getTagPattern() + { + return tagPattern; + } + + @Override + public String toString() + { + StringBuilder result = new StringBuilder(); + result.append( "Conventional Commits config:\n" ); + result.append( " VersionTag:\n" ); + result.append( " >>>" ).append( tagPattern ).append( "<<<\n" ); + result.append( " MajorRules:\n" ); + for ( Pattern majorUpdatePattern : majorUpdatePatterns ) + { + result.append( " >>>" ).append( majorUpdatePattern ).append( "<<<\n" ); + } + result.append( " Minor Rules:\n" ); + for ( Pattern minorUpdatePattern : minorUpdatePatterns ) + { + result.append( " >>>" ).append( minorUpdatePattern ).append( "<<<\n" ); + } + return result.toString(); + } +} diff --git a/maven-release-policies/maven-release-ccsemver-policy/src/main/mdo/ccsemver-config.mdo b/maven-release-policies/maven-release-ccsemver-policy/src/main/mdo/ccsemver-config.mdo new file mode 100644 index 000000000..578604b80 --- /dev/null +++ b/maven-release-policies/maven-release-ccsemver-policy/src/main/mdo/ccsemver-config.mdo @@ -0,0 +1,77 @@ + + + + + ccsemver-config + CCSemverVersionPolicyConfig + + The config for the CCSemverVersionPolicy. + + + + package + org.apache.maven.shared.release.policy.ccsemver.config + + + + + + ProjectVersionPolicyConfig + 1.0.0+ + + + + versionTag + 1.1.0+ + String + + The regex with exactly 1 capture group that extracts the version from the SCM tag. + + + + minorRules + 1.1.0+ + List + + String + * + + + The list of regexes that must be classified as "minor" version changes. + + + + majorRules + 1.1.0+ + List + + String + * + + + The list of regexes that must be classified as "major" version changes. + + + + + + + diff --git a/maven-release-policies/maven-release-ccsemver-policy/src/site/site.xml b/maven-release-policies/maven-release-ccsemver-policy/src/site/site.xml new file mode 100644 index 000000000..220ecbb57 --- /dev/null +++ b/maven-release-policies/maven-release-ccsemver-policy/src/site/site.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maven-release-policies/maven-release-ccsemver-policy/src/test/java/org/apache/maven/shared/release/policy/ccsemver/CCSemVerVersionPolicyTest.java b/maven-release-policies/maven-release-ccsemver-policy/src/test/java/org/apache/maven/shared/release/policy/ccsemver/CCSemVerVersionPolicyTest.java new file mode 100644 index 000000000..4c90f5c27 --- /dev/null +++ b/maven-release-policies/maven-release-ccsemver-policy/src/test/java/org/apache/maven/shared/release/policy/ccsemver/CCSemVerVersionPolicyTest.java @@ -0,0 +1,160 @@ +package org.apache.maven.shared.release.policy.ccsemver; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import org.apache.maven.shared.release.policy.version.VersionPolicyRequest; +import org.apache.maven.shared.release.versions.VersionParseException; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +public class CCSemVerVersionPolicyTest +{ + + private void verifyNextVersion( + String versionRulesConfig, + String pomVersion, + String expectedReleaseVersion, + String expectedDevelopmentVersion, + String comment, + String... tags + ) throws VersionParseException + { + VersionPolicyRequest request = new VersionPolicyRequest(); + MockScmProvider provider = new MockScmProvider(comment, tags); + request.setScmProvider( provider ); + request.setScmRepository( new MockScmRepository( provider ) ); + request.setWorkingDirectory( "/tmp" ); + request.setConfig( versionRulesConfig ); + request.setVersion( pomVersion ); + + String suggestedVersion = new CCSemVerVersionPolicy().getReleaseVersion( request ).getVersion(); + assertEquals( expectedReleaseVersion, suggestedVersion ); + + request.setVersion( suggestedVersion ); + String suggestedDevelopmentVersion = new CCSemVerVersionPolicy().getDevelopmentVersion( request ).getVersion(); + assertEquals( expectedDevelopmentVersion, suggestedDevelopmentVersion ); + } + + private void verifyNextVersionMustFail( + String versionRulesConfig, + String pomVersion, + String comment, + String... tags + ) + { + try + { + verifyNextVersion( versionRulesConfig, pomVersion, "ignore", "ignore", comment, tags ); + } + catch ( VersionParseException vpe ) + { + // Success ! + return; + } + fail( "Should have failed" ); + } + + @Test + public void testDefaultVersionRules() throws VersionParseException + { + String normal = "Did something"; + String patch = "fix(core): Another fix."; + String minor = "feat(core): New thingy."; + String major = "fix!(core): Breaking improvement"; + + String versionRulesConfig = ""; + verifyNextVersion( versionRulesConfig, "1.1.1-SNAPSHOT", "1.1.1", "1.1.2-SNAPSHOT", normal ); // No Tag - No CC Comments + verifyNextVersion( versionRulesConfig, "1.1.1-SNAPSHOT", "1.1.1", "1.1.2-SNAPSHOT", patch ); // No Tag - Patch Comments + verifyNextVersion( versionRulesConfig, "1.1.1-SNAPSHOT", "1.2.0", "1.2.1-SNAPSHOT", minor ); // No Tag - Minor Comments + verifyNextVersion( versionRulesConfig, "1.1.1-SNAPSHOT", "2.0.0", "2.0.1-SNAPSHOT", major ); // No Tag - Major Comments + + // The default tag pattern will look at the "2.3.4" tag + verifyNextVersion( versionRulesConfig, "1.1.1-SNAPSHOT", "2.3.5", "2.3.6-SNAPSHOT", normal, "2.3.4", "v3.4.5" ); // Tag - No CC Comments + verifyNextVersion( versionRulesConfig, "1.1.1-SNAPSHOT", "2.3.5", "2.3.6-SNAPSHOT", patch, "2.3.4", "v3.4.5" ); // Tag - Patch Comments + verifyNextVersion( versionRulesConfig, "1.1.1-SNAPSHOT", "2.4.0", "2.4.1-SNAPSHOT", minor, "2.3.4", "v3.4.5" ); // Tag - Minor Comments + verifyNextVersion( versionRulesConfig, "1.1.1-SNAPSHOT", "3.0.0", "3.0.1-SNAPSHOT", major, "2.3.4", "v3.4.5" ); // Tag - Major Comments + + // Too many valid version tags on one commit + verifyNextVersionMustFail( versionRulesConfig, "1.1.1-SNAPSHOT", major, "1.1.1", "2.2.2" ); + } + + @Test + public void testCustomTagPattern() throws VersionParseException { + String normal = "Did something"; + String patch = "fix(core): Another fix."; + String minor = "feat(core): New thingy."; + String major = "fix!(core): Breaking improvement"; + + String versionRulesConfig = "" + + "" + + "^v([0-9]+\\.[0-9]+\\.[0-9]+)$" + + "" + + ""; + + verifyNextVersion( versionRulesConfig, "1.1.1-SNAPSHOT", "1.1.1", "1.1.2-SNAPSHOT", normal ); // No Tag - No CC Comments + verifyNextVersion( versionRulesConfig, "1.1.1-SNAPSHOT", "1.1.1", "1.1.2-SNAPSHOT", patch ); // No Tag - Patch Comments + verifyNextVersion( versionRulesConfig, "1.1.1-SNAPSHOT", "1.2.0", "1.2.1-SNAPSHOT", minor ); // No Tag - Minor Comments + verifyNextVersion( versionRulesConfig, "1.1.1-SNAPSHOT", "2.0.0", "2.0.1-SNAPSHOT", major ); // No Tag - Major Comments + + // The custom tag pattern will look at the "v3.4.5" tag + verifyNextVersion( versionRulesConfig, "1.1.1-SNAPSHOT", "3.4.6", "3.4.7-SNAPSHOT", normal, "2.3.4", "v3.4.5" ); // Tag - No CC Comments + verifyNextVersion( versionRulesConfig, "1.1.1-SNAPSHOT", "3.4.6", "3.4.7-SNAPSHOT", patch, "2.3.4", "v3.4.5" ); // Tag - Patch Comments + verifyNextVersion( versionRulesConfig, "1.1.1-SNAPSHOT", "3.5.0", "3.5.1-SNAPSHOT", minor, "2.3.4", "v3.4.5" ); // Tag - Minor Comments + verifyNextVersion( versionRulesConfig, "1.1.1-SNAPSHOT", "4.0.0", "4.0.1-SNAPSHOT", major, "2.3.4", "v3.4.5" ); // Tag - Major Comments + + // Too many valid version tags on one commit + verifyNextVersionMustFail( versionRulesConfig, "1.1.1-SNAPSHOT", minor, "v1.1.1", "v2.2.2" ); + } + + @Test + public void testCustomVersionRules() throws VersionParseException { + String normal = "This is a different commit."; + String patch = "This is a No Change commit."; + String minor = "This is a Nice Change commit."; + String major = "This is a Big Change commit."; + + String versionRulesConfig = "" + + "" + + "^The awesome ([0-9]+\\.[0-9]+\\.[0-9]+) release$" + + "" + + "^.*Big Change.*$" + + "" + + "" + + "^.*Nice Change.*$" + + "" + + "" + + ""; + + verifyNextVersion( versionRulesConfig, "1.1.1-SNAPSHOT", "1.1.1", "1.1.2-SNAPSHOT", normal ); // No Tag - No CC Comments + verifyNextVersion( versionRulesConfig, "1.1.1-SNAPSHOT", "1.1.1", "1.1.2-SNAPSHOT", patch ); // No Tag - Patch Comments + verifyNextVersion( versionRulesConfig, "1.1.1-SNAPSHOT", "1.2.0", "1.2.1-SNAPSHOT", minor ); // No Tag - Minor Comments + verifyNextVersion( versionRulesConfig, "1.1.1-SNAPSHOT", "2.0.0", "2.0.1-SNAPSHOT", major ); // No Tag - Major Comments + verifyNextVersion( versionRulesConfig, "1.1.1-SNAPSHOT", "3.4.6", "3.4.7-SNAPSHOT", normal, "2.3.4", "The awesome 3.4.5 release" ); // Tag - No CC Comments + verifyNextVersion( versionRulesConfig, "1.1.1-SNAPSHOT", "3.4.6", "3.4.7-SNAPSHOT", patch, "2.3.4", "The awesome 3.4.5 release" ); // Tag - Patch Comments + verifyNextVersion( versionRulesConfig, "1.1.1-SNAPSHOT", "3.5.0", "3.5.1-SNAPSHOT", minor, "2.3.4", "The awesome 3.4.5 release" ); // Tag - Minor Comments + verifyNextVersion( versionRulesConfig, "1.1.1-SNAPSHOT", "4.0.0", "4.0.1-SNAPSHOT", major, "2.3.4", "The awesome 3.4.5 release" ); // Tag - Major Comments + + // Too many valid version tags on one commit + verifyNextVersionMustFail( versionRulesConfig, "1.1.1-SNAPSHOT", minor, "The awesome 1.1.1 release", "The awesome 2.2.2 release" ); + } + +} diff --git a/maven-release-policies/maven-release-ccsemver-policy/src/test/java/org/apache/maven/shared/release/policy/ccsemver/MockScmProvider.java b/maven-release-policies/maven-release-ccsemver-policy/src/test/java/org/apache/maven/shared/release/policy/ccsemver/MockScmProvider.java new file mode 100644 index 000000000..6b18e1872 --- /dev/null +++ b/maven-release-policies/maven-release-ccsemver-policy/src/test/java/org/apache/maven/shared/release/policy/ccsemver/MockScmProvider.java @@ -0,0 +1,105 @@ +package org.apache.maven.shared.release.policy.ccsemver; +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import org.apache.maven.scm.ChangeSet; +import org.apache.maven.scm.ScmResult; +import org.apache.maven.scm.command.changelog.ChangeLogScmRequest; +import org.apache.maven.scm.command.changelog.ChangeLogScmResult; +import org.apache.maven.scm.command.changelog.ChangeLogSet; +import org.apache.maven.scm.provider.AbstractScmProvider; +import org.apache.maven.scm.provider.ScmProviderRepository; + +import java.util.Arrays; +import java.util.Date; + +public class MockScmProvider + extends AbstractScmProvider +{ + String comment; + String[] tags; + + public MockScmProvider( String comment, String... tags ) + { + this.comment = comment; + this.tags = tags; + } + + @Override + public String getScmType() + { + return "dummy"; + } + + @Override + public ScmProviderRepository makeProviderScmRepository( String scmSpecificUrl, char delimiter ) + { + ScmProviderRepository repository = new ScmProviderRepository(){}; + repository.setUser( "someone" ); + repository.setPassword( "secret" ); + repository.setPushChanges( false ); + return repository; + } + + private ChangeSet changeSet(String comment, String... tags) { + ChangeSet changeSet = new ChangeSet(); + changeSet.setComment( comment ); + changeSet.setAuthor( "Someone " ); + changeSet.setTags( Arrays.asList( tags ) ); + return changeSet; + } + + @Override + public ChangeLogScmResult changeLog(ChangeLogScmRequest request) { + Date from = new Date( 39817800000L ); + Date to = new Date( 1644768534785L ); + ChangeLogSet changeLogSet = new ChangeLogSet( + Arrays.asList( + changeSet( "Commit 19" ), + changeSet( "Commit 18" ), + changeSet( "Commit 17" ), + changeSet( "Commit 16" ), + changeSet( "Commit 15", "tag 1", "tag 2" ), + changeSet( comment ), // The comment that should make the difference + changeSet( "Commit 13" ), + changeSet( "Commit 12", "tag 3" ), + changeSet( "Commit 11" ), + changeSet( "Commit 10" ), + changeSet( "Commit 9" ), + changeSet( "Commit 8" ), + changeSet( "Commit 7" ), + changeSet( "Commit 6", "tag 4" ), + changeSet( "Commit 5" ), + changeSet( "Commit 4" ), + changeSet( "Commit 3" ), + changeSet( "Commit 2", tags ), // The first tag that looks like a version + changeSet( "Commit 1" ), + changeSet( "Commit 0" ) + ), from, to + ); + + ScmResult scmResult = new ScmResult( + "No command", + "Special for CCSemVer testing", + "No command output", + true + ); + return new ChangeLogScmResult( changeLogSet, scmResult ); + } +} diff --git a/maven-release-policies/maven-release-ccsemver-policy/src/test/java/org/apache/maven/shared/release/policy/ccsemver/MockScmRepository.java b/maven-release-policies/maven-release-ccsemver-policy/src/test/java/org/apache/maven/shared/release/policy/ccsemver/MockScmRepository.java new file mode 100644 index 000000000..5a6179afa --- /dev/null +++ b/maven-release-policies/maven-release-ccsemver-policy/src/test/java/org/apache/maven/shared/release/policy/ccsemver/MockScmRepository.java @@ -0,0 +1,30 @@ +package org.apache.maven.shared.release.policy.ccsemver; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import org.apache.maven.scm.repository.ScmRepository; + +public class MockScmRepository extends ScmRepository +{ + public MockScmRepository( MockScmProvider provider ) + { + super( "dummy", provider.makeProviderScmRepository( "dummy", ':' ) ); + } +} diff --git a/maven-release-policies/maven-release-ccsemver-policy/src/test/java/org/apache/maven/shared/release/policy/ccsemver/NextVersionCalculationTest.java b/maven-release-policies/maven-release-ccsemver-policy/src/test/java/org/apache/maven/shared/release/policy/ccsemver/NextVersionCalculationTest.java new file mode 100644 index 000000000..0a2f80c7f --- /dev/null +++ b/maven-release-policies/maven-release-ccsemver-policy/src/test/java/org/apache/maven/shared/release/policy/ccsemver/NextVersionCalculationTest.java @@ -0,0 +1,143 @@ +package org.apache.maven.shared.release.policy.ccsemver; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import org.apache.maven.shared.release.policy.version.VersionPolicyRequest; +import org.apache.maven.shared.release.versions.VersionParseException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.semver.Version; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.semver.Version.Element.MAJOR; +import static org.semver.Version.Element.MINOR; +import static org.semver.Version.Element.PATCH; + +public class NextVersionCalculationTest +{ + + private CCSemVerVersionPolicy versionPolicy; + private static final VersionRules DEFAULT_VERSION_RULES = new VersionRules( null ); + + @Before + public void setUp() + { + versionPolicy = new CCSemVerVersionPolicy(); + } + + @After + public void tearDown() + { + versionPolicy = null; + } + + private void assertNextVersion( VersionRules versionRules, String input, Version.Element element ) + { + switch (element) { + case MAJOR: + assertTrue( versionRules.isMajorUpdate( input ) ); + // We do not care about minor and patch + break; + case MINOR: + assertFalse( versionRules.isMajorUpdate( input ) ); + assertTrue( versionRules.isMinorUpdate( input ) ); + // We do not care about patch + break; + case PATCH: + assertFalse( versionRules.isMajorUpdate( input ) ); + assertFalse( versionRules.isMinorUpdate( input ) ); + break; + } + } + + @Test + public void testMajorMinorPatchDetection() + { + VersionRules rules = DEFAULT_VERSION_RULES; + assertNextVersion( rules, "feat!(core): New feature.", MAJOR ); + assertNextVersion( rules, "feat!: New feature.", MAJOR ); + assertNextVersion( rules, "feat(core): Foo.\n\nBREAKING CHANGE: New feature.\n", MAJOR ); + assertNextVersion( rules, "feat: Foo.\n\nBREAKING CHANGE: New feature.\n", MAJOR ); + + assertNextVersion( rules, "feat(core): New feature.", MINOR ); + assertNextVersion( rules, "feat: New feature.", MINOR ); + + assertNextVersion( rules, "Does not match any pattern.", PATCH ); + } + + @Test + public void testConvertToSnapshot() + throws Exception + { + String suggestedVersion = versionPolicy.getDevelopmentVersion( new VersionPolicyRequest().setVersion( "1.0.0" ) ) + .getVersion(); + + assertEquals( "1.0.1-SNAPSHOT", suggestedVersion ); + } + + public void verifyNextVersion(VersionRules versionRules, + String currentPomVersion, + String tag, + List comments, + String expectedNextVersion) throws VersionParseException { + CommitHistory commitHistory = new CommitHistory(); + commitHistory.addTags( tag ); + commitHistory.addChanges( comments ); + + assertEquals( expectedNextVersion, versionPolicy + .getReleaseVersion( + new VersionPolicyRequest().setVersion( currentPomVersion ), + versionRules, + commitHistory + ).getVersion() ); + } + + String patch1 = "Quick patch"; + String patch2 = "fix(core): Another fix."; + String minor1 = "feat(core): New thingy."; + String major1 = "fix!(core): Breaking improvement" ; + + List EMPTY = Collections.emptyList(); + List MAJOR_MESSAGES = Arrays.asList( patch1, patch2, minor1, major1 ); + List MINOR_MESSAGES = Arrays.asList( patch1, patch2, minor1 ); + List PATCH_MESSAGES = Arrays.asList( patch1, patch2 ); + + @Test + public void testDefaultVersionRules() throws VersionParseException + { + VersionRules rules = DEFAULT_VERSION_RULES; + verifyNextVersion( rules, "1.2.3-SNAPSHOT", "", EMPTY, "1.2.3"); // No Tag - No CC Comments + verifyNextVersion( rules, "1.2.3-SNAPSHOT", "", PATCH_MESSAGES, "1.2.3"); // No Tag - Patch Comments + verifyNextVersion( rules, "1.2.3-SNAPSHOT", "", MINOR_MESSAGES, "1.3.0"); // No Tag - Minor Comments + verifyNextVersion( rules, "1.2.3-SNAPSHOT", "", MAJOR_MESSAGES, "2.0.0"); // No Tag - Major Comments + verifyNextVersion( rules, "1.2.3-SNAPSHOT", "2.3.4", EMPTY, "2.3.5"); // Tag - No CC Comments + verifyNextVersion( rules, "1.2.3-SNAPSHOT", "2.3.4", PATCH_MESSAGES, "2.3.5"); // Tag - Patch Comments + verifyNextVersion( rules, "1.2.3-SNAPSHOT", "2.3.4", MINOR_MESSAGES, "2.4.0"); // Tag - Minor Comments + verifyNextVersion( rules, "1.2.3-SNAPSHOT", "2.3.4", MAJOR_MESSAGES, "3.0.0"); // Tag - Major Comments + } + +} diff --git a/pom.xml b/pom.xml index 1429ac0a7..95e817e6e 100644 --- a/pom.xml +++ b/pom.xml @@ -41,6 +41,7 @@ maven-release-manager maven-release-policies/maven-release-oddeven-policy maven-release-policies/maven-release-semver-policy + maven-release-policies/maven-release-ccsemver-policy maven-release-plugin diff --git a/src/site/apt/index.apt b/src/site/apt/index.apt index cbdaf26c5..47e46d943 100644 --- a/src/site/apt/index.apt +++ b/src/site/apt/index.apt @@ -42,3 +42,5 @@ Maven Release *----------------------------------------------------------+----------------+ | {{{./maven-release-policies/maven-release-semver-policy/}maven-release-semver-policy}} | a version policy that enforce SemVer format and upgrades minor element for next development version *----------------------------------------------------------+----------------+ +| {{{./maven-release-policies/maven-release-ccsemver-policy/}maven-release-ccsemver-policy}} | a version policy that enforce SemVer format and upgrades major/minor/patch element for next development version depending on the commit messages since the previous release (actually tag in the SCM). +*----------------------------------------------------------+----------------+