maven release plugin ignores releaseProfile - maven-2

I am using two profiles: development and production.
Development should be active on default; production should be used when I am releasing.
In my pom.xml I have:
[...]
<plugin>
<artifactId>maven-release-plugin</artifactId>
<version>2.0-beta-9</version>
<configuration>
<useReleaseProfile>false</useReleaseProfile>
<goals>deploy</goals>
<arguments>-Pproduction</arguments>
</configuration>
</plugin>
[...]
<profiles>
<profile>
<id>production</id>
<properties>
<profile.name>production</profile.name>
</properties>
[...]
</profile>
<profile>
<id>development</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<profile.name>development</profile.name>
</properties>
[...]
</profile>
[...]
It just does not work.
useReleaseProfiles doesn't work either:
http://jira.codehaus.org/browse/MRELEASE-459
The development profile should be always active but not when running mvn release:perform.
How do you achieve this?
[UPDATE]:
I have seen with the debug flag that my production profile is used, but development profile is used too, because it is activeByDefault. This cant be overridden by the releaseProfile argument. It would be nice to force the release plugin to use only the "production" profile.

The maven-release-plugin documentation encourages using the releaseProfiles configuration parameter to automatically invoke profiles during the release process.
This is a better approach than manually invoking release profiles from the command-line. One reason, is because the profiles used in the release will be documented in the pom.xml and stored with the tagged code. This makes the build process easier to understand and easier to repeat later, exactly the same way the project was originally released.
If using maven-release-plugin older than 2.4 see this bug preventing use of the above mentioned parameter.
Be aware that in case of a multi-module project you'll have to put the "releaseProfiles" configuration in the root pom! See also this issue for more information about that.

I think you should simply activate your profiles through a property.
<profiles>
<profile>
<id>production</id>
<activation>
<property>
<name>build</name>
<value>release</value>
</property>
</activation>
[...]
</profile>
<profile>
<id>development</id>
<activation>
<property>
<name>build</name>
<value>develop</value>
</property>
</activation>
[...]
</profile>
<profiles>
Do your builds by executing something like this
mvn -Dbuild=develop package
mvn -Dbuild=develop test
mvn -Dbuild=release release:prepare
mvn -Dbuild=release release:perform

If you check "Introduction to Build Profiles", "Deactivating a profile":
mvn groupId:artifactId:goal -P !profile-1,!profile-2
I guess you could use this to deactivate your default profile?

This is a very old post but I came across this issue quite recently. The releaseProfile only worked for me when I set the releaseProfiles to profile called release. Any other profile gives same error.
Sample code:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
<configuration>
<tagNameFormat>#{project.artifactId}-#{project.version}</tagNameFormat>
<autoVersionSubmodules>true</autoVersionSubmodules>
<releaseProfiles>release</releaseProfiles>
<allowTimestampedSnapshots>true</allowTimestampedSnapshots>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>release</id>
<properties>
<connectionUrl>${scm-base}/tags/${project.artifactId}-${project.version}</connectionUrl>
</properties>
</profile>
</profiles>

Related

Maven: Only want to run profile if doing a build on the parent pom

I'm using Maven 3.0.3. I have a project that inherits from a parent …
<modelVersion>4.0.0</modelVersion>
<groupId>com.myco.util.ant</groupId>
<artifactId>selenium-framework</artifactId>
<packaging>jar</packaging>
<name>Myco Selenium Utils</name>
<parent>
<groupId>com.nna</groupId>
<artifactId>parent</artifactId>
<version>1.2-SNAPSHOT</version>
<relativePath>../parent</relativePath>
</parent>
In my parent pom I have the below profile. However, I only want this profile to be active if someone is doing a build on the parent pom, as opposed to one of its children. Does anyone know how I can adjust the below so that it won't be activated if someone is doing a build of a child project?
<profile>
<id>deploy-snapshot</id>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<phase>deploy</phase>
<configuration>
<target>
<condition property="is-release">
<not>
<contains string="${project.version}" substring="SNAPSHOT" />
</not>
</condition>
<fail if="is-release" message="You can only deploy snapshot versions of this project." />
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
Thanks, - Dave
You could try activating it by the presence/absence of a file or directory. You can find an example in the Sonatype Maven book. Note that there's a difference between "current working directory" and "${project.basedir}", and the differences are slightly different between Maven 2 and Maven 3, if that matters to you.
I had a similar situation, I wanted to run a profile in a subproject by default but not when build from the top level, and at the same time give the option to run it from the top project as well.
I used the user.dir property for that in combination of Ryan's reference.
in integration project's pom:
<profile>
<id>continuous-integration</id>
<!-- Two ways of activating this profile -->
<activation>
<!-- Run the build from the top with param -DfullTest -->
<property>
<name>fullTest</name>
</property>
<!-- Run the build from the integration directory -->
<file>
<missing>${user.dir}/integration</missing>
</file>
</activation>
...
<profile>
If needs to be disabled just change the <missing/> for a <exists/>.

How to exclude a module from a Maven reactor build?

We have a Maven 2 project with lots of modules in it. Example:
<modules>
<module>common</module>
<module>foo</module>
<module>data</module>
<module>bar</module>
... more ...
</module>
Let's say the "data" module is time consuming to build and we want to exclude it when the project is build by a CI server. Currently we use two pom.xml files to achieve this. One has all modules in it and the other one has all modules except the ones which can be left out for CI. But that's pretty annoying because sometimes we forget to put a new module into both files.
Is there a solution which doesn't need two separate module lists?
With Maven 3.2.1, you can now use -pl !<module_name>,!<module_name> to exclude certain modules from the reactor build.
See this feature request: https://issues.apache.org/jira/browse/MNG-5230
The easiest might be to use profiles like this:
<project>
...
<modules>
<module>common</module>
<module>foo</module>
<module>bar</module>
<modules>
...
<profiles>
<profile>
<id>expensive-modules-to-build</id>
<modules>
<module>data</module>
</modules>
</profile>
</profiles>
</project>
You should then check out ways you can activate profiles
The projects to build can also be specified on the mvn command line. This would remove the need for a separate pom, but instead you would have to change the CI configuration everytime there is a new module.
-pl,--projects <arg> Comma-delimited list of specified
reactor projects to build instead
of all projects. A project can be
specified by [groupId]:artifactId
or by its relative path.
Maybe a combination of this flag and --also-make-dependents or --also-make would reduce this maintenance burden again.
-am,--also-make If project list is specified, also
build projects required by the
list
-amd,--also-make-dependents If project list is specified, also
build projects that depend on
projects on the list
I assume you want the default build to always build everything, regardless of speed, so that new developers can get started quickly without having to understand lots about the POM. You can use profiles like this:
<modules>
<module>common</module>
<module>foo</module>
<module>bar</module>
</modules>
...
<profiles>
<profile>
<id>expensive-modules-to-build</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<modules>
<module>data</module>
</modules>
</profile>
</profiles>
</project>
The problem with this is that if a developer specifies another profile on the command line, then the expensive-modules-to-build isn't included (unless the developer also specifies it). This makes it complicated to remember which profiles need to be included.
Here is a hacky way around that. Both profiles are always included, because the pom.xml file always exists. So to exclude the expensive modules, you can use -P!full-build on the command line.
<profiles>
<profile>
<id>full-build</id>
<activation>
<file>
<exists>pom.xml</exists>
</file>
</activation>
<modules>
<module>data</module>
</modules>
</profile>
<profile>
<id>short-build</id>
<activation>
<file>
<exists>pom.xml</exists>
</file>
</activation>
<modules>
<module>common</module>
<module>foo</module>
<module>bar</module>
</modules>
</profile>
</profiles>
Another idea: Reactor modules can be nested, so it should be possible to group your fast and slow-building modules into separate poms and then add another aggregator pom containing these two as modules. Your CI Server could then only reference the pom containing the fast building modules.
<artifactId>fast</artifactId>
<modules>
<module>fast-a</module>
<module>fast-b</module>
<module>fast-c</module>
</module>
<artifactId>all</artifactId>
<modules>
<module>fast</module>
<module>slow</module>
</module>
You could be to use maven profiles. In our build environment, we created a profile quick that disables many plugins and test execution.
This is done by
<profile>
<id>quick</id>
<properties>
<skipTests>true</skipTests>
<!-- others... -->
</properties>
<build>
<plugins>
<!-- configuration... -->
</plugins>
</build>
</profile>
And then we invoke maven the following way
mvn groupId:artifactId:goal -P quick
You could maybe disable compilation and other standard plugins in the pom of your module to speed it up.
Not exactly the answer these folks were asking for. My situation was I wanted to deploy only the parent pom. I'm using the spring-boot-thin-layout in a child module. This requires the parent module be deployed into artifactory. I added the following into my project. It enables skipping of install and/or deploy phase.
In my parent pom:
<properties>
<disable.install>true</disable.install>
<disable.deploy>true</disable.deploy>
<enable.deployAtEnd>true</enable.deployAtEnd>
</properties>
<profiles>
<profile>
<id>deploy-parent</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<disable.install>true</disable.install>
<disable.deploy>true</disable.deploy>
<deployAtEnd>${enable.deployAtEnd}</deployAtEnd>
</properties>
<build>
<finalName>${project.version}</finalName>
</build>
</profile>
</profiles>
And the in my child pom(s) or any module you don't want deployed with parent:
<properties>
<maven.install.skip>${disable.install}</maven.install.skip>
<maven.deploy.skip>${disable.deploy}</maven.deploy.skip>
<deployAtEnd>${enable.deployAtEnd}</deployAtEnd>
</properties>
So effectively when I run mvn deploy on the parent pom, it will compile all the modules, not run install on anything, and then at the end deploy any module not having <maven.deploy.skip>${disable.deploy}</maven.deploy.skip> in it's properties. So in my case only deploying the parent.

