Michael has posted 3 posts at DZone. View Full User Profile

Automating Releases With maven-release-plugin

05.20.2010
| 38030 views |
  • submit to reddit

The maven-release-plugin is used to automate a lot of the manual steps involved in releasing new versions of your software. The automation prevents mistakes which ultimately occur using a manual process. The amount of work the plug-in does is impressive – it will perform these basic operations.

  1. Verify all files in your project are committed to CVS
  2. Verify your project has no SNAPSHOT dependencies
  3. Verify <version> of your project's pom.xml is a SNAPSHOT version
  4. Confirm what the project's next RELEASE version will be
  5. Confirm what the project's CVS tag for the next release version will be
  6. Confirm what the project's next SNAPSHOT version will be
  7. Update the <version> of your pom.xml from the SNAPSHOT version to the next RELEASE version
  8. Commit the pom.xml to CVS
  9. Tag the project in CVS
  10. Checkout the project from CVS using the tag
  11. Build the project
  12. Upload the artifacts to a Maven repository
  13. Update the <version> of your pom.xml from the RELEASE version to your project's next SNAPSHOT version
  14. Commit the pom.xml to CVS

If you work on one project, performing all these steps manually may not be a big deal. But if your enterprise consists of multiple projects with dependencies between them, the automation provided by the maven-release-plugin saves time and prevents mistakes. This is why I needed to get the maven-release-plugin working.

The homepage for the plugin ( http://maven.apache.org/plugins/maven-release-plugin/) will tell you everything you need to know about the plugin except how to run it! Think about the technologies the plugin is integrating. Consider CVS. Should be simple enough to integrate CVS; just configure the project with the CVS connection string. However, SourceForge.net requires an SSL connection for write access to a CVS repository. This means integration with something like SSH. Now that SSH is involved, do you really want to put in your username/password every time a connection to the CVS repository is needed? No? This means integration with public/private key pairs on both the client and server side. See how quickly this gets very complicated. Now throw in the Windows operating system where SSH and CVS binaries are not as readily available as on a Linux environment and you have yourself a configuration nightmare.

Abstract

The purpose of this article is to document the steps needed to configure all the technologies which the maven-release-plugin will need to work with a regular Maven repository and with a CVS repository requiring an SSL connection. If you are an open source developer using a CVS repository on SourceForge.net, a standard Maven repository, and your primary OS is Windows, then this article is for you.

If someone has a different way of doing this, please contact me! It took me over a week of putting together different Internet resources to get this working and given its complexity I have a feeling there has to be an easier way.

Outline

There are many steps required to get all the technologies configured correctly for the maven-release-plugin. Before we begin, here is an outline.

  • Create Accounts
  • Download Software
  • Configure the System %PATH%
  • Generate Public/Private Key
  • Configure SourceForge.net
  • Configure "sourceforge.cmd"
  • Test Plink
  • Configure the System %CVS_RSH%
  • Test CVS
  • Configure Maven
  • Configure Eclipse
  • Checkout your project
  • Configure your project
  • Run maven-release-plugin
  • Promote Artifacts from Staging
  • Troubleshooting

Create Accounts

SourceForge.net

http://sourceforge.net

SourceForge.net requires an SSL connection for write access to your project's CVS repository. I am going to use SourceForge.net for this article however the configuration steps in this article can also be applied to any CVS repository requiring SSL.

Normally connecting to a SourceForge.net CVS repository over SSL is not a problem. Configure the CVS connection in Eclipse to use the "extssh" connection type and enter your username and password when prompted. It is not so simple when you want to use the maven-release-plugin later.

If you do not already have a SourceForge.net account, go the website and create a new account and a new project.

Sonatype OSS Nexus

http://oss.sonatype.org

Sonatype recently opened a Maven repository at http://oss.sonatype.org for open source developers. Like SourceForge.net giving you a CVS repository to put your source code, Sonatype OSS Nexus gives you a Maven Repository to put your artifacts (both RELEASE and SNAPSHOT). Your account at OSS Nexus can be configured to promote your artifacts into the OSS Nexus public "Releases" repository or into the Maven main repo (http://repo1.maven.org/maven2).

If you do not already have an OSS Nexus account, go to the website and create a new one.

Download Software

You are going to need all this software.

CVSNT

http://www.march-hare.com/cvspro/

CVSNT recently became CVSPRO with a paid commercial version. There is a community edition still available which is free however the first time you use cvs.exe, a popup dialog box appears asking to buy the PRO version and you just have to wait for it to go away. If you can find a previous version of CVSNT, use it instead.

When you go to the URL listed above to download CVSNT, Click on the "All Downloads" hyperlink at the top. In the dropdown list of downloadable products, select "CVSNT Community Command Line Client 2.5.05 for Windows" (see figure 1). Download and install it on your computer.

Figure 1
Figure 1

PUTTYGEN

http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html

Puttygen is used to generate a public/private key pair so SSL connections can be established without having to enter a username and password every time.

PLINK

http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html

Plink is a command-line connection tool similar to ssh. It will allow SSL connections from your computer to your CVS Repository on SourceForge.net.

MAVEN

http://maven.apache.org/

Download and unzip Maven.

ECLIPSE

http://www.eclipse.org/

Download and unzip Eclipse

M2ECLIPSE

http://marketplace.eclipse.org/content/maven-integration-eclipse

M2Eclipse is an Eclipse plug-in for working with Maven projects and Maven repositories. The URL above takes you to the M2Eclipse plug-in homepage. Click the green arrow to get the URL for the plug-in update site then add that URL to Eclipse to install the plug-in (see figure 2).

Figure 2
Figure 2

Configure the System %PATH %

The cvs.exe binary needs to be added to the Windows system PATH. Follow these steps (see figure 3).

  1. Right-click "My Computer" on the desktop
  2. Select "Properties"
  3. Click the "Advanced system settings" hyperlink
  4. Click the "Environment Variables..." button
  5. Select "PATH" from the list.
  6. Click the "Edit..." Button
  7. Add a ";" character to the end
  8. Paste in the fully-qualified path to the CVSNT directory (Your CVSNT directory may be different than the one shown in the screenshot).
  9. Click all the "OK" buttons until all the windows are closed.

Figure 3
Figure 3

After adding the CVSNT directory to the PATH, let us check to make sure it worked. To do this, first open a Windows Command Prompt (or DOS Prompt) now needs to be opened. Follow these steps (see figure 4).

  1. Click the Windows "Start" button on the desktop
  2. Type "cmd" in the search box.
  3. Press the "Enter" key to open a Windows Command Prompt

Figure 4
Figure 4

To check the cvs.exe binary is on the PATH correctly, execute the cvs.exe command. The results will be similar to figure 5.

Figure 5
Figure 5

If you attempt to execute the cvs.exe command and instead an error message appears saying

"cvs.exe is not recognized as an internal or external command...",

your PATH is not set properly. Fix this before continuing.

Generate Public/Private Key

Puttygen.exe will now be used to generate a public/private key pair. This is necessary for communication with your SourceForge.net repository over SSL. The public/private key pair will allow the communication without prompting for a username/password every time a connection is made.

Double-click puttygen.exe to run the application (see figure 6).

Figure 6
Figure 6

To generate a new public/private key pair, follow these steps.

  1. Click the "Generate" button (see figure 6)
  2. Follow the instructions
  3. Click the "Save public key" button
  4. Save the public key in a file named "MyKey.pub"
  5. Click the "Save private key" button
  6. Save the private key in a file named "MyKey.ppk"

You now have a public/private key pair which you will use for SSL communication with your SourceForge.net CVS repository.

Keep the PuttyGen application running! You will need it open during the next step which is to configure your SourceForge.net account.

Configure SourceForge.net

For SSL communication with public/private key pairs, the private key always remains secret and protected on your computer. The public key, however, is put onto whatever system you are communicating securely with. In this case, you will be communicating securely with your SourceForge.net CVS repository. So you need to put the contents of your public key on your SourceForge.net account. Follow these steps (see figure 7).

  1. Open a browser to http://sourceforge.net
  2. Login to your SourceForge.net Account.
  3. Click the "Account" hyperlink in the upper-right corner of the page.
  4. Click the "Services" tab
  5. Click the "Edit SSH Keys for Shell/CVS"hyperlink.

Figure 7
Figure 7

You will now be able to see the SSL public keys on your SourceForge.net account. If you have just created an account or you have never put a public key on your account, the text area of keys will be blank. To get your public key on your SourceForge.net account correctly, follow these steps.

  1. Switch back the running instance of PuttyGen
  2. Select and COPY the entire public key (see figure 8)
  3. Switch back to the web browser to SourceForge.net
  4. PASTE the contents of the public key on a new line of your list of keys (see figure 9). When you paste, the entire key should be on a single line – the key should not be broken up into multiple lines. If you have more than one key on your account, each key is pasted on its own line. Do not have an extra line between keys.
  5. Click the "Update" button.

Figure 8
Figure 8

Figure 9
Figure 9

Configure "sourceforge.cmd"

Plink is a command-line connection tool similar to ssh. It will allow SSL connections from your computer to your CVS Repository on SourceForge.net. After having completed the creation of a public/private key pair and putting the public key on your SourceForge.net account, it is now time to see if Plink will work in establishing a secure SSL connection.

Instead of using the plink.exe binary directly, we are going to create a small Windows command file so configuration parameters can more easily passed to Plink. Follow these steps.

  1. Open Notepad
  2. Type the following into notepad (location of your files may be different)
    C:\plink.exe -noagent -i C:\MyKey.ppk %*%
  3. Save the file as "sourceforge.cmd"

Test Plink

Now we are able to test Plink and see if an SSL connection can be made from your computer to your CVS Repository on SourceForge.net. Follow these steps.

  1. Open a Command Prompt (DOS Prompt).
  2. Change directory to the location of the "sourceforge.cmd" command file.
  3. Execute the following command:
    C:\>sourceforge.cmd [YOUR_SOURCEFORGE_PROJECT_NAME].cvs.sourceforge.net

You will be prompted for your username as plink.exe prepares to make the connection. Once connected two things will happen. First, a short welcome message will be displayed showing you have successfully connected. Second, the connection will be immediately terminated because this is a non-interactive shell (see figure 10).

Figure 10
Figure 10

If this worked, congratulations! You just successfully established a SSL connection with SourceForge.net using your public/private key. If not, fix this before continuing.

Configure the System %CVS_RSH%

CVS relies on a System environment variable named CVS_RSH to tell it where the program is located which is capable of creating SSL connections. For Linux, this is typically ssh. For Windows, we have plink.exe. More specifically, we have the "sourceforge.cmd" command file created in the previous step.

A new System environment variable named "CVS_RSH" must now be created pointing to the "sourceforge.cmd" command file. Recalling how the System PATH was configured, follow these steps (see figure 11).

  1. Click the "New..." button.
  2. Set "Variable name:" equal to "CVS_RSH"
  3. Set "Variable value:" equal to the fully qualified location of the "sourceforge.cmd" file.
  4. Click all the "OK" buttons until all the windows are closed.

Figure 11
Figure 11

Test CVS

Now that the CVS_RSH environment variable is set, cvs.exe should be able to use it to establish a secure connection with a CVS repository. To test this, follow these steps:

  1. Open a NEW Command Prompt (DOS Prompt). I emphasize the word NEW here. If you already have a Command Prompt open you must close it and open a new one.
  2. Execute the following command (This is a long command! Make sure you have all the ":", "@", "."and "/" characters in the right place!)
    c:\>cvs -d :ext:[YOUR_SOURCEFORGE_USERNAME]@[YOUR_SOURCEFORGE_PROJECT_NAME].cvs.sourceforge.net:/cvsroot/[YOUR_SOURCEFORGE_PROJECT_NAME] ls

When this command is executed the first time, you may get a dialog box from CVSPRO asking you to purchase the software. You just have to wait until the dialog box goes away. After it does, your command will be executed. If successful, you will see a listing of the directories in your SourceForge.net CVS repository (see figure 12). If not, fix this before continuing.

Figure 12
Figure 12

Configure Maven

Up until now we have been concentrating on CVS and your account at SourceForge.net. All the configuration done to this point allows you to establish a secure SSL connection from your computer to your SourceForge.net CVS repository using public/private key pairs.

Now we are going to concentrate on a Maven repository and your account at Sonatype OSS Nexus. We are going to configure Maven so your computer knows how to resolve dependencies deployed to Sonatype OSS Nexus and how to deploy your artifacts to Sonatype OSS Nexus.

If you have not visited the Sonatype OSS Nexus webpage and created an account, do so now.

The %HOME%\.m2\settings.xml file is a standard Maven configuration file and is where we will be starting the Maven configuration.

<server> my-snapshots

This server configures the username and password used by Maven to connect to the repository to which your SNAPSHOT artifacts will be deployed. NOTE – The URL of the snapshot repository is not defined here! It will be defined later in your project's pom.xml.

   
<!-- settings.xml -->
<server>
<id>my-snapshots</id>
<username>[YOUR_OSS_REPO_USERNAME]</username>
<password>[YOUR_OSS_REPO_PASSWORD]</password>
</server>

<server> my-staging

This server configures the username and password used by Maven to connect to the repository to which your RELEASE artifacts will be deployed. NOTE – The URL of the release repository is not defined here! It will be defined later in your project's pom.xml.

OSS Nexus does not allow direct deployment into its public "Releases" repository. OSS Nexus is configured to deploy your artifacts to your staging repository first. After your artifacts are staged, you need to login to the OSS Nexus website to manually promote them to the public "Releases" repository. This staging allows you time to check the staged artifacts are correct before putting them into the public "Releases" repository. Once in the public "Releases" repository you cannot change them.

   
<!-- settings.xml -->
<server>
<id>my-staging</id>
<username>[YOUR_OSS_REPO_USERNAME]</username>
<password>[YOUR_OSS_REPO_PASSWORD]</password>
</server>

<repository> oss-public

This repository defines the OSS Nexus public "Releases" repository. Once your artifacts are promoted from your staging repository, they are publically available from this repository.

NOTE – This is put into a <profile>.

   
<!-- settings.xml -->
<repository>
<id>oss-public</id>
<url>
http://oss.sonatype.org/content/groups/public
</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>

<repository> oss-staging

This repository defines the OSS Nexus staging repository. Because your artifacts are staged first before they are put into the public "Releases" repository, this repository configuration allows Maven to resolve dependencies which you have staged but not promoted to the public "Releases" repository.

NOTE – This is put into a <profile>.

  
<!-- settings.xml -->
<repository>
<id>oss-staging</id>
<url>
http://oss.sonatype.org/content/groups/staging
</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>

<repository> oss-snapshots

This repository defines the OSS Nexus snapshot repository. If you are working on a project with multiple developers, this repository allows the team to resolve dependencies on the latest snapshots. Snapshots do not go into staging first. Snapshot cannot be promoted into the OSS Nexus public "Releases" repository.

NOTE – This is put into a <profile>.

  
<!-- settings.xml -->
<repository>
<id>oss-snapshots</id>
<url>
http://oss.sonatype.org/content/repositories/snapshots
</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>

Configure Eclipse

There are two parts of Eclipse to configure. The first is the Eclipse connection to your SourceForge.net CVS repository. The second is the Maven Indexes of the M2Eclipse plug-in.

M2Eclipse Plug-in

If you have not installed the M2Eclipse plug-in, do so now. When we edited the Maven settings.xml file, we did so to enable Maven to resolve dependencies deployed in the OSS Nexus repository. We now need to do a similar configuration for the M2Eclipse plug-in. If you right-click on a Maven project and select "Add Dependencies", the artifact search feature of M2Eclipse can only find artifacts in the repositories listed in the "Maven Indexes" view. In order to find your artifacts in the OSS Nexus repository, open the "Maven Indexes" view and add the three repositories shown in figure 13.

  • http://oss.sonatype.org/content/groups/public
  • http://oss.sonatype.org/content/repositories/snapshots
  • http://oss.sonatype.org/content/groups/staging

Figure 13
Figure 13

CVS Repositories

By default, Eclipse comes with the "CVS Repositories" view so there is no need to install it. Open the "CVS Repositories" view. We need to add your SourceForge.net CVS repository to the list.

NOTE - Even if you already have your repository configured you will need to remove it and add it again! The reason why will be given later.

To configure your SourceForge.net CVS repository, follow these steps (see figure 14)

  1. Enter your Host, Repository Path, and User
  2. Set the "Connection type:" dropdown box to be "ext" (see figure 14). It is very important to set the value to "ext".
  3. DO NOT click the "Finish" button yet!

Figure 14
Figure 14

By setting the connection type to "ext", the CVS connection string will attempt to use some kind of external means to establish a connection to the CVS repository. In a command-line Linux environment, this external means is usually ssh to provide a secure connection to the CVS repository. To configure what "ext" means inside Eclipse, follow these steps:

  1. Click on the "Configure connection preferences..." hyperlink (see figure 15)
  2. Select the "Use another connection method type to connect" radio button (see figure 16).
  3. Select "extssh" from the "Connection type" dropdown box (see figure 16). This configuration tells Eclipse it should treat the "ext" connection type as its internal "extssh" connection type.
  4. Click the "OK" buttons until all the windows are closed.

Figure 15
Figure 15

Figure 16
Figure 16

After all the windows are closed, the connection to your SourceForge.net CVS repository has been configured within Eclipse. Although you configured the connection type as "ext", Eclipse will treat it as its internal "extssh" connection type.

Test the connection by getting the list of directories in your SourceForge.net CVS repository. Eclipse will prompt you for a password. Eclipse will then use its internal ssh implementation to connect. When you check out a module (and this is the important part), the hidden CVS/Root file will have "ext" as its connection type (see figure 17). This is vital for getting the maven-release-plugin to work.

Figure 17
Figure 17

Checkout your project

It is now time to check out your project from your SourceForge.net CVS repository.

NOTE – If you already have your project checked out you need to delete it and check it out again using the Eclipse CVS Repository configured with the "ext" extension. If you do not do this, then the maven-release-plugin will not work.

Configure your project

Assuming you have checked out a Maven project from your SourceForge.net CVS repository, it is now time for the final configuration – configuring your project's pom.xml.

<scm>

The <scm> tags hold information so Maven knows about the CVS repository the project came from. You will need to configure the <scm> tag with information about your SourceForge.net CVS repository.

This information must go into each project's pom.xml. If your development group has a parent POM project, the <scm> information must still go into each project's pom.xml because the information is unique to each project.

The <scm> configuration has a number of child tags Make sure you have all the ":", "@", "."and "/" characters in the right place!. The child tags will be explained following this example:

  
<!-- pom.xml -->
<project...>
...
<scm>
<connection>
scm:cvs:pserver:anonymous@[YOUR_SOURCEFORGE_PROJECT_NAME].cvs.sourceforge.net:/cvsroot/[YOUR_SOURCEFORGE_PROJECT_NAME]:[DIRECTORY_IN_YOUR_CVS_REPOSITORY]
</connection>
<tag></tag>
<developerConnection>
scm:cvs:ext: [YOUR_SOURCEFORGE_USERNAME]@[YOUR_SOURCEFORGE_PROJECT_NAME].cvs.sourceforge.net:/cvsroot/[YOUR_SOURCEFORGE_PROJECT_NAME]:[DIRECTORY_IN_YOUR_CVS_REPOSITORY]
</developerConnection>
<url>
[URL_TO_YOUR_PROJECT'S_HOMEPAGE]
</url>
</scm>
</project>

<connection>

This tag is configured for anonymous pserver (non-ssh) access to a module in your SourceForge.net CVS repository.

<tag>

This tag is used by the maven-release-plugin. You do not have to worry about it right now.

<developerConnection>

This tag is configured for your developer ext (ssh) access to a module in your SourceForge.net CVS repository.

<url>

This tag is the URL to your project's homepage.

<distributionManagement>

The <distributionManagement> tag holds a lot of different information. In our case we want to configure a <repository> and a <snapshotRepository>. Remember back when the settings.xml file was configured with the username and password needed to deploy artifacts to the OSS Nexus repository? Remember the URL to the repository was not configured in settings.xml? The answer to where the URL to the repository is configured is pom.xml. If your development team has a parent POM, this configuration can go in the parent POM.

An explanation of <repository> and <snapshotRepository> follow this example:

<!-- pom.xml -->
<project...>
...
<distributionManagement>
...
<repository>
<id>my-staging</id>
<name>my-staging</name>
<url>
http://oss.sonatype.org/service/local/staging/deploy/maven2
</url>
</repository>

<snapshotRepository>
<id>my-snapshots</id>
<name>my-snapshots</name>
<url>
http://oss.sonatype.org/content/repositories/snapshots
</url>
</snapshotRepository>
</distributionManagement>
</project>

<repository>

This tag defines the location of your OSS Nexus staging repository. When you execute "mvn deploy", your RELEASE artifacts will be staged to this repository. After your artifacts are staged, you need to login to the OSS Nexus website to manually promote them to the public "Releases" repository.

The <id> values from settings.xml and pom.xml MUST MATCH!

<!—
| In the settings.xml file of %HOME%\.m2\
-->
<server>
...
<id>my-staging</id>
</ server >

<!—
| In the pom.xml file of your project!
-->
<repository>
...
<id>my-staging</id>
</repository>

If the <id> values do not match, Maven will be unable to find the correct username and password to connect to this repository.

<snapshotRepository>

This tag defines the location of the OSS Nexus snapshot repository. When you execute "mvn deploy", your SNAPSHOT artifacts will be staged to this repository.

The <id> values from settings.xml and pom.xml MUST MATCH!

<!—
| In the settings.xml file of %HOME%\.m2\
-->
<server>
...
<id>my-snapshots</id>
</ server >

<!—
| In the pom.xml file of your project!
-->
<snapshotRepository>
...
<id>my-snapshots</id>
</snapshotRepository>

If the <id> values do not match, Maven will be unable to find the correct username and password to connect to this repository.

Review

Before continuing, let us review what has been done so far.

  1. Downloaded and configured CVSNT
  2. Downloaded and used puttygen.exe to generate a public/private key and set the public key in your SourceForge.net account.
  3. Downloaded and configured plink.exe to allow cvs.exe to connect to your SourceForge.net CVS repository using SSL.
  4. Configured Maven for the Sonatype OSS Nexus repository.
  5. Configured Eclipse's m2eclipse for the Sonatype OSS Nexus repository.
  6. Configured Eclipse's CVS Repository for your SourceForge.net CVS repository
  7. Configured your project's pom.xml for both your SourceForge.net CVS repository and the OSS Nexus repository.

Run maven-release-plugin

It is finally time to run the maven-release-plugin!

Our goal is to have the maven-release-plugin automate the deployment of a new version of your project to your OSS Nexus staging repository.

To prepare for the release, follow these steps:

  1. Edit your project's pom.xml file so the version ends with "-SNAPSHOT". If you do not do this the maven-release-plugin will complain.
  2. Commit the changes to the pom.xml file to CVS. If you do not do this the maven-release-plugin will complain.
  3. Open a new Command Prompt (DOS Prompt)
  4. Change to your project's directory.
  5. Execute the following command:
    C:\>mvn -Dmaven.scm.provider.cvs.implementation=cvs_native release:prepare

If all goes well, you will first be prompted for what version this release will be. The maven-release-plugin removes the "-SNAPSHOT" from your pom's <version> tag and assumes it is the next version. If it is, just press enter. If not type in the correct value for the next version then press enter (see figure 18).

Figure 18
Figure 18

Next, the maven-release-plugin will ask you for the name it will use to tag this version in CVS. Again, the maven-release-plugin makes an intelligent guess for its value. If it is correct just press enter. If not type in the correct value for the CVS tag then press enter (see figure 19).

Figure 19
Figure 19

Finally, the maven-release-plugin will ask you for the name of the new SNAPSHOT version. Again, the maven-release-plugin makes an intelligent guess for its value. If it is correct just press enter. If not type in the correct value for the next SNAPSHOT version then press enter (see figure 20).

Figure 20
Figure 20

If all goes well, you will get the wonderful Maven build successful message:

[INFO] --------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] --------------------------------------------------------------

. . .BUT YOU ARE NOT DONE YET!

You have successfully prepared for the release. To perform the release and get your project's artifact deployed to your OSS Nexus staging repository, execute the following command:

C:\>mvn -Dmaven.scm.provider.cvs.implementation=cvs_native release:perform

If this is successful and you get another. . .

[INFO] --------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] --------------------------------------------------------------

