16

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:

  • When I use an existing POM and build and deploy it through Jenkins, it is automatically deployed to our old environment.
  • I have then tried to define the deploymentManagement section in my .settings file in Maven, but this is not allowed (see Configuring Maven, there

    Note: the installation and user configuration cannot be used to add shared project information - for example, setting or company-wide.

  • I could of course copy the whole, and change the distributionManagement inside each POM, but I would like to use the same (not a copied) example in different installations.

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.

Community
  • 1
  • 1
mliebelt
  • 15,345
  • 7
  • 55
  • 92
  • "When I use an existing POM and build and deploy it through Jenkins, it is automatically deployed to our old environment." - why? do you have the old env defined in all poms? or in one shared parent pom? where is it? – eis May 02 '13 at 14:30
  • I have added a section to the section of the POM I want to override. – mliebelt May 02 '13 at 14:50
  • ok. one additional question: why would you need to modify a lot of poms just for this purpose, if you go with the profiles approach? afaik only thing you need to change is the root pom, references to its version and then just run the build with a different profile? – eis May 02 '13 at 15:58
  • I do understand that. But adding the stuff to the root POM (and delivering it in the future) polutes it (kind of), because I am the only one that need that variation. And if I do that only for a new version (not publicly deployed), I have at least to update all other POMs that depend on this. – mliebelt May 02 '13 at 16:16

1 Answers1

24

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>

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.

Raedwald
  • 46,613
  • 43
  • 151
  • 237
user944849
  • 14,524
  • 2
  • 61
  • 83
  • Great answer, I will give it a try and will return with some feedback. – mliebelt May 03 '13 at 06:02
  • I have checked it now, and even provided a version, where one part of the profile is in the root pom, and the URLs (and passwords) are contained in the installation or user settings. So there is one switch, and the concrete POMs don't have to have that information, too. The switch `-P test-repo` does all the magic then. – mliebelt May 03 '13 at 14:05