using maven variables defined in two separate profiles

I have two profiles in my pom.xml, dev and stage:
<profiles>
<profile>
<id>dev</id>
<properties>
<hostname>vl-wlp1.hk.oracle.com</hostname>
</properties>
<id>stage</id>
<properties>
<hostname>vl-wcfs.hk.oracle.com</hostname>
</properties>
</profile>
</profiles>
And I'd like use these in my site documentation at:
src/site/apt/index.apt
like so:
Dev Site: ${dev.hostname}
Stage Site: ${stage.hostname}
Can I do that or something else that has the same effect?
Not without a huge hack, no.
If you want to read both property values independently, they will have to be two different properties.
How about a pragmatic solution like this:
<properties>
<dev.host>vl-wlp1.hk.oracle.com</dev.host>
<stage.host>vl-wcfs.hk.oracle.com</stage.host>
</properties>
<profiles>
<profile>
<id>dev</id>
<properties>
<hostname>${dev.host}</hostname>
</properties>
<id>stage</id>
<properties>
<hostname>${stage.host}</hostname>
</properties>
</profile>
</profiles>
src/site/apt/index.apt:
Dev Site: ${dev.host}
Stage Site: ${stage.host}
(The huge hack mentioned above would mean programmatically iterating over the current project's profiles and parsing each profile's properties manually, you could do that in a custom maven plugin or in a Groovy Script using GMaven)

Maven profiles and install

If I have Maven builds set up for an app with profiles set up for different environments (say like prod vs. dev, defining different DB settings and stuff like that) the 'install' goal doesn't seem to make sense, as I don't know which environment got installed into my repo - I've just got com.example.myproject:myapp:0.0.1.
Have I misunderstood something, or are profiles supposed to be used with other goals?
Well, you could use the classifier attribute so that each profile creates a jar with the classifier, i.e. a unique jar for each environment. Here is a code snippet to illustrate this. When run with the dev profile (mvn -P dev install), it creates a jar with -dev classifier, like myapp-dev-0.0.1.jar
<project>
...
<properties>
<env></env>
</properties>
...
<build>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<classifier>${env}</classifier>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
...
<profile>
<id>dev</id>
<properties>
<env>dev</env>
</properties>
...
</profile>
</profiles>
</project>
You run the usual mvn commands and can select the appropriate profile with -P http://maven.apache.org/guides/introduction/introduction-to-profiles.html So it dependends on which profile you chose, what gets installed in the repository.

How to skip install phase in Maven build if I already have this version installed in repo

I have a project that consist of 3 different libraries. When I run install script it takes all libraries from repo and run mvn clean install on them. But this version of library already installed in repo. Is there a way to skip install phase if version in pom.xml equal version in my local repo.
I know that I can use local repo and just set dependencies. But my boss want that our project can build only with public repos and without any our repos.
You can bypass like this
-Dmaven.install.skip=true
<profiles>
<profile>
<id>skipInstall</id>
<activation>
<property>
<name>maven.install.skip</name>
<value>true</value>
</property>
</activation>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>default-install</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
Last week Olivier Lamy patched this jira.
MINSTALL-73
Most maven plugins can be skipped by specifying something like:
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>X.Y</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
you can also set up build profiles to set properties and use that to determine the value. for example, running the command: mvn -Pexample would select the "example" profile. The POM would then contain:
...
<properties>
<skip.install>false</skip.install>
...
</properties>
...
<profile>
<id>example</id>
<properties>
<skip.install>false</skip.install>
</properties>
</profile>
...
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>X.Y</version>
<configuration>
<skip>${skip.install}</skip>
</configuration>
</plugin>
...
Using these POM additions, the default behavior for the install plugin will be to perform its default goal, but if the example profile is selected, then the install plugin will skip its goal.
Using what I learned from the other answers, this was the cleanest result for me.
In my super pom I added a pluginManagement/plugin to disable default-install and default-test phases when the property deployOnly is set.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
<executions>
<execution>
<id>default-install</id>
<configuration>
<skip>${deployOnly}</skip>
</configuration>
</execution>
<execution>
<id>default-test</id>
<configuration>
<skip>${deployOnly}</skip>
</configuration>
</execution>
</executions>
</plugin>
So on the command line, I can disable install and test phases by adding -DdeployOnly.
mvn clean install #build and test everything
mvn deploy -DdeployOnly #just deploy it
I know that I can use local repo and just set dependencies. But my boss want that our project can build only with public repos and without any our repos.
Are you sure you understood correctly what you boss meant? I interpret the above as "don't install third party libraries in your local repository, use only libraries available in public repositories". This is different from "don't use your local repository" which is basically impossible, that's just not how maven works. I'd try to clarify this point.
Apart from that, I don't get the question which is very confusing (what repo are you talking about? What is the install script doing? Why do you call clean install on libraries? etc).
Extending the other answers, from the future.
Maven plugins have a surprisingly high freedom, how do they run. If they want, they can ignore/override the typical pom.xml settings. Furthermore, also the <configuration><skip>true</skip></configuration> is only a convention, nothing obligates a plugin to follow it, except that most of them is developed so.
My experiments with the recent problem show, that both #Cemo's and #MiloshBoroyevich solution should be utilized, also the plugin requires both to really let us in peace. More concretely, the only working configuration by me was this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
<executions>
<execution>
<id>default-install</id>
<phase>none</phase>
</execution>
</executions>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
One of your options is to put the deployment to another module. I.e. have one pom.xml build the artifact and install it to the local repo, and another pom.xml to deploy it. This separation is quite common in larger projects, where the testsuite is sometimes a separate module or even a project, the packaging happens in several stages, etc.
- pom.xml - myProject-root - type=pom
- pom.xml - myProject-artifact - type=jar
- pom.xml - myProject-deploy - type=pom, does the deployment, skips it's own `install` goal