. . .congratulations! You have successfully configured all the technologies which the maven-release-plugin needs to work with a regular Maven repository and with a CVS repository requiring an SSL connection.

Promote Artifacts from Staging

Since running the maven-release-plugin was successful, your project's RELEASE artifacts are waiting in your OSS Nexus staging repository.

You now need to login to your OSS Nexus Repository, verify your artifacts are properly staged, and finally promote the artifacts to the OSS Nexus "Releases" repository. Optionally, your artifacts will be promoted to the Maven main repo (http://repo1.maven.org/maven2) if your account is configured to promote there.

To verify your artifacts are properly staged, follow these steps (see figure 21):

  1. Open a browser to the Sonatype OSS Nexus repository (http://oss.sonatype.org)
  2. Log in
  3. Click the "Staging" hyperlink
  4. Click on your staging repository
  5. Click on what has been staged
  6. Expand the tree and see your artifacts ready for promotion

Figure 21
Figure 21

Verify all the artifacts for your release are properly staged. Once verified, continue to the final step, promotion.

To promote your artifacts from staging into the OSS Nexus "Releases" repository, follow these steps:

  1. Right-click what has been staged (see figure 22)
  2. Select "close"
  3. Enter a description
  4. Right-click (again) what has been staged (see figure 23)
  5. Select "promote"
  6. Enter a description

NOTE - At any point you can select "Drop" instead to remove it from staging. Re-run the maven-release-plugin to try again.

Figure 22
Figure 22

Figure 23
Figure 23

Congratulations! Your artifacts are now in the OSS Nexus "Releases" repository.

Troubleshooting

If everything was not successful there is a lot that could have gone wrong. This is a complex configuration and I cannot cover even a fraction of what might go wrong. Here are some tips:

  1. Make sure you follow each step of this document from top to bottom. Do not continue to the next step if you are not successful at the one you are on.
  2. I had a positive experience with descriptive error messages and finding solutions for them online. If you get stuck, search for the solution.
  3. The maven-release-plugin has 2 goals I did not cover. Make sure you read about these.
    • release:clean
    • release:rollback
  4. Have patience. It might be difficult to get working but the effort is rewarded with the ease coming from automating the complex release process.
Published at DZone with permission of its author, Michael Remijan.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Michael Remijan replied on Thu, 2010/05/06 - 3:29pm

Added profile picture

Jilles Van Gurp replied on Thu, 2010/05/20 - 1:19pm

I've had mixed experiences with the release plugin. When it works it is ok-ish but most of the time I've used it, I've found myself rolling back multiple times and on several occasions just doing things manually because it just couldn't handle the simple job of tag and deploy to nexus.

There are a few things that I think are really bad design decisions:

1) Release prepare actually commits on your svn. This is counter intuitive.  A prepare step should not permanently change anything, especially not in the holiest of holy: the version repository. I would expect this to be part of the perform operation. Technically perform just does an export tag + site-deploy. That's easy and you can do it again if it fails. Having to go in and delete tags is just bad. Prepare does all the relevant work.

2) It ignores -Dmaven.test.skip=true. You can't believe how annoying it is to watch surefire do it's thing for the 12th time in a row when all you wanted is just get the damn tag + deploy over with and you know 100% sure that it will be saying "build successful" in about 5 minutes . Any responsible release manager won't even go near mvn release:prepare before the CI builds are all in the green. So it is a completely redundant thing to run the tests to begin with. I agree it should by default do the right thing. But don't get completely ANAL about not letting me skip the formality of running our tests. I've on multiple occasions had to release manually due to some stupid build funkiness (completely unrelated to code quality). The maven release plugin is just a major PITA when you need to do this.

