mavendeploymentmaven-3

Setting up Maven to allow deployment to different repositories easily


I'm currently working in an environment where I define the rules for a lot of people. We currently use Hudson and Artifactory, and I want to evaluate if the switch to Jenkins and Nexus are worth the migration cost (but this is not the question).

To eval it, I have setup Maven, Jenkins, and Nexus locally, and I try to find a setup to use as much of the previous setup, so that I can compare the solutions. The problem here is:

Our current root POM contains the following section:

<distributionManagement>
    <repository>
      <uniqueVersion>false</uniqueVersion>
      <id>company-central</id>
      <name>Company central maven respository</name>
      <url>https://company.com/artifactory/libs-releases</url>
    </repository>
    <snapshotRepository>
      <id>company-snaps</id>
      <name>company-snapshots</name>
      <url>https://company.com/artifactory/libs-snapshots</url>
    </snapshotRepository>
    <downloadUrl>https://company.com/artifactory/libs-releases</downloadUrl>
  </distributionManagement>

What is the easiest way to use the same POM, but to deploy it to different repository managers?

PS: I have read set up maven pom file for different deployment scenarios and don't like it (in my context), Deploying Maven artifact to multiple repositories with different settings is really a different question. Multiple deployments in maven is an interesting approach, but I would have to modify a lot of POMs only for this purpose.


Solution

  • I'm on a similar team, providing tools to others. We have our parent POM (not the settings.xml) set up like the below. The prod version is active unless one of my team members adds -DuseTestRepo=true to the mvn command line. You could experiment with changing the activation to look for a particular file that exists only on the Jenkins server (for example). I've also wondered if Maven interpolates properties in repo URLs. If it does, you could do <url>${my.remote.repo}/releases</url> and define my.remote.repo in settings.xml. Haven't tried that one.

    <profiles>
        <profile>
            <id>test-repository</id>
            <activation>
                <property>
                    <name>useTestRepo</name>
                    <value>true</value>
                </property>
            </activation>
            <properties>
            </properties>
            <distributionManagement>
                <repository>
                     <!-- ... -->
                </repository>
                <snapshotRepository>
                     <!-- ... -->
                </snapshotRepository>
            </distributionManagement>
        </profile>
    
        <profile>
            <id>prod-repository</id>
            <activation>
                <property>
                    <name>!useTestRepo</name>
                </property>
            </activation>
            <properties>
            </properties>
            <distributionManagement>
                <repository>
                     <!-- ... -->
                </repository>
                <snapshotRepository>
                     <!-- ... -->
                </snapshotRepository>
            </distributionManagement>
        </profile>
    </profiles>
    

    As to delivering (deploying) your experimental parent POM - you would be deploying it to your test Nexus repo, right? And none of your developers are accessing that, only you. So Artifactory will contain the real com.company:corporate-parent:1.0 POM, and Nexus the com.company:corporate-parent:1.0 that contains the changes you require for your testing.

    I would also consider changing the local repo in your settings.xml so you don't mix artifacts from the two remote repos.