Как я могу развернуть несколько артефактов maven в нескольких репозиториях nexus, включая репозитории моментальных снимков, без необходимости указывать профиль?

У нас есть проект шлюза-клиента, который является частью многомодульного проекта maven. Шлюз-клиент pom.xml настроен на создание двух основных артефактов: gateway-client.jar и gateway-services-client.jar и их развертывание в двух отдельных репозиториях Nexus: репозиторий Releases и сторонний репозиторий соответственно. Делается это через профиль, который активен по умолчанию:

<profile>
    <!-- ====================================================================== -->
    <!-- default Profile -->
    <!-- This is the default profile which will run by default.  This profile -->
    <!-- produces two client artifacts: gateway-client and gateway-services-client -->
    <!-- for the releases and thirdparty repositories respectively. -->
    <!-- ====================================================================== -->
    <id>default</id>
    <activation>
        <activeByDefault>true</activeByDefault>
    </activation>
    <!-- ====================================================================== -->
    <!-- default Profile Build plugins -->
    <!-- ====================================================================== -->
    <build>
        <plugins>
            <!-- ====================================================================== -->
            <!-- default Profile Maven deploy plugin -->
            <!-- ====================================================================== -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-deploy-plugin</artifactId>
                <configuration>
                    <skip>true</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>deploy-thirdparty-jar</id>
                        <phase>deploy</phase>
                        <goals>
                            <goal>deploy-file</goal>
                        </goals>
                        <configuration>
                            <url>${nexus.url}/content/repositories/thirdparty</url>
                            <repositoryId>thirdparty</repositoryId>
                            <file>${project.build.directory}/${project.build.finalName}.${project.packaging}</file>
                            <groupId>${project.groupId}</groupId>
                            <artifactId>gateway-services-client</artifactId>
                            <version>${project.version}</version>
                            <packaging>jar</packaging>
                            <generatePom>true</generatePom>
                        </configuration>
                    </execution>
                    <execution>
                        <id>deploy-release-jar</id>
                        <phase>deploy</phase>
                        <goals>
                            <goal>deploy-file</goal>
                        </goals>
                        <configuration>
                            <url>${nexus.url}/content/repositories/releases</url>
                            <repositoryId>releases</repositoryId>
                            <file>${project.build.directory}/${project.build.finalName}.${project.packaging}</file>
                            <groupId>${project.groupId}</groupId>
                            <artifactId>gateway-client</artifactId>
                            <version>${project.version}</version>
                            <packaging>jar</packaging>
                            <generatePom>true</generatePom>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</profile>

Проблема в том, что, поскольку этот профиль активен по умолчанию, если мы попытаемся запустить mvn deploy, а версия координат GAV будет -SNAPSHOT, сборка непреднамеренно все равно попытается развернуться в репозиториях Nexus 3rd Party и Releases и, конечно, не удастся он не будет принимать версии артефакта -SNAPSHOT. Чтобы обойти это, я настроил профиль специально для версий -SNAPSHOT, которые будут развернуты только в хранилище моментальных снимков:

<profile>
    <!-- ====================================================================== -->
    <!-- snapshot Profile -->
    <!-- Activating this profile will automatically deactivate the default profile. -->
    <!-- The purpose of this profile is to produce a a gateway-services-client and gateway-client -->
    <!-- snapshot artifacts and deploy them to the snapshots Nexus repository where they can -->
    <!-- act as the latest development dependencies for other projects -->
    <!-- ====================================================================== -->
    <id>snapshot</id>
    <activation>
        <activeByDefault>false</activeByDefault>
    </activation>
    <!-- ====================================================================== -->
    <!-- snapshot profile Build plugins -->
    <!-- ====================================================================== -->
    <build>
        <plugins>
            <!-- ====================================================================== -->
            <!-- snapshot profile Maven deploy plugin -->
            <!-- ====================================================================== -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-deploy-plugin</artifactId>
                <configuration>
                    <skip>true</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>deploy-thirdparty-snapshot-jar</id>
                        <phase>deploy</phase>
                        <goals>
                            <goal>deploy-file</goal>
                        </goals>
                        <configuration>
                            <url>${nexus.url}/content/repositories/snapshots</url>
                            <repositoryId>snapshots</repositoryId>
                            <file>${project.build.directory}/${project.build.finalName}.${project.packaging}</file>
                            <groupId>${project.groupId}</groupId>
                            <artifactId>gateway-services-client</artifactId>
                            <version>${project.version}</version>
                            <packaging>jar</packaging>
                            <generatePom>true</generatePom>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</profile>

Проблема в том, что вы должны указать профиль при выполнении команды Maven: mvn deploy -P 'snapshot'. Мой вопрос заключается в том, что я могу сделать, чтобы все, что мне нужно сделать, это запустить mvn deploy без указания профиля моментального снимка и автоматически развернуть сборку в репозиторий моментальных снимков или в сторонние репозитории и репозитории выпусков, все на основе наличия -SNAPSHOT в версия координат GAV?


person Sheparzo    schedule 30.04.2015    source источник


Ответы (2)