3) release:perform can still fail leaving you with a build problem mvn release:prepare failed to detect and a already tagged release. That's just nasty. I've on multiple occasions had to pollute my svn repo with svn delete <tagurl>. 

What it boils down to is that I only need the release plugin to do 1 thing: support me in changing the version in all my poms. I can test, tag, export, deploy, etc. myself just fine. Tagging support is nice of course but not really essential. It's having to open all those pom files and having to edit the version in a dozen places that is the real issue. And that is a design problem with the way maven pom files. The maven release plugin is just a really annoying workaround. In short the only reason this plugin is needed to begin with is the way maven does versioning in multi module projects. 

A properly designed release plugin should work like this:

1) ask for versions of tag and next snapshot

2) change the pom files to reflect versions in the tag

3) clean install (with option to skip) (you want to know this still works with the tag version)

4) run deploy and site-deploy with a --dry-run type flag that generates all the artifacts but does not upload them to nexus yet.

5) commit pom files with the tag version

6) svn tag

7) now upload the artifacts generated under 4

8) change the pom files to reflect next snapshot version

9) commit

Why is this better? Nothing gets committed until it has been verified that all the relevant artifacts can be generated. No damage is done in either svn or nexus until this moment. Barring easy to fix configuration issues, nothing can go wrong after step 4. Step 1-4 is what I would expect to happen during a release:prepare. Nothing happens there that can't be undone. Arguably step 3 and 4 could be combined to save some time.

Fabrizio Giudici replied on Fri, 2010/05/21 - 5:10am

"Release prepare actually commits on your svn."

You're right, it's annoying and indeed a logic flaw. With Mercurial (or other distributed systems) I've found a way to fool it so it does a push to a local repository, which I later sync to the real one only if I decide to "approve" the release. With this schema, In the same way, I make Maven to publish artifacts to a local repository, so I can get to a "real" release that it's still on my computer. If everything is ok, I can later push all the stuff (source changes and artifacts) to the network.

See http://weblogs.java.net/blog/fabriziogiudici/archive/2009/10/29/fixing-two-problems-maven-mercurial-hudson
    
"It ignores -Dmaven.test.skip=true"

I think you just need to put that in the configuration of the maven-release-plugin:

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-release-plugin</artifactId>
                <configuration>
                    <preparationGoals>clean install verify</preparationGoals>
                    <goals>clean install javadoc:javadoc assembly:assembly deploy</goals>
                    <arguments>-Dstuff_goes_here</arguments>
                </configuration>
            </plugin>

That's why the release plugin is just forking another Maven process, but with the above stuff you can configure the forked thing.

Mladen Girazovski replied on Fri, 2010/05/21 - 6:30am

You could set the preparationGoals from the commandline as well, btw. i think the reason why maven is doing first a commit on the SCM and after that the deploy on the artifact repo is simple, it easier to remove an unwanted tag from the SCM, compared with removing a deployed artifact from an artifact repo(think about any other devloper pulling a broken version of the artifact and copying it into their lokal repo, not to mention downstream artifact repos).

Steven Baker replied on Sat, 2010/05/22 - 11:57am

release:prepare is about as far as i would go with it.... unless it was for a project in oss/central mvn repo.

 

also, release:rollback has a very big bug... that it cannot remove the tag from svn

Vineet Manohar replied on Sat, 2010/05/22 - 3:05pm

Good comprehensive article.

You can also run both maven prepare and perform in a single line in the batch mode - accepting all default options. You can use this option to do a night release without any manual intervention. See this post for more details:

http://www.vineetmanohar.com/2009/10/how-to-automate-project-versioning-and-release-with-maven/

Fabrizio Giudici replied on Sat, 2010/05/22 - 4:19pm

BTW, guys, do you know whether it's possible, by configuration or command line, to avoid that Maven prepends the project name in the SCM tag? I get stuff such as foo-1.2.3, while I'd like to have 1.2.3 alone.

Thanks.

Michael Remijan replied on Fri, 2011/09/16 - 9:25am

I've just read about a small tip.  Download WinCVS and use the cvs.exe which comes with that project.  That way you'll annoy the annoying dialog box which pops up when using the other cvs.exe.

G Sekar replied on Tue, 2012/06/26 - 8:58am

 

Hi Michael,

Could you please share the document if you have similaer document to configure maven release plugin with  jenkins++SVN to automate the release process. 

