Doświadczenie z użyciem flatten-maven-plugin do uproszczenia wersjonowania w projektach maven

O nas

W 1C opracowujemy nie tylko platformę 1C: Przedsiębiorstwo na C++ i JavaScript, ale także aplikacje w Java – w szczególności nowe środowisko rozwoju Narzędzia do rozwoju przedsiębiorstw na bazie Eclipse, a serwer jest głęboko zintegrowany z platformą komunikatora – Systemy Interakcji.

Wprowadzenie

Jako system budowania aplikacji Java najczęściej używamy maven, i w tym krótkim artykule chcemy opowiedzieć o jednym z problemów, z którymi musieliśmy się zmierzyć w procesie organizacji rozwoju, oraz o podejściu, które pozwoliło nam pokonać ten problem.

Podłoża i proces roboczy

Ze względu na specyfikę rozwoju w naszych projektach maven używamy dość wielu modułów, zależności i projektów podrzędnych. Liczba plików pom w jednej strukturze może sięgać dziesiątek, a nawet setek.

Doświadczenie z użyciem flatten-maven-plugin do uproszczenia wersjonowania w projektach maven

Wydawało się: nic strasznego, raz stworzyliśmy i zapomnieliśmy. Jeśli trzeba coś zmienić lub dodać we wszystkich plikach naraz, istnieje wiele wygodnych narzędzi w edytorach i IDE. A jakie jest najczęstsze, regularne zmieniane w pom.xml? Uważamy, że zmiana wersji projektu i zależności. Może ktoś zechce się z tym spierać, ale u nas sprawa wygląda właśnie tak. Powód tkwi w tym, że obok rdzenia równolegle rozwijamy wiele własnych bibliotek, a dla stałej powtarzalności wyników kompilacji i testowania użycie snapshotów nie wydaje się nam wygodnym podejściem. Z tego powodu musimy podnosić numer wersji w projektach przy każdej kompilacji.

Również dla dewelopera od czasu do czasu pojawia się potrzeba zbudowania swojego oddziału jakiejś biblioteki i sprawdzenia jej działania we wszystkich zależnościach, co wymaga ręcznej zmiany wersji we wszystkich z nich.

Początkowe rozwiązanie

Z takimi częstymi i licznymi zmianami wersji proces w ramach CI chce się uprościć i zautomatyzować. W tym przypadku z pomocą przychodzi wygodny, ogólnie znany plugin versions-maven-plugin — podłączamy go i uruchamiamy

mvn -N versions:set -DnewVersion=2.0.1

i maven zrobi wszystko jak należy: przejdzie przez hierarchię od góry do dołu, podmieni wszystkie wersje — piękne! Teraz zostaje tylko podnieść pull-request, koledzy sprawdzą zmiany i można szybko włączyć się w trunk. Szybko? Jakby nie było. Para-trzy setki pom.xml w recenzji, nie licząc kodu. Dodatkowo nikt nie jest zabezpieczony przed konfliktami scalania przy tak dużej liczbie zmienionych plików. Należy zauważyć, że podczas CI zmiany wersji odbywają się automatycznie wraz ze zmianą funkcjonalności, a nie jakoś osobno.

Nowe możliwości

Przez pewien czas uspokoiliśmy się i, pogodzawszy się, tak żyliśmy, aż chłopaki z Maven Apache Project nie wprowadzili do maven, począwszy od wersji 3.5.0-beta-1, wsparcia dla tzw. „zamienników” wersji (placeholders). Istotą tych zamienników jest to, że w pom.xml zamiast konkretnego wskazania wersji projektu używane są zmienne ${revision}, ${sha1} i ${changelist}. Same wartości tych atrybutów są określane albo w elemencie <properties>, albo można je zdefiniować poprzez właściwość systemową

mvn -Drevision=2.0.0 clean package

Wartości właściwości systemowych mają pierwszeństwo przed wartościami zdefiniowanymi w <properties>.

Rodzic
<project>
  <modelVersion>4.0.0<\/modelVersion>
  <parent>
    <groupId>org.apache<\/groupId>
    <artifactId>apache<\/artifactId>
    <version>18<\/version>
  <\/parent>
  <groupId>org.apache.maven.ci<\/groupId>
  <artifactId>ci-parent<\/artifactId>
  <name>First CI Friendly<\/name>
  <version>${revision}${sha1}${changelist}<\/version>
  …
  <properties>
    <revision>1.3.1<\/revision>
    <changelist>-SNAPSHOT<\/changelist>
    <sha1\/>
  <\/properties>