Единственное решение, которое приходит мне на ум, — это использование свойств и добавление трех исполнений во время развертывания. Ужасно то, что в случае SNAPSHOT ваш артефакт будет развернут дважды в один и тот же репозиторий.

Вот что вы можете сделать:

<plugin>
    <groupId>org.codehaus.groovy.maven</groupId>
    <artifactId>gmaven-plugin</artifactId>
    <version>1.0</version>
    <executions>
        <execution>
            <id>eval-repo</id>
            <phase>initialize</phase>
            <goals>
                <goal>execute</goal>
            </goals>
            <configuration>
                <source>
                    if (project.version.endsWith("-SNAPSHOT")){
                    project.properties.repoId = "snapshots";
                    project.properties.repoUrl = "snapshots url";
                    project.properties.thirdPartyRepoId =   "snapshots";
                    project.properties.thirdPartyRepoUrl = "snapshots url";                             
                    }
                    else {
                    project.properties.repoId = "releases";
                    project.properties.repoUrl = "releases url";
                    project.properties.thirdPartyRepoId =   "thirdparty";
                    project.properties.thirdPartyRepoUrl = "thirdparty url";                                    
                    }
                </source>
            </configuration>
        </execution>
    </executions>
</plugin>

Затем добавьте три исполнения со следующими конфигурациями:

    <configuration>
        <artifactId>gateway-client</artifactId>
        <url>${repoUrl}</url>
        <repositoryId>${repoId}</repositoryId>
        ...

    <configuration>
        <artifactId>gateway-services-client</artifactId>
        <url>${repoUrl}</url>
        <repositoryId>${repoId}</repositoryId>
        ...

    <configuration>
        <artifactId>gateway-services-client</artifactId>
        <url>${thirdPartyRepoId}</url>
        <repositoryId>${thirdPartyRepoUrl}</repositoryId>
        ...
person Clauds    schedule 03.09.2015

Вы не можете сделать это с профилями. Из документа maven:

Профиль можно запустить/активировать несколькими способами:

  • Явно
  • Через настройки Maven
  • На основе переменных среды
  • Настройки ОС
  • Наличие или отсутствие файлов

Так что вы не можете сделать это так, как вы этого хотите. Впрочем, мы делаем это постоянно. Наша установка заключается в том, что мы используем следующее в нашем супер-пом

 <distributionManagement>
   <repository>
     <id>deploymentRepo</id><!-- key in settings.xml -->
     <name>Releases</name>
     <uniqueVersion>false</uniqueVersion>
     <url>${repos.release}</url>
     <layout>default</layout>
   </repository>
   <snapshotRepository>
     <id>deploymentRepo</id>
     <name>Snapshots</name>
     <uniqueVersion>true</uniqueVersion>
     <url>${repos.snapshot}</url>
     <layout>default</layout>
   </snapshotRepository>
 </distributionManagement>

Обратите внимание, что идентификатор один и тот же, потому что оба репозитория используют одни и те же учетные данные.

Мы также используем нексус, где каждое репо настраивается как моментальный снимок или выпуск, и только благодаря этому maven может знать, что *-SNAPSHOT переходит в репозиторий моментальных снимков.

Другими словами, просто дайте оба варианта одновременно, не помещайте их во взаимоисключающие профили, и maven будет знать, в какую сторону их отправить. Если это не так, попробуйте менеджер репо

person Hilikus    schedule 01.05.2015
comment
Насколько я знаю, вы можете добавить только один элемент <repository> под <distributionManagement>. Если я правильно понял, чего он пытается добиться, ваше решение не решит ни проблемы необходимости развертывания выпусков одного и того же артефакта в двух разных репозиториях, ни развертывания только выпусков (т.е. без снимков) одного из артефактов в сторонний репозиторий. - person Clauds; 03.09.2015
comment
@Clauds, ты наткнулся на недостаток этого ответа. Я хотел сделать что-то вроде того, что говорит Hilikus, но я не мог найти способ 1) развертывания в нескольких репозиториях Nexus и 2) автоматического развертывания в обоих выпусках и сторонних репозиториях Nexus, если в версии нет моментального снимка или развернуть только в репозиторий Nexus моментального снимка, если в версии есть снимок - person Sheparzo; 03.09.2015
comment
@Sheparzo, я не понял, что вы хотели развернуть не-моментальные снимки в 2 репозиториях и моментальные снимки в 1 (другом) репозитории. Единственная проблема — развертывание в двух репозиториях. Мое решение работает для обычного случая развертывания моментальных снимков в 1 репо и не-моментальных снимков в другом (другом) репо. Во всяком случае, лучшая практика в maven - это 99% раз, 1 pom = 1 артефакт -file">Посмотрите этот вопрос. если вы исправите это, у вас не будет этой проблемы - person Hilikus; 04.09.2015
comment
@Hilikus Хороший вопрос, разделяющий артефакты. Таким образом, он мог бы использовать стандартный подход к развертыванию для выпуска/моментального снимка, и ему потребовалось бы только одно дополнительное развертывание для публикации не снимка в стороннем репозитории. - person Clauds; 04.09.2015