This document describes how to publish Maven artifacts at Apache. We use an instance of Nexus Pro at http://repository.apache.org to maintain our Maven repository. This instance is configured to ensure that artifacts meet both the Apache Release requirements (FAQ) as well as the Central Repository requirements.

Note that this document describes how to release Maven artifacts. These are optional.

All Apache releases MUST be released via the ASF mirror system.

Important: It is recommended that those using Apache Maven version 2.2.0 upgrade immediately and do not try and publish using this older version. See Apache Maven 2.2.1 release notes for a list of issues fixed and then go ahead and download Apache Maven 2.2.1 or later before proceeding further into this document.

Contents

Getting your project setup in the Nexus Repository

The repository enforces security by constraining who can deploy or release a project's artifacts. This is done by mapping which artifacts (usually by GroupId) are produced by an Apache project. This is particularly helpful in preventing accidental releases of a project

Before a project can use the repository to release Maven artifacts, it must be configured in Nexus. This is generally a quick and easy process. To get setup, create a JIRA ticket here with the following information:

  • Project URL: a link to your project page.

  • SVN URL: where the source is located in case we need to lookup more information and to provide feedback on your pom.

  • Maven Group Ids: a list of the groupIds for this project. They should all be subgroups of org.apache

  • Managed By This TLP Project: if this is a subproject, list the TLP that is responsible. Subprojects usually don't have their own LDAP group, so we need the TLP LDAP group for permissions. Once this JIRA is filed, the following will happen:

  • Setup the project in Nexus: We will configure your groupIds in Nexus and link them to the appropriate LDAP group for Authorization

  • Move Existing Artifacts: In order to maintain the proper maven-metadata.xml files and to prevent rsync conflicts in Central, we must move all your artifacts to the new repository. We will move your artifacts from the old repository on people to the new repository and mark the folder in people as read-only to prevent accidental deployments.

  • Check POMs: We will quickly check your POM (if your project is Maven based) for any obvious problems. If you have specific questions or concerns, please call them out in the issue.

Maven Specific Preparations and procedures

Other informations can be found here http://maven.apache.org/pom/asf/

The following information pertains to projects that build with Maven.

Adjusting your build to use the repository

Inherit the Apache POM

Inherit the Apache Parent POM like this: (it's a good idea to check you are using the latest version )

<parent>
  <groupId>org.apache</groupId>
  <artifactId>apache</artifactId>
  <version>10</version>
</parent>
This parent POM sets up the defaults for your <distributionManagement> section to use the correct release and snapshot repositories. Be sure to remove those from your POM so they inherit correctly. You will need to keep the entry for deploying your site (if you use Maven to deploy your site). If you do, we suggest you use apache.website as the id to better match the settings below and to save the sanity of committers working on multiple projects.

The POM also provides a default configuration that will ensure that a correct source archive is created for your project. Note: This is separate and in addition to the typical -sources.jar that are created.

Setup your development environment



All artifacts must be signed with a key that is publicly verifiable. Follow the instructions here to get your keys created and environment setup.
Use the following block as a template and place it in ~/.m2/settings.xml

Note: It is highly recommended to use Maven's password encryption capabilities for your passwords.
Also there should be no need to store your signing key in settings.xml (i.e. please don't!).
The gpg plugin can either prompt for the key (input is masked) or you can configure it to use an agent.

<settings>
...
  <servers>
    <!-- To publish a snapshot of some part of Maven -->
    <server>
      <id>apache.snapshots.https</id>
      <username> <!-- YOUR APACHE LDAP USERNAME --> </username>
      <password> <!-- YOUR APACHE LDAP PASSWORD (encrypted) --> </password>
    </server>
    <!-- To stage a release of some part of Maven -->
    <server>
      <id>apache.releases.https</id>
      <username> <!-- YOUR APACHE LDAP USERNAME --> </username>
      <password> <!-- YOUR APACHE LDAP PASSWORD (encrypted) --> </password>
    </server>
   ...
  </servers>
</settings>

Test your settings

Try installing locally artifacts with activation apache-release profile.

mvn clean install -Papache-release (this will build artifacts, sources and sign)

Staging a release

1 - Prepare your POMs for release

  1. Make sure there are no dependencies on snapshots in the POMs to be released. However, the project you want to stage must be a SNAPSHOT version.

  2. Check that your POMs will not lose content when they are rewritten during the release process:

  3. Verify that all pom.xml files have an SCM definition.

  4. Do a dryRun release: mvn release:prepare -DdryRun=true p.s. you may also wish to pass -DautoVersionSubmodules=true as this will save you time if your project is multi-moduled.

  5. Diff the original file pom.xml with the one called pom.xml.tag to see if the license or any other info has been removed. This has been known to happen if the starting <project> tag is not on a single line. The only things that should be different between these files are the <version> and <scm> elements. Any other changes you must backport yourself to the original pom.xml file and commit before proceeding with the release.

2 - Publish a snapshot

mvn deploy
...
[INFO] [deploy:deploy]
[INFO] Retrieving previous build number from apache.snapshots.https
...
If you experience an error during deployment like a HTTP 401 check your settings for the required server entries as outlined in the Maven Settings section above.

Note: Be sure that the generated artifacts respect the Apache release rules : NOTICE and LICENSE files should be present in the META-INF directory within the jar. For -sources artifacts, be sure that your POM does not use the maven-source-plugin:2.0.3 which is broken.

Note: You should verify the deployment under the Maven Snapshot repository at Apache.

3 - Prepare the release

mvn release:clean
mvn release:prepare
Note: Preparing the release will create the new tag in SVN, automatically checking in on your behalf.

Note: If you're located in Europe then release:prepare may fail with 'Unable to tag SCM' and ' svn: No such revision X '. Wait 10 seconds and run mvn release:prepare again.

4 - Stage the release for a vote

mvn release:perform
The release will automatically be inserted into a temporary staging repository for you. See the Nexus staging documentation for full details.

Now you must close the staging repository to indicate to Nexus that the build is done and to make the artifacts available. Follow the steps in Closing the Staged Repository to close your new repository, this will allow your community to VOTE on the staged atrifacts.

Troubleshooting

If you get an error message similar to:
[INFO] Unable to tag SCM
Provider message:
The svn tag command failed.
Command output:
svn: Commit failed (details follow):
svn: File
'/repos/asf/maven/plugins/tags/maven-eclipse-plugin-2.7/.../EclipsePlugin.java'
already exists
Then the resolution is to use a Subversion client 1.6+ and to run svn update.

If you get an error message similar to:

[ERROR] BUILD FAILURE
[INFO]


[INFO] Unable to tag SCM Provider message: The svn tag command failed. Command output: svn: Path 'https://svn.apache.org/repos/asf/maven/plugins/tags/maven-eclipse-plugin-2.7' already exists

Then the resolution is to delete the tag using:
svn del -m "re-releasing build" {svn path}
This likely occured because you're trying to restage the release and you didn't rollback the changes that created the previous tag. Either that or you're trying to release a version that already exists, in which case you need to adjust the versions in your POM and start over.

Ant + Ivy specific Preparations and procedures

Prepare your build

Usually your normal build process will already create the artifacts you want to publish (typically jars) but you may need to PGP-sign them the same way you sign your normal distribution artifacts. The jars are expected to follow the naming scheme artifactId - version.jar.

In addition you will need a minimal POM for your jar. If you are already using Ivy, you can use the makepom task to create one from your ivy.xml , otherwise see the Apache Maven project's documentation for "minimal" and the Apache Compress Antlib's POM for an example. If you are publishing multiple jars you may consider adding a parent POM to encapsulate the common information; see the Maven documentation, an example might be Ant's parent POM used for the several jars that make up an Ant release.

Users that use your project's jars from the Maven repository rather than using your "normal" distributions will likely want additional artifacts containing the source files or javadocs matching your jars in files named artifactId - version -sources.jar and artifactId - version -javadoc.jar respectively. Don't forget to sign those jars as well if you provide them.

Create Minimal Ivy Files for your Project

If you are not already using Ivy in your project you'll need to create a minimal ivy.xml file for your project. The syntax is described in Ivy's documentation. Since you will only use it to publish your artifacts, all you need to provide are the organization , module and revision definitions and an entry for each artifact you want to publish; see Ant's ivy.xml for a minimal version.

organization and module combined must match your Maven groupId.

You will need artifact elements for your jar as well as the POM and any PGP signature file. You don't need artifacts for your checksum files (if you create any) since Nexus will create MD5 and SHA1 checksums on the fly anyway.

If you are publishing source or javadoc jars as well, you'll need to provide something similar to Maven's classifier. You do so by adding an extra attribute to each artifact element that lives outside of Ivy's XML namespace and referencing this element in your ivysettings.xml file (see below). An example which uses this approach is the Compress Antlib's ivy.xml. It contains additional information and -sources as well as -javadoc artifacts.

Alternatively you can specify the -sources and -javadoc artifacts inside your publish task rather than your ivy.xml file. If you use Ivy 2.2.0 or later you can also configure it to PGP-sign you artifacts and no longer need to specify your signatures as artifacts. Ivy's own ivy-settings.xml configures Ivy to sign artifacts and the publish task inside the upload-nexus target declares the POM as well as -sources and -javadoc jars as additional artifacts.

Configure Ivy to Use Nexus

If you are already using Ivy you may need to adapt your resolvers configuration by adding an url resolver for Nexus and referencing that in a module matching your ivy.xml.

In general you'll mostly need to adapt the ivysettings.xml file used by Ant by using the same values for organization and name on the module element that you used in your ivy.xml file (where name on the module element in ivysettings.xml corresponds to module in ivy.xml ).

Ant's ivysettings.xml uses Ant properties for the authentication information and Nexus' URL which will be expanded by the ivy:configure task. It also shows how to use the classifier extra attribute.

Uploading the Artifacts

Uploading involves three Ivy tasks.

  1. ivy:configure uses your ivysettings.xml file to configure Ivy (what else?).

  2. ivy:resolve reads your ivy.xml and doesn't do much beyond that if you are only using Ivy to upload your artifacts.

  3. Finally ivy:publish publishes the artifcats to Nexus.

An example build file combining those steps that expects you to provide the authentication information via the command line (i.e. ant -Dupload.user=YOUR-ASF_ID -Dupload.password=YOUR-PASSWORD ) can be found here: http://svn.apache.org/repos/asf/ant/antlibs/common/trunk/upload.xml.

Common procedures

This section contains information about managing the results of your staged release regardless of the build tool used.

Closing the Staged Repository

Your artifacts should now exist in a new staging repository. See Closing a Staging Repository for instructions on how to "close" this repository to trigger the quality checks and prepare it for the vote.

Now you go call your vote and based on the results you will either promote (yay!) or drop and restage. If you are an incubating project, don't forget the IPMC vote before promoting. The actual Vote process is project specific, but if you're looking for some examples, the Maven project has thorough documentation on their voting process.

Dropping a Repo

So you bungled the release or your vote failed. That's ok, just follow these instructions to drop your repo and it's like it never happened. Don't forget to rollback any SCM changes.

Promoting a Repo

Congratulations, your vote was successful. The last step is to promote the artifacts to the release repository where they will get picked up by Central.