<\/project>

Potomek
<project>
  <modelVersion>4.0.0<\/modelVersion>
  <parent>
    <groupId>org.apache.maven.ci<\/groupId>
    <artifactId>ci-parent<\/artifactId>
    <version>${revision}${sha1}${changelist}<\/version>
  <\/parent>
  <groupId>org.apache.maven.ci<\/groupId>
  <artifactId>ci-child<\/artifactId>
   …
<\/project>

Jeśli chcesz zbudować wersję 2.0.0-SNAPSHOT, po prostu użyj

    mvn -Drevision=2.0.0 clean package

Jeśli chcesz zrobić wydanie, po prostu resetuj SNAPSHOT

    mvn -Dchangelist= clean package

*Przykłady powyżej wzięte z artykułu na stronie Maven Apache Project

Brutalna rzeczywistość

Wszystko jest dobrze i świetnie, czas poczuć satysfakcję, ale nie. Okazuje się, że dla install i deploy ten sposób się nie nadaje, ponieważ w opisach publikowanych w repozytorium artefaktów nie będzie zastępowane ${revision} na jej wartość i maven nie zrozumie dalej o co chodzi.

<parent>
    <groupId>org.apache<\/groupId>
    <artifactId>apache<\/artifactId>
    <version>${revision}<\/version>
<\/parent>

Światło na końcu tunelu

Trzeba szukać rozwiązania problemu. Sytuację mogłoby uratować flatten-maven-pluginTen wtyczka pozwala na używanie wszystkich zmiennych w pom, ale jednocześnie usuwa wiele innych informacji, które są potrzebne tylko podczas budowy i nie są potrzebne przy imporcie opublikowanych artefaktów do innych projektów. Dodatkowo wtyczka "prostuje" wszystkie zależności parent-child, co skutkuje płaskimi pom, zawierającymi wszystko, co potrzebne. Uciążliwością było to, że usuwa "nadmiarowe" informacje zbyt dużo, co nam zupełnie nie pasowało. Po zbadaniu informacji na temat rozwoju tej wtyczki okazało się, że nie jesteśmy sami we wszechświecie, a już w sierpniu 2018 na GitHubie w repozytorium wtyczki stworzono pull-request z prośbą o możliwość samodzielnego określenia, jak powinno się „psuć” pom.xml. Deweloperzy wysłuchali głosów potrzebujących i już w grudniu, wraz z wydaniem nowej wersji 1.1.0, w flatten-maven-plugin pojawił się nowy tryb resolveCiFriendliesOnly, który idealnie się wpasował – pozostawia pom.xml taki, jaki jest, z wyjątkiem elementu <version> i pozwala na ${revision}, ${sha1} i ${changelist}.

Dodajemy wtyczkę do projektu

<plugins>
  <plugin>
    <groupId>org.codehaus.mojo<\/groupId>
    <artifactId>flatten-maven-plugin<\/artifactId>
    <version>1.1.0<\/version>
    <configuration>
      <updatePomFile>true<\/updatePomFile>
      <flattenMode>resolveCiFriendliesOnly<\/flattenMode>
    <\/configuration>
    <executions>
      <execution>
        <id>flatten<\/id>
        <phase>process-resources<\/phase>
        <goals>
          <goal>flatten<\/goal>
        <\/goals>
      <\/execution>
      <execution>
        <id>flatten.clean<\/id>
        <phase>clean<\/phase>
        <goals>
          <goal>clean<\/goal>
        <\/goals>
      <\/execution>
    <\/executions>
  <\/plugin>
<\/plugins>

Gotowe!

Szczęśliwe zakończenie

Od teraz, aby zmienić wersję całego projektu i poinformować o tym wszystkie zależności, wystarczy edytować element <revision> w jednym tylko korzeniu pom.xml. Na przegląd przesyłany jest nie setki tych plików z tym samym zmienonym elementem, a jeden. Tak więc znika konieczność korzystania z versions-maven-plugin.

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster