16

I am using the preparationGoals configuration option of the Maven release plugin to transform additional files to reflect the version of the project being released. This works beautifully.

The problem is that when executing the commit, the plugin explicitly specifies that only the pom.xml files should be included thus leaving my other files uncommited:

[INFO] Executing: /bin/sh -c cd /Users/jw/dev/Test && git commit --verbose -F /var/folders/w0/hr1h_7h50f3_pwd_nrk9l808000195/T/maven-scm-114713951.commit pom.xml library/pom.xml sample/pom.xml

Is there any way for me to override this behavior and specify additional files or globs to include in the commit?

(I also need this behavior for the completionGoals as well which I have configured to do that same transformation)

Jake Wharton
  • 75,598
  • 23
  • 223
  • 230
  • Which files should represent the version of your release? – khmarbaise Apr 16 '12 at 08:24
  • 1
    According to [maven-release plugin's doc](http://maven.apache.org/plugins/maven-release-plugin/examples/prepare-release.html), it only **Commit the modified POMs**. – yorkw Sep 26 '12 at 02:12
  • **Vote** for [this feature request](https://issues.apache.org/jira/browse/MRELEASE-798) – Vivek Apr 18 '21 at 09:01

4 Answers4

10

I also need to commit some additional files (changed by Maven Replacer plugin). I did it in the following way:

First I configured Maven Release plugin to execute additional goals:

<plugin>
    <artifactId>maven-release-plugin</artifactId>
    <version>2.5.3</version>
    <configuration>
        <preparationGoals>-Prelease -DreplacerVersion="${releaseVersion}" clean replacer:replace scm:checkin verify</preparationGoals>
        <completionGoals>-Prelease -DreplacerVersion="${developmentVersion}" clean replacer:replace scm:checkin verify</completionGoals>
    </configuration>
</plugin>
  • release profile defines configuration of Maven SCM plugin
  • replacerVersion argument is used by Maven Replacer plugin to set correct version in some files
  • clean is a standard goal run by Maven Release plugin (default: clean verify)
  • replacer:replace goal is responsible for modifying files
  • scm:checkin does commit and push
  • verify is a standard goal run by Maven Release plugin (default: clean verify)

Next I configured Maven Replacer plugin:

<plugin>
    <groupId>com.google.code.maven-replacer-plugin</groupId>
    <artifactId>replacer</artifactId>
    <version>1.5.3</version>
    <configuration>
        <includes>
            <include>${basedir}/file1.txt</include>
            <include>${basedir}/file2.txt</include>
        </includes>
        <replacements>
            <replacement>
                <token><![CDATA[<pattern>.*</pattern>]]></token>
                <value><![CDATA[<pattern>${replacerVersion}</pattern>]]></value>
            </replacement>
        </replacements>
    </configuration>
</plugin>

${replacerVersion} allows to use the same configuration for changing from a development to a release and next from the release to a next development version.

Finally I defined which version of Maven SCM plugin I want to use:

<plugin>
    <artifactId>maven-scm-plugin</artifactId>
    <version>1.9.5</version>
</plugin>

and configuration it in the release profile (I defined it in the profile to prevent accidental commits during non-release build):

<profile>
    <id>release</id>
    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <artifactId>maven-scm-plugin</artifactId>
                    <configuration>
                        <message>[maven-scm-plugin] set ${replacerVersion} version in files</message>
                        <includes>file1.txt, file2.txt</includes>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</profile>

Thanks to that after executing a command:

mvn release:prepare -DdevelopmentVersion=1.2.1-SNAPSHOT -DreleaseVersion=1.2.0 -Dtag=1.2.0

I see 4 commits:

  1. [maven-scm-plugin] set 1.2.0 version in files
  2. [maven-release-plugin] prepare release 1.2.0
  3. [maven-scm-plugin] set 1.2.1-SNAPSHOT version in files
  4. [maven-release-plugin] prepare for next development iteration
agabrys
  • 8,728
  • 3
  • 35
  • 73
  • How does this configure work with `DdryRun=true` option? Will maven-scm-plugin commit changes? – Jun May 03 '18 at 11:17
  • The configuration does not support `-DdryRun=true` option - it always commits and pushes changed files.Unfortunately, [Maven SCM Plugin](https://maven.apache.org/scm/maven-scm-plugin/) does not allow to skip execution (`skip` parameter does not exist). You can try to set `pushChanges` as false when `dryRun` is set as true - commits will be added only to a local repository. – agabrys May 04 '18 at 17:04
8

Could you use the maven-scm-plugin? Add a plugin execution running the scm:checkin goal to commit the files you want. Bind it to a phase that will execute when preparationGoals are run (if you specified one or more phases as the value for that element), or include the scm:checkin goal in preparationGoals directly.

user944849
  • 14,524
  • 2
  • 61
  • 83
  • +1 This is probably the only workaround at the moment, the con is it may cause trouble if rollback is performed later, as mentioned in [this similiar SO discussion](http://stackoverflow.com/questions/10583434/commit-some-files-while-maven-releaseprepare). – yorkw Sep 26 '12 at 02:20
  • I was able to get this working for a single file, but not for multiple. It works when executing manually, but not when I put it in the preparationGoals, with a comma-separated list. – Christopher Oct 27 '17 at 19:50
  • @Christopher I am hit by the same thing. Asked https://stackoverflow.com/questions/48947392/commit-multiple-files-with-maven-scm-plugin. Did you maybe figure it out? – Aruna Herath Mar 05 '18 at 09:50
  • @ArunaHerath Not exactly. I had to create a profile with multiple files in the includes, and then reference that profile in the release-plugin configuration. See the `commit-changed-manifests` profile in https://github.com/revelc/formatter-m2e-configurator/blob/master/pom.xml – Christopher Mar 06 '18 at 06:49
0

It appears the failure to allow specification of additional tag files is actually a bug in Maven. On line 130 in the org.apache.maven.shared.release.phase.AbstractScmCommitPhase class of the Maven Release Plugin, there are references to a "commitByProject" flag first introduced in Maven 2.0-beta-7.

A branch is used to determine the mechanism by which files are added to the Maven release:prepare commit. The SCM plugin is loaded with files in advance of the commit using the SCMFileSet class. One of the branch instantiations of that class may have been trying to add all files in the base directory, but it doesn't work that way in SCM.

This is a point where a fix could be implemented to take a list of files or to add a directory of files to commit.

Bottom line, after deep-diving into a debug execution of the Maven Release Plugin, it is invoking SCM Plugin to add only the POMs from the repos. Changing the poorly documented "commitByProject" flag has zero impact on the results in respect to which files are added into the SCM commit.

ingyhere
  • 11,818
  • 3
  • 38
  • 52
0

Another workaround is to configure another plugin (e.g. Maven AntRun Plugin) to manually run git add ., and then execute that as part of preparationGoals as well. This just happens to work and the modified files are part of the "[maven-release-plugin] prepare release ..." commit. However, I am not sure if this behavior is guaranteed, so this might rely on implementation details of the Maven Release Plugin.

Example configuration using the Maven AntRun Plugin to run git add:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-release-plugin</artifactId>
  <version>3.0.0-M6</version>
  <configuration>
    <preparationGoals>
      ... other goals ...
      antrun:run@git-add-changed
    </preparationGoals>
  </configuration>
</plugin>

<plugin>
  <artifactId>maven-antrun-plugin</artifactId>
  <version>3.1.0</version>
  <executions>
    <execution>
      <id>git-add-changed</id>
      <goals>
        <goal>run</goal>
      </goals>
      <configuration>
        <target>
          <exec executable="git" dir="${project.basedir}" failonerror="true">
            <arg value="add" />
            <arg value="." />
          </exec>
        </target>
      </configuration>
    </execution>
  </executions>
</plugin>

The main advantage of this compared to using the Maven SCM Plugin is that this does not require you to know in advance which files were modified and have to be committed. This can be useful when you replace a certain string in multiple files, e.g. @since NEXT in the Javadoc of all source files. With the scm:add goal of the Maven SCM Plugin the includes parameter seems to execute git add for all matching files separately, which will be slower and can cause issues when it matches by accident a file listed in .gitignore.

Marcono1234
  • 5,856
  • 1
  • 25
  • 43