Zdalne repozytorium Maven + Podpisy GPG

Po krótce opowiem jak zrobić własne repozytorium Mavena na w zasadzie dowolnym hostingu.

Mavena myślę, że przedstawiać nie trzeba, każdy kto miał do czynienia z JVM powinien znać ten system. Nawet jeśli używasz gradle, to oczywiście paczki dalej są ciągnięte z repozytoriów Mavena. Istnieje kilka lokalizacji, które kryją się pod tym hasłem.

  1.  Repozytorium użytkownika, w katalogu domowym pod ~/.m2/repository. Pierwsze w kolejności przeszukiwania, tutaj są pobierane paczki, zanim zostaną użyte. Raz pobrana paczka jest dalej używana z tego miejsca.
  2. Repozytorium centralne (Maven Central Repository), w którym znajdują się w większości stabilne wersje oprogramowania, do użytku ogólnego.
  3. Repozytoria lokalne, które zapewniają dostęp do paczek nieobecnych w repozytorium centalnym.

Mam zamiar skupić się na tym ostatnim punkcie. O ile finalną wersję warto wstawić do repozytorium centralnego, mordując się nieco z procedurami (np. przez OSSRH), to w przypadku prywatnego użytku nie ma to sensu.

Repozytorium może być osiągalne przez spory zbiór protokołów, File, HTTP, FTP, SSH itd. http://maven.apache.org/wagon/wagon-providers/index.html

Repozytorium w systemie plików

Podstawowym przykładem jest wykorzystanie repozytorium w lokalnym folderze, do spakowania binarnych bibliotek razem z projektem.

  <repositories>
    <repository>
      <id>project</id>
      <name>Project Repository</name>
      <url>file:///${basedir}/lib</url>
    </repository>
    <repository>
      <id>project2</id>
      <name>Project Repository</name>
      <url>file:///${basedir}/../lib</url>
    </repository>
  </repositories>

Pozwala to na użycie paczek spoza Mavena, które w lokalnym repozytorium będą dostępne dla projektu. Wersja z id „project2” przydaje się dla projektu modułowego, dla którego ${basedir} w modułach jest „zwykle” poziom niżej względem rodzica (głównego pom.xml). Kto tworzy bardziej pokrętne struktury projektu, powinien sam sobie poradzić z dodaniem tego w inny sposób.

Nie możemy klasycznie wrzucić luzem jar do /lib, bo to działać nie będzie. Repozytorium musi mieć zachowaną strukturę. By dodać paczkę do repozytorium, należy użyć polecenia

mvn install:install-file  -Dfile=path-to-your-artifact-jar \
                          -DgroupId=your.groupId \
                          -DartifactId=your-artifactId \
                          -Dversion=version \
                          -Dpackaging=jar \
                          -DlocalRepositoryPath=path-to-specific-local-repo

Każda paczka zainstalowana w ten sposób, będzie osiągalna w projekcie. Oczywiście, to nie jest dobre podejście, jeśli używamy systemu kontroli wersji, w którym, z zasady, żadnych obiektów binarnych się nie przechowuje.

Zdalne repozytorium

Innym podejściem jest wrzucanie współdzielonych z innymi osobami paczek w jakiejś wspólnej lokalizacji, na przykład na serwerze, poprzez HTTP. Wystarczy najbardziej prymitywny hosting. Możemy to zautomatyzować proces wrzucania plików na serwer poprzez deploy. Wykorzystam do tego połączenie FTP.

<distributionManagement>
   <repository>
	<id>ftp-repository</id>
	<url>ftp://mvn.globalbus.info/</url>
   </repository>
</distributionManagement>
<build>
	<extensions>
		<extension>
			<groupId>org.apache.maven.wagon</groupId>
			<artifactId>wagon-ftp</artifactId>
			<version>1.0-beta-6</version>
		</extension>
	</extensions>
</build>

Extension jest potrzebne do obsługi FTP przez deploy-plugin. Potrzebujemy też jakiś danych uwierzytelniających dla połączenia FTP. Dla przykładu konfiguracja poprzez ustawienia użytkownika w  ~/.m2/settings.xml
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                      http://maven.apache.org/xsd/settings-1.0.0.xsd">
<servers>
    <server>
      <id>ftp-repository</id>
      <username>user</username>
      <password>password</password>
    </server>
</servers>
</settings>

Kluczowe jest id, które podajemy w pom.xml projektu.

W projekcie wykonujemy

mvn deploy

co powinno wgrać pliki na serwer.

Oczywiście, do pełni szczęścia brakuje tego, by pliki wgrane przez FTP byłby osiągalne przez HTTP. Wtedy wystarczy użyć

    <repository>
      <id>globalbus</id>
      <name>globalbus private repository</name>
      <url>http://mvn.globalbus.info</url>
    </repository>

Na innej maszynie Maven użyje tego repozytorium i pobierze niezbędne paczki.

Podpis Cyfrowy.

No, a co jakbyśmy jednak chcieli wgrać paczkę do repozytorium centralnego? Jednym z wymogów jest podpisanie jej przy użyciu swojego klucza.

Jeśli jeszcze nie korzystałeś z GPG, musisz wygenerować parę kluczy.

gpg --gen-key

Potrzebne będzie hasło zabezpieczające klucz. Potem można wgrać publiczną część klucza na serwer
gpg --send-keys idklucza

Skoro jest już klucz, to można użyć pluginu podpisującego
<plugins>
	<plugin>
		<groupId>org.apache.maven.plugins</groupId>
		<artifactId>maven-gpg-plugin</artifactId>
		<version>1.6</version>
		<configuration>
			<useAgent>true</useAgent>
		</configuration>
		<executions>
			<execution>
				<id>sign-artifacts</id>
				<phase>verify</phase>
				<goals>
					<goal>sign</goal>
				</goals>
			</execution>
		</executions>
	</plugin>
</plugins>

Kluczowy jest parametr useAgent, który odpali agenta GPG, który poda mu hasło do klucza. W jaki sposób, to już zależy od konfiguracji GPG, zwykle prompt.

Ponieważ faza verify jest przed install (Maven Lifecycle), składanie podpisu może być upierdliwe. Dobrym pomysłem jest wrzucenie podpisu i deploy w oddzielny profil. No, ale o profilach to może kiedy indziej.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *