Maven Release Plugin - release:branch - Version Parameter in -DbranchName - maven

When executing the mvn release:branch command, I'd like to try and configure the -DbranchName argument with a version parameter. But I haven't been able to find a way to successfully do this yet.
For example, if I have a project in trunk with version 1.0-SNAPSHOT, I want to create a branch using the --batch-mode option and specify a -DbranchName with the current project version (1.0-SNAPSHOT) as a parameter in the within the branchName.
I've tried doing mvn release:branch -DbranchName=VERSION-#{project.version}, but it doesn't seem to work as I had hoped. Instead of creating a branch with the name VERSION-1.0, I get the following error:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-release-plugin:2.5.3:branch (default-cli) on project project-a: Unable to branch SCM
[ERROR] Provider message:
[ERROR] The svn branch command failed.
[ERROR] Command output:
[ERROR] svn: E205000: Try 'svn help copy' for more information
[ERROR] svn: E205000: Syntax error parsing peg revision '{project.version}'
Is there a valid way to do this? Or is this not possible when doing a release:branch with the maven release plugin?
Edit
Basically what I'm looking for is something similar to the tagNameFormat property but for branches. When doing a release:perform goal, I can have <tagNameFormat>VERSION-#{project.version}</tagNameFormat> specified in the pom, and I don't need to include any tag name property when doing a release using --batch-mode. Is there any similar property for formatting of branch names when doing a release:branch?

You can use the built-in ${project.version} (prefixed with $ instead of # -- the latter seems only available in the tagNameFormat parameter). Note that if you use ${project.version}, the value will probably contain the substring SNAPSHOT in it. There may be several ways of removing that substring. One way is to apply the helper plugin mentioned in the answer to this question which gives you access to the version's semantic components:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>parse-version</id>
<goals>
<goal>parse-version</goal>
</goals>
</execution>
</executions>
</plugin>
Then you can use the properties on the command line:
mvn release:branch -DbranchName=VERSION-${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}
Or better to include the branchName parameter as part of the plugin configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
<executions>
<execution>
<configuration>
<branchName>VERSION-${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}</branchName>
</configuration>
<goals>
<goal>branch</goal>
</goals>
</execution>
</executions>
</plugin>
In this case you don't need to pass these magic properties on the command line.

Related

Pomless Tycho build + maven release plugin

I have a pomless tycho build which I want to release with the maven release plugin. The issue I have is that I get errors from the git plugins for the generated .polyglot.build.properties even though it is not included in the configuration of the git-add goal.
Parent pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
<configuration>
<autoVersionSubmodules>true</autoVersionSubmodules>
<localCheckout>true</localCheckout>
<preparationGoals>
org.eclipse.tycho:tycho-versions-plugin:${tycho.version}:update-eclipse-metadata
build-helper:parse-version
org.apache.maven.plugins:maven-scm-plugin:1.9.5:add
org.apache.maven.plugins:maven-scm-plugin:1.9.5:checkin
</preparationGoals>
<completionGoals>
org.eclipse.tycho:tycho-versions-plugin:${tycho.version}:update-eclipse-metadata
build-helper:parse-version
org.apache.maven.plugins:maven-scm-plugin:1.9.5:add
org.apache.maven.plugins:maven-scm-plugin:1.9.5:checkin
</completionGoals>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-scm-plugin</artifactId>
<version>1.9.5</version>
<executions>
<execution>
<id>default-cli</id>
<goals>
<goal>add</goal>
<goal>checkin</goal>
</goals>
<configuration>
<includes>**/META-INF/MANIFEST.MF,**/feature.xml,**/*.product,**/category.xml,release.properties</includes>
<excludes>**/target/**</excludes>
<message>Changing the version to reflect the pom versions for the release</message>
<pushChanges>false</pushChanges>
</configuration>
</execution>
</executions>
</plugin>
The error I get:
fatal: pathspec 'my.plugin/.polyglot.build.properties'
did not match any files
After looking at the source code of tycho-pomless, polyglot, and maven-release, I conclude pomless build can't work with maven release. I need to add pom.xml
The reason is:
tycho-pomless uses polyglot, which creates an temporary pom from the build.properties, which is deleted when the JVM exits
maven release:prepare spawns a child maven process to execute the preparation goals. When the child process finishes, this deletes the temporary files. The available mavenExecutorId values are "invoker" which invokes a new process, and "forked", which forks the process. Which means both spawn a new JVM.
So in conclusion, it looks like tycho-pomless (or any polyglot build, really) and maven-release are incompatible in the presence of preparation goals, and there seems to be no workaround. The possible workaround of executin the preparation goals in the same JVM seems to be unavailable. So the solution is adding a pom.xml
Check first is this is similar to this question, where the plugin does finds the files it should add, but, when creating the command line, it does not respect the correct root directory.
See if the path mentioned in pathspec 'my.plugin/.polyglot.build.properties' the correct one.
Double-check if your POM and folder hierarchy is at the right place, meaning in the project root folder.
The OP kutschkem refers in the comments to:
the .polyglot.build.properties is a temporary file, deleted by the release:prepare child process exit.
But release plugin picks it up as the pom of the project to checkin.
That might be why I see in Tycho/Reproducible Version Qualifiers
<jgit.ignore>
pom.xml
.polyglot.build.properties
</jgit.ignore>

Using maven-deploy-plugin to deploy Eclipse product

I am trying to deploy an Eclipse product to Nexus repository. I am somewhat successful, but still get some errors that I am not sure how to handle.
I am using maven-deploy-plugin in the feature (F) that builds product:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<phase>deploy</phase>
<goals>
<goal>deploy-file</goal>
</goals>
<configuration>
<repositoryId>snapshots</repositoryId>
<packaging>zip</packaging>
<generatePom>true</generatePom>
<url>http://repo:8081/nexus/content/repositories/snapshots</url>
<groupId>my.group</groupId>
<artifactId>my.artifact</artifactId>
<version>1.0.0-SNAPSHOT</version>
<file>
target/products/product.zip
</file>
</configuration>
</execution>
</executions>
</plugin>
I execute 'mvn clean install' to build the product and then 'mvn deploy' on F. If I do that then I get error
Exception while publishing product /home/akravets/dev/workspaces/trunk/my.repository.feature/myProduct.product: publishing result: [Included element my.product.feature.feature.group 8.0.1.R20180301-1431 is missing. Cannot determine filter for requirement to this element.] -> [Help 1]
I've read discussions about this issue, but nothing seems relevant to my issue because I don't have any defined deploy phases besides the one in maven-deploy-plugin.
If I change phase of maven-deploy-plugin to 'install' I get almost satisfactory results. The zip file and generated pom get deployed to repository, but the build fails with error
product.qualifier-p2artifacts.xml. Return code is: 400, ReasonPhrase: Bad Request.
Why does this file even gets considered to be deployed to repository when it's not in file element of maven-deploy-plugin and it's not in the directory structure where zip file is: target/ vs target/product/product.zip? Is this because maven-deploy-plugin is executed during the install phase and it picks up all generated resources as candidates for deployment?
I simply recommend you to use Maven-Tycho to deploy Eclipse RCP product.Tycho determines the dependencies of a plug-in via the MANIFEST.MF file of the plug-in and fetches the required plugins-bundles through the online repositories.
You can check this git repository as an example; rcp - tycho

Use maven-exec-plugin to run command line

I want to use maven-exec-plugin to run command line (cmd) for converting a Markdown file to a PDF file using Pandoc.
To do that manually, I've executed these commands:
pandoc ReadMe.md -o ReadMe.html
pandoc ReadMe.html --latex-engine=xelatex -o ReadMe.pdf
I wasn't able to run that in one command, pandoc giving weird error! But this is another problem...
I've added this to my pom file using other sample found on the web but without success.
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>pandoc</id>
<phase>generate-pdf</phase>
<configuration>
<executable>cmd</executable>
<workingDirectory></workingDirectory>
<arguments>
<argument>/C</argument>
<argument>pandoc</argument>
<argument>README.md</argument>
<argument>-o</argument>
<argument>README.html</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
I'm not a maven guru and help is appreciate!
The defined phase, <phase>generate-pdf</phase>, is not a maven phase, hence Maven didn't bind the execution to its workflow.
You should bind it to a standard Maven phase, depending on your need. Try <phase>package</phase> for instance, it will be executed nearly at the end of your build.
The id element of a plugin execution is free text, you can type the id you want, it will appear as part of the build output in curved brackets after the plugin and goal name,
i.e. exec-maven-plugin:1.1:exec (pandoc)
The phase element instead must match a well known maven phase in order to attach the plugin/goal execution to it. If the phase is not well known, then Maven will simply ignore that plugin/goal execution (which is also an adopted approach, usually using the de-facto standard none as phase, to disable an inherited plugin execution, but that's a bit advanced for the scope of this question I would say).
For more details on maven phases, look at the official documentation, here.
For a full list of maven phases, here.

Maven Release Perform Commit Additional Files

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)
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:
[maven-scm-plugin] set 1.2.0 version in files
[maven-release-plugin] prepare release 1.2.0
[maven-scm-plugin] set 1.2.1-SNAPSHOT version in files
[maven-release-plugin] prepare for next development iteration
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.
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.
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.

mvn release:perform automatically specify scm tag that includes release version

I would like to setup my maven release to run in batch mode, but I'm not a fan of the default scm tag ${artifactId}-${releaseVersion}. Instead, I'd like to simply tag it with ${releaseVersion}; however, I'm unclear if such a property exists (ie. without the -SNAPSHOT suffix).
I'd like the configuration to resemble the code below. Is such a default tagging possible with the maven-release-plugin?
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.0</version>
<configuration>
<tag>${releaseVersion}</tag>
</configuration>
</plugin>
I just got this to work when using Hudson to do my release. I noted that Hudson (with the Maven Release Plugin) is initiating the command with a property like -Dproject.rel.com.example:my-artifact-id=1.0.1. Using the following plugin configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<configuration>
<tag>REL-${project.rel.com.example:my-artifact-id}</tag>
</configuration>
</plugin>
Resulted in the tag being REL-1.0.1
I'm new to the release plugin but I would assume something similar would work from the command line.
You can pass in the properties for:
releaseVersion -- What version you want it to be released as (1.0)
developmentVersion -- The next version (2.0-SNAPSHOT)
tag -- The name of the tag
a 1.0-SNAPSHOT implies a 1.0 release version, but doesn't set it. You can set that property in your POM file as a regular property.
try this:
<configuration>
<tag>${project.version}</tag>
</configuration>

Resources