Thanks in advance

 

 

 


 

Vijay Doddala replied on Mon, 2014/03/03 - 8:34am in response to: Jilles Van Gurp

 Hi,

I am trying to configure Maven Release plugin in Jenkins job. I am getting authentication exception. For invoking maven release plugin do we need to have svn client from where we are invoking the release? The requirement is as follows:
My requirement is to configure maven release plugin as follows:
1. My current version is at 1.0.0-SNAPSHOT and once testing is done and ready for movement to production the maven release plugin will be invoked from Jenkins job to move the code from branch to trunk.
2. The configuration has to check out the source from branch, update all the POMs to version 1.0.0, tag the source code and check in the code at trunk location. The tags folder will contain the tagged version at 1.0.0 (as best practice we need to change the version from 1.0.0-SNAPSHOT to 1.0.0 once the product is ready for production, right? or while moving to UAT itself it should be done?).
3. Also, the next snapshot version will be updated to 1.0.1-SNAPSHOT(which is configurable in release plugin) and checked in at branch level for the next development.
I am able to configure this, but somehow it is not working. I am getting authentication exception.
svn: Authentication required for '<https://server-mydomain.com:443>'.

We are using Jenkins, maven, artifactory, SCM as tools.

The questions that I have are:
1. Do we need to use any certificate for https protocol communication with SCM?
2. How to send credentials to release plugin?

Also, pls share screenshots if you have any for configuring this. I can send you my configuration files and jenkins screenshots if you can share your id. I tried both Maven Release Plugin and M2Release plugin but no luck. I need your help as I am completely struck with this and this has been a blocker for me and stopping to move ahead.

Below is the log in Jenkins:

Building in workspace D:\Softwares\jenkins\jobs\Perf

orm_Release\workspace
Updating https://server-mydomain.com/svn/New_FW/CI_POC/branches/CI_POC_Release01/SpringMVC323REST_NEW at revision '2014-02-11T19:15:39.301 +0530'
At revision 547
no change for https://server-mydomain.com/svn/New_FW/CI_POC/branches/CI_POC_Release01/SpringMVC323REST_NEW since the previous build
Parsing POMs
[workspace] $ "C:\Program Files\Java\jdk1.6.0_24/bin/java" -cp D:\Softwares\jenkins\plugins\maven-plugin\WEB-INF\lib\maven31-agent-1.4.jar;D:\Softwares\apache-maven-3.1.0\boot\plexus-classworlds-2.4.2.jar;D:\Softwares\apache-maven-3.1.0/conf/logging jenkins.maven3.agent.Maven31Main D:\Softwares\apache-maven-3.1.0 D:\Softwares\jboss-5.0.1.GA\server\default\deploy\jenkins.war\WEB-INF\lib\remoting-2.33.jar D:\Softwares\jenkins\plugins\maven-plugin\WEB-INF\lib\maven31-interceptor-1.4.jar D:\Softwares\jenkins\plugins\maven-plugin\WEB-INF\lib\maven3-interceptor-commons-1.4.jar 56824
<===[JENKINS REMOTING CAPACITY]===>channel started
Executing Maven:  -B -f D:\Softwares\jenkins\jobs\Perform_Release\workspace\pom.xml -DdevelopmentVersion=1.0.1-SNAPSHOT -DreleaseVersion=1.0.0 -X -Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true -Dresume=false -DdryRun=true release:prepare
Apache Maven 3.1.0 (893ca28a1da9d5f51ac03827af98bb730128f9f2; 2013-06-28 07:45:32+0530)
Maven home: D:\Softwares\apache-maven-3.1.0
Java version: 1.6.0_24, vendor: Sun Microsystems Inc.
Java home: C:\Program Files\Java\jdk1.6.0_24\jre
Default locale: en_US, platform encoding: Cp1252
OS name: "windows nt (unknown)", version: "6.2", arch: "amd64", family: "windows"
[INFO] Error stacktraces are turned on.
[DEBUG] Reading global settings from D:\Softwares\apache-maven-3.1.0\conf\settings.xml
[DEBUG] Reading user settings from C:\Users\doddalav\.m2\settings.xml
[INFO] Scanning for projects...
[WARNING]
[WARNING] Some problems were encountered while building the effective model for com.mydomain.simple:ServiceEJB:jar:1.0.0-SNAPSHOT
[WARNING] 'build.plugins.plugin.version' for org.apache.maven.plugins:maven-ejb-plugin is missing. @ line 24, column 12
[WARNING]
[WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.
[WARNING]
[WARNING] For this reason, future Maven versions might no longer support building such malformed projects.
[WARNING]
[HUDSON] Collecting dependencies info[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] Service
[INFO] ServiceEJB
[INFO] SpringMVC323REST

[HUDSON] Collecting dependencies info
[HUDSON] Collecting dependencies info
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Service 1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-release-plugin:2.4.2:prepare (default-cli) @ Service ---
[INFO] Change the default 'svn' provider implementation to 'javasvn'.
[INFO] Verifying that there are no local modifications...
[INFO]   ignoring changes on: **\release.properties, **\pom.xml.next, **\pom.xml.releaseBackup, **\pom.xml.backup, **\pom.xml.branch, **\pom.xml.tag
[INFO] SVN status directory: D:\Softwares\jenkins\jobs\Perform_Release\workspace
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] Service ........................................... FAILURE [21.763s]
[INFO] ServiceEJB ........................................ SKIPPED
[INFO] SpringMVC323REST .................................. SKIPPED
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 28.550s
[INFO] Finished at: Tue Feb 11 19:16:55 IST 2014
[INFO] Final Memory: 8M/63M
[INFO] ------------------------------------------------------------------------
Waiting for Jenkins to finish collecting data
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-release-plugin:2.4.2:prepare (default-cli) on project Service: Unable to check for local modifications
[ERROR] Provider message:
[ERROR] SVN status failed.
[ERROR] Command output:
[ERROR] svn: Authentication required for '<https://server-mydomain.com:443>'
[ERROR] -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-release-plugin:2.4.2:prepare (default-cli) on project Service: Unable to check for local modifications
Provider message:
SVN status failed.
Command output:
svn: Authentication required for '<https://server-mydomain.com:443>'
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:212)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
        at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
        at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:318)
        at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:153)
        at org.jvnet.hudson.maven3.launcher.Maven31Launcher.main(Maven31Launcher.java:132)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launchStandard(Launcher.java:331)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:239)
        at jenkins.maven3.agent.Maven31Main.launch(Maven31Main.java:181)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at hudson.maven.Maven3Builder.call(Maven3Builder.java:134)
        at hudson.maven.Maven3Builder.call(Maven3Builder.java:69)
        at hudson.remoting.UserRequest.perform(UserRequest.java:118)
        at hudson.remoting.UserRequest.perform(UserRequest.java:48)
        at hudson.remoting.Request$2.run(Request.java:328)
        at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:72)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
        at java.util.concurrent.FutureTask.run(FutureTask.java:138)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:662)
Caused by: org.apache.maven.plugin.MojoFailureException: Unable to check for local modifications
Provider message:
SVN status failed.
Command output:
svn: Authentication required for '<https://server-mydomain.com:443>'
        at org.apache.maven.plugins.release.PrepareReleaseMojo.prepareRelease(PrepareReleaseMojo.java:285)
        at org.apache.maven.plugins.release.PrepareReleaseMojo.execute(PrepareReleaseMojo.java:232)
        at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:106)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
        ... 31 more
Caused by: org.apache.maven.shared.release.scm.ReleaseScmCommandException: Unable to check for local modifications
Provider message:
SVN status failed.
Command output:
svn: Authentication required for '<https://server-mydomain.com:443>'
        at org.apache.maven.shared.release.phase.ScmCheckModificationsPhase.execute(ScmCheckModificationsPhase.java:137)
        at org.apache.maven.shared.release.phase.ScmCheckModificationsPhase.simulate(ScmCheckModificationsPhase.java:200)
        at org.apache.maven.shared.release.DefaultReleaseManager.prepare(DefaultReleaseManager.java:228)
        at org.apache.maven.shared.release.DefaultReleaseManager.prepare(DefaultReleaseManager.java:169)
        at org.apache.maven.shared.release.DefaultReleaseManager.prepare(DefaultReleaseManager.java:146)
        at org.apache.maven.shared.release.DefaultReleaseManager.prepare(DefaultReleaseManager.java:107)
        at org.apache.maven.plugins.release.PrepareReleaseMojo.prepareRelease(PrepareReleaseMojo.java:277)
        ... 34 more
[ERROR]

Thank You,
Vijay

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.