Jak określić dystrybucję Mavena w całej organizacji?

110

Próbuję dowiedzieć się, jak zorganizować wiele (około 50+) projektów maven2, aby można je było wdrożyć w centralnym repozytorium Nexus. Korzystając z mvn deploycelu, należy określić cel w tagu distributionManagement w następujący sposób:

<distributionManagement>
   <repository>
      <id>nexus-site</id>
        <url>http://central_nexus/server</url>
   </repository>
</distributionManagement>

Teraz nie chcę, aby każdy pojedynczy plik pom.xml (z tych 50+) zawierał ten blok w kółko. Moim pierwszym byłby settings.xmlplik, ale wydaje się, że nie jest możliwe (zgodnie z projektem), aby go tam zdefiniować. Zatem pierwsze pytanie brzmiałoby, dlaczego tak jest? Gdyby to było możliwe, mógłbym to określić w pliku settings.xml w dystrybucji maven2, który mógłby być dystrybuowany do wszystkich programistów.

Jedynym możliwym rozwiązaniem, które znalazłem, było utworzenie projektu master-pom obejmującego całą organizację, który zawiera te ustawienia i uzależnienie wszystkich innych pom.xml od tego master-pom za pośrednictwem <parent>tagu. Ale wygląda to trochę dziwnie w kompilacjach wielomodułowych:

- master configuration POM (pm)
- Project 1 parent pom (p1 with module 1 and module 2 as modules)
    - Project 1 module pom (with pm as parent)
    - Project 2 module pom (with pm as parent)

Zwykle czytam w całej dokumentacji, że moduł poms powinien używać pom-rodzica, a nie innego. Ale po przeczytaniu strony internetowej maven o dziedziczeniu v. Aggregation napisano, że jest to rzeczywiście możliwe.

Jeden problem, który znalazłem, dotyczył generowania witryny Maven, która wydaje się mieć problemy z tą konfiguracją (moduły nie są poprawnie łączone, jeśli nie mają bezpośredniego odniesienia wstecznego)

Czy jest to więc prawidłowe podejście? Jakieś inne, bardziej oczywiste, prostsze rozwiązanie problemu?

mglauche
źródło
5
@OhadR: Piszą tylko, jak napisać to w jednym projekcie.
Chodzi
1
Widzę. punkt zajęty. więc jak powiedział ten, który odpowiedział, możesz mieć główny pom do projektu, który będzie zawierał 'distributionMngmnt' ...
OhadR

Odpowiedzi:

144

Najlepszym rozwiązaniem jest utworzenie prostego projektu nadrzędnego pliku pom (z opakowaniem „pom”) ogólnie dla wszystkich projektów w Twojej organizacji.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>your.company</groupId>
    <artifactId>company-parent</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <distributionManagement>
        <repository>
            <id>nexus-site</id>
            <url>http://central_nexus/server</url>
        </repository>
    </distributionManagement>

</project>

Można go zbudować, wydać i wdrożyć w lokalnym nexusie, aby każdy miał dostęp do jego artefaktu.

Teraz dla wszystkich projektów, których chcesz używać, po prostu dołącz tę sekcję:

<parent>
  <groupId>your.company</groupId>
  <artifactId>company-parent</artifactId>
  <version>1.0.0</version>
</parent>

Takie rozwiązanie pozwoli Ci w łatwy sposób dodać inne wspólne rzeczy do wszystkich projektów Twojej firmy. Na przykład, jeśli chcesz ustandaryzować wykorzystanie JUnit do określonej wersji, byłoby to idealne miejsce do tego.

Jeśli masz projekty, które używają struktur wielomodułowych, które mają własnego rodzica, Maven obsługuje również dziedziczenie łańcuchowe, więc jest całkowicie akceptowalne, aby plik nadrzędny pom projektu odnosił się do macierzystego pom firmy, a moduły podrzędne projektu nawet nie wiedziały o twoim spółka dominująca.

Z twojego przykładowego projektu wynika, że ​​próbujesz umieścić swój projekt nadrzędny na tym samym poziomie, co Twój agregator pom. Jeśli Twój projekt potrzebuje własnego elementu nadrzędnego, najlepszym rozwiązaniem, jakie znalazłem, jest uwzględnienie elementu nadrzędnego na tym samym poziomie, co pozostałe moduły i umieszczenie pliku pom.xml agregatora w katalogu głównym, w którym znajdują się wszystkie katalogi modułów.

- pom.xml (aggregator)
    - project-parent
    - project-module1
    - project-module2

To, co robisz z tą strukturą, to dołączanie modułu nadrzędnego do agregatora i budowanie wszystkiego za pomocą pliku mvn installz katalogu głównego.

Używamy dokładnie tego rozwiązania w mojej organizacji, które przetrwało próbę czasu i całkiem dobrze nam się sprawdziło.

Jesse Webb
źródło
Oto kolejna odpowiedź, w której bardziej szczegółowo opiszę dziedziczenie projektu i jak zarządzać dziedziczeniem złożoności, przepraszam za kalambur. ;) stackoverflow.com/questions/6347913
Jesse Webb
7
Mała uwaga: z powodów, dla których firma nadrzędna jest najlepszym rozwiązaniem, zobacz dyskusję Nie można określić DistributionManagement w settings.xml z listy użytkowników Mavena.
Premek Brada
W klasycznym modelu konsultingowym, w którym „klient jest właścicielem kodu”, mój zespół programistów będzie musiał pracować nad projektem poza siedzibą, a następnie przenieść najnowszy kod do siedziby klienta i ponownie go zbudować. W mojej sytuacji, pracując z projektem wielomodułowym, jeśli będę odwoływał się do firmy POM w POM-cie nadrzędnym projektu, będę musiał zaktualizować to odniesienie, aby wskazywało na POM firmy klienta. Wolałbym starać się zachować wszystkie ustawienia specyficzne dla środowiska w settings.xml, jeśli mogę na to poradzić. Jakie jest zalecane podejście w mojej sytuacji?
Użytkownik sieciowy
2
@WebUser Twój problem brzmi bardziej jak sytuacja, w której potrzebujesz różnych wartości w plikach POM, w przeciwieństwie do tego, co rozwiązuje ta odpowiedź: unikanie powielania ustawień w wielu modułach. Myślę, że powinieneś spróbować wstrzyknąć właściwości za pośrednictwem pliku settings.xml . Jeśli to ci nie pomoże, zadaj nowe pytanie tutaj na SO, link do niego tutaj, a ja postaram się dalej ci pomóc.
Jesse Webb
Dzięki @JesseWebb Skończyło się na tym, że wypróbowałem to i warto odciągnąć te wartości od POM dla opisanej przeze mnie sytuacji. Na moje potrzeby dodałem odpowiednie właściwości pod aktywnym profilem oraz rozwiązane w POM.
Użytkownik sieciowy
36

Nie ma potrzeby posiadania rodzica POM.

Możesz całkowicie pominąć część DistributionManagement w swoich poms i ustawić ją na serwerze kompilacji lub w settings.xml.

Aby to zrobić na serwerze kompilacji, po prostu przejdź do mvnpolecenia:

-DaltSnapshotDeploymentRepository=snapshots::default::https://YOUR_NEXUS_URL/snapshots
-DaltReleaseDeploymentRepository=releases::default::https://YOUR_NEXUS_URL/releases

Zobacz https://maven.apache.org/plugins/maven-deploy-plugin/deploy-mojo.html, aby uzyskać szczegółowe informacje, które opcje można ustawić.

Można to również ustawić w pliku settings.xml.

Po prostu utwórz tam profil, który jest włączony i zawiera właściwość.

Przykład settings.xml:

<settings>
[...]
  <profiles>
    <profile>
      <id>nexus</id>
      <properties>
        <altSnapshotDeploymentRepository>snapshots::default::https://YOUR_NEXUS_URL/snapshots</altSnapshotDeploymentRepository>
        <altReleaseDeploymentRepository>releases::default::https://YOUR_NEXUS_URL/releases</altReleaseDeploymentRepository>
      </properties>
    </profile>
  </profiles>

  <activeProfiles>
    <activeProfile>nexus</activeProfile>
  </activeProfiles>

</settings>

Upewnij się, że poświadczenia „migawek” i „wersji” znajdują się w <servers>sekcji pliku settings.xml

Właściwości altSnapshotDeploymentRepository i altReleaseDeploymentRepository są wprowadzane za pomocą maven-deploy-plugin w wersji 2.8. Starsze wersje zakończą się niepowodzeniem z komunikatem o błędzie

Deployment failed: repository element was not specified in the POM inside distributionManagement element or in -DaltDeploymentRepository=id::layout::url parameter

Aby to naprawić, możesz wymusić nowszą wersję wtyczki:

        <build>
          <pluginManagement>
            <plugins>
              <plugin>
                <artifactId>maven-deploy-plugin</artifactId>
                <version>2.8</version>
              </plugin>
            </plugins>
          </pluginManagement>
        </build>
Michael Wyraz
źródło
Ciągle próbuję tego rozwiązania, ale działa tylko właściwość altDeploymentRepository . altReleaseDeploymentRepository i altSnapshotDeploymentRepository nie są rozpoznawane i pojawia się ten błąd: Wdrożenie nie powiodło się: element repozytorium nie został określony w POM w elemencie DistributionManagement lub w parametrze -DaltDeploymentRepository = id :: layout :: url. Każda sugestia byłaby pomocna. Dziękuję
Shabirmean
@Shabirmean Przyczyną jest zbyt stara wersja wtyczki do wdrażania. Rozszerzyłem moją odpowiedź o rozwiązanie.
Michael Wyraz
Tak, wymyśliłem to. Dziękuję bardzo :)
Shabirmean