Felmerült nálunk az igény arra, hogy a Respresso-hoz kapcsolódóan kódokat tegyünk közzé Maven centralon. Ezért elkezdtünk körülnézni a neten, hogy milyen megoldással juttathatnánk el az állományokat a központi repository-ba. A cikk megírásának pillanatában a következő elfogadott repository szolgáltatók érhetőek el:

A Maven oldalán ezen szolgáltatásokon túl az OSSRH (Open Source Software Respository Hosting) által szolgáltatott repository-t emelik ki mint, a legegyszerűbb publikálási megoldást, melyet a Sonatype üzemeltet. A Maven oldalán található leírás alapján arra a következtetésre jutottunk, hogy számunka is az OSSRH lesz megfelelő, hiszen egyik fent említett szolgáltatásba sem passzolt a projektünk. A következőkben így az OSSRH-n keresztüli publikálásra fogunk fókuszálni.

Az OSSRH követelményei

Elkezdtünk tehát megismerkedni a publikálás folyamatával és követelményeivel. A következő szabályoknak kell jelenleg minden publikáló projektjének megfelelnie:

  • Generáltatni kell Java doc jar-t és sources jar-t
  • Alá kell írnunk a fájlokat GPG/PGP-vel
  • Szerepleniük kell a publikálási információknak (groupId, artifactId, version) a Maven/Gradle fájlban
  • Szükséges a projekt neve és leírása
  • Licencet kell készítenünk a projekthez
  • Meg kell adnunk fejlesztőkről szóló információkat
  • SCM (Source Control Manager) kapcsolatot kell biztosítanunk, amin keresztül a forráskód olvasható

Az SCM információk kivételével mindennek meg tudtunk felelni. Ez azonban egy sarkalatos pont volt, mivel mi nem szerettük volna publikussá tenni a forráskódunkat. Szerencsére nem ijedtünk meg a kihívástól, és átolvastuk a Maven által közzétett, publikálására vonatkozó dokumentációkat.

A kitartó munka eredményesen zárult. Kiderült ugyanis, hogy abban az esetben, ha a forráskód publikálását licenc tiltja, nem kötelező azt közzé tenni, ekkor a pom fájl publikálása is elegendő. Így a kötelezettségnek már mi is meg tudtunk felelni, és nekiláthattunk a teljes folyamat lebonyolításának.

A kód közzétételéről szóló tájékoztatást Te is elolvashatod, kedves érdeklődőnk.  Érdemes a "FAQ and common mistakes" szekciót különös figyelemmel megtekinteni!

Regisztráció és projektindítás

Keressük fel a https://issues.sonatype.org oldalt, ahol rögtön regisztrálnunk is kell magunkat. A bejelentkezést követően azonnal a „Create” felületre kerülünk, ahol egy Issue létrehozását kéri tőlünk a rendszer. Amennyiben mégsem erre a felültre kerültünk, akkor használhatjuk a Create lehetőséget. Ez az Issue fontos lesz még a későbbiekben, ugyanis ezen keresztül tudjuk majd tartani a kapcsolatot az OSSRH ügyintézőivel. Érdemes a lehető legbeszédesebben kitölteni a megjelenő formot, mivel ezt más felhasználók is láthatják, írhatnak hozzá, illetve így nekünk is kevesebb akadályon kell átküzdenünk magunkat a későbbiekben.

 

Minta a kitöltéshez:

Project: Community Support - Open Source Project Repository Hosting (OSSRH)

Issue Type: New Project

Summary: Megosztani kívánt projekt egysoros összefoglalója.

Descirption: Megosztani kívánt projekt részletesebb leírása. Érdemes több sorban megfogalmaznunk, hogy miket publikálunk a későbbiekben a groupId alatt.

GroupId: azonosító, ami a fejlesztőt azonosítja (pl.: ponte.hu)

Project url: ezen a linken található a projekt leírása

SCM url: azon verziókezelő, ahol a projekt  vagy pom fájl található

 

Kitöltöttünk minden mezőt, majd vártuk az OSSRH jelentkezését. Szerencsére nem kellett túl sokat, mivel 24 órán belül meg is kaptuk a számunkra szükséges tájékoztatást. Kérésük alapján igazolnunk kellett, hogy a ponte.hu domain a birtokunkban van. Ennek bizonyításához be kellett állítanunk egy általuk megadott DNS rekordot, valamint írnunk kellett számukra egy emailt a pontés címünkről. Ezek után pár napon belül átestünk az ellenőrzésen és már publikálhattuk is a kódunkat.

Első deploy

Sikeresen regisztráltunk és már égtünk a vágytól, hogy kirakhassuk a kódunkat. Mivel az OSSRH rendelkezik SNAPSHOT repository-val, és a SNAPSHOT verzió publikálásához elegendő csupán a regisztráció, a feljebb említett követelmények teljesítése nélkül, így ennek nem láttuk akadályát. A kód SNAPSHOT változatának pubikálása természetesen nem kötelező eleme a folyamatnak, azonban a kód éles környezetben való kipróbálásához megfelelő környzetet biztosít.

A SNAPSHOT verzió használatával felül tudjuk írni a korábbi publikációnkat a verziószám megtartásával. A függőségkezelők pedig (majdnem) minden build előtt ellenőrzik, hogy van-e friss változat az adott függőségből. A „majdnem” csupán az időfaktor miatt szerepel a mondatban, hiszen felesleges percenként ellenőrizni a repository tartalmát.

Amennyiben Maven függőség kezelőt használunk, konfiguráljuk a következő módon:

<?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/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>

   <groupId>hu.ponte.sample</groupId>
   <artifactId>sample-artifact</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <packaging>jar</packaging>
   <name>Sample deploy project</name>
   <description>This is a sample project to introduce a publish process.</description>
   <url>https://github.com/pontehu</url>
   <inceptionYear>2019</inceptionYear>


   <distributionManagement>
      <snapshotRepository>
         <id>ossrh</id>
         <url>https://oss.sonatype.org/content/repositories/snapshots</url>
      </snapshotRepository>
   </distributionManagement>
   <build>
      <plugins>
         <plugin>
            <groupId>org.sonatype.plugins</groupId>
            <artifactId>nexus-staging-maven-plugin</artifactId>
            <version>current_version</version>
            <extensions>true</extensions>
            <configuration>
               <serverId>ossrh</serverId>
               <nexusUrl>https://oss.sonatype.org/</nexusUrl>
               <autoReleaseAfterClose>true</autoReleaseAfterClose>
            </configuration>
         </plugin>
      </plugins>
   </build>
</project>

Ezek után állítsuk be a publikáláshoz szükséges privilégiumokat. Ezt a settings.xml-ben tudjuk megtenni, melyet a USER_HOME/.m2/settings.xml útvonalon érhetünk el:

<settings>
  <servers>
    <server>
      <id>ossrh</id>
      <username>your-jira-id</username>
      <password>your-jira-password</password>
    </server>
  </servers>
</settings>

Gradle típusú függéségkezelő használata esetén éljünk egy apró trükkel a publikálási folyamat megírása előtt. Szervezzük külön gradle fájlba a publikálást, ezt mi mavencetral.gradle-nek fogjuk elnevezni. A fájlt helyezzük azonos könyvtárba a build.gradle-lel, amelyen keresztül importálni fogjuk. Az említett build.gradle fájlba, a projekt modul típust követően helyezzük el a következő sort:

apply from: 'mavencentral.gradle'

A későbbikben már csak a frissen létrehozott mavencentral.gradle fájlba fogunk dolgozni. Egészítsük is ki a következő sorokkal:

apply plugin: 'maven'
def getSnapshotRepositoryUrl() {
    return "https://oss.sonatype.org/content/repositories/snapshots/"
}
afterEvaluate { project ->
    uploadArchives {
        repositories {
            mavenDeployer {
                pom.groupId = 'hu.ponte.sample'
                pom.artifactId = 'sample-artifact'
                pom.version = '0.0.1-SNAPSHOT'
                snapshotRepository(url: getSnapshotRepositoryUrl()) {
                    authentication(userName: ossrhUsername, password: ossrhPassword)
                }

                pom.project {
                    name = 'Sample deploy project'
                    packaging = 'jar/aar'
                    description = 'This is a sample project to introduce a publish process'
                    url = 'https://github.com/pontehu' 
scm { url = 'https://github.com/pontehu' connection = 'scm:git:git://github.com/pontehu/sample.git' developerConnection = 'scm:git:git://github.com/pontehu/sample.git' } } } } } } dependencies { }

Állítsuk be a publikáláshoz szükséges privilégiumokat, melyet a properties.gradle fájlban tudunk megtenni:

ossrhUsername=sampleUser
ossrhPassword=samplePass

A gradle.properties fájl több helyről is elérhető lehet a program számára:

  • a projektünk főkönyvtárában (ahol a build script található)
  • alprojekt mappájában
  • a gradle user home-ban (USER_HOME/.gradle)

Majd válasszuk az uploadArchives lehetőséget. A Deploy sikerességét azonnal le is tudjuk ellenőrizni, ugyanis a https://oss.sonatype.org/content/repositories/snapshots/ oldalon megtalálható minden sikeresen publikált projekt. Ezeket a publikációkat ettől fogva már akár függőségként is használhatjuk.

Jöjjön az éles verzió

Az éles kiadáshoz pár dolgot még be kell állítanunk. A feljebb bemutatott követelményeknek eddig nem feleltünk meg maradéktalanul, így pótolni fogjuk a hiányzókat, hiszen az összes elvárásnak való megfelelés elengedhetetlen az éles verzió publikálásához.

Javadoc

A feltölteni kívánt állományhoz generáltatnuk kell egy uploaded-project-name-javadoc.jar állományt. Amennyiben a publikálni kívánt kód java nyelven íródott, a Maven javadoc függősége elegendő lehet számunkra:

 <build>
   <plugins>
      <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-javadoc-plugin</artifactId>
         <version>current_version</version> 
         <executions> 
            <execution> 
               <id>attach-javadocs</id> 
                  <goals> 
                     <goal>jar</goal> 
                  </goals> 
            </execution> 
        </executions> 
     </plugin>
  </plugins>
</build> 

Mi azonban Kotlin kódot írtunk, és abból szerettünk volna javadoc-ot generáltatni. Ennek megfelelően a package hierarchiánk is kotlin/hu/ponte/sample/… -ként alakult. Ez esetben a javadoc függőség már nem volt megfelelő. Keresnünk kellett tehát egy olyan megoldást, ami Kotlin fájlokból is képes javadoc-ot generálni. Ekkor találtunk rá a dokka-ra.

Amennyiben groovy kódból szeretnénk docot generáltatni:

buildscript {
	repositories {
		google()
		jcenter()

	}
	
	dependencies {
		classpath 'com.android.tools.build:gradle:$gradle_version'
		classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
		classpath "org.jetbrains.dokka:dokka-gradle-plugin:${dokka_version}"
		classpath "org.jetbrains.dokka:dokka-android-gradle-plugin:${dokka_version}"
		// NOTE: Do not place your application dependencies here; they belong
		// in the individual module build.gradle files
		}
}

apply plugin: 'org.jetbrains.dokka'

dokka {
	moduleName = 'data'
	outputFormat = 'javadoc'
	outputDirectory = "$buildDir/javadoc"

	sourceDirs = files('src/main/groovy')
}

task androidJavadocsJar(type: Jar) {
	classifier = 'javadoc'
	from sourceSets.main.runtimeClasspath
}

artifacts {
	archives androidJavadocsJar
}	

A javadoc-ot követően szükséges egy forrásokat tartalmazó jar generálása is. Ez esetében a hagyományos, Maven által szolgáltatott generátor is jól használható:

Állományok titkosítása GPG/PGP használatával

A forráskódunkat titkosítanunk kell mielőtt közzé tesszük, tehát szükségünk van egy GPG kliensre. A https://www.gnupg.org/download/ oldalon megtalálhatjuk az operációs rendszerünknek megfelelő GPG változatot.

  • Windows esetén használhatjuk a Kleopatra klienst
  • Linux esetén a GnuPG klienst
  • Mac-en a GPGSuit klienst

A kulcsok generálásának és megosztásának folyamatáról részletes információ érhető el az alábbi oldalon: https://central.sonatype.org/pages/working-with-pgp-signatures.html. A sikeres kulcs generálást követően használjuk a publikáláshoz készített függőségeket.

Windows esetén a frissen telepített GPG kliens miatt indítsuk újra az Android Studio-t vagy IntelliJ-t.

A gradle properties fájlba szúrjuk be a következő sorokat: signing.gnupg.executable=gpg signing.gnupg.useLegacyGpg=true signing.gnupg.homeDir=../../../../Users/USER_NAME/AppData/Roaming/gnupg

Az útvonal megadása szükséges, mivel a Gradle alatt futó GPG kliensnek szüksége van a pubringre és hozzá tartozó fájlokra a helyes működéshez. (Kulcs importálást követően a kliens ugyanúgy legyártja ezeket a fájlokat.) A fentebb említett szignatúra Windows rendszer esetén értendő, Linuxon és Mac-en a felhasználói név alatti megfelelő mappában keresendők a gpg-hez tartozó fájlok.

A release szerverre való publikációhoz szükséges továbbá felhasználói tokent és jelszót is generáltatnunk. Ehhez a művelethez keressük fel a https://oss.sonatype.org/ oldalt és jelentkezzünk be. A jobb felső sarokban található felhasználónévre kattintva válasszuk a Profile lehetőséget. Az itt megjelenő legördülő menüben kattintsunk a User Token lehetőségre, majd az Access User Token gombra. A megjelenő adatokat tudjuk a későbbikben publikálásra használni. Az első mezőben a felhasználónév, a másodikban a jelszó kapott helyet. Kezeljük ezeknek tartalmát bizalmasan! Helyezzük el a gradle properties-be, illetve a settings.xml-be a tartalmat.

Licenc és fejlesztői információk megadása

Érdemes alaposan körülnézni a megfelelő licenc kiválasztásához, hiszen ez határozza meg a kódunk felhasználhatóságát. A licencen természetesen utólag is lehet módosítani mind engedni, mind megszorítani rajta.

OSS utolsó simítások

A sikeres deploy-t követően fel kell keresnünk a https://oss.sonatype.org oldalt. Jelentkezzünk be, majd válasszuk a Staging repository lehetőséget az oldalsó menüben. A listázott elemek között megtalálhatjuk az általunk feltöltött artifactot. Jelöljük ki, és nézzük meg az Activity fül alatt, hogy minden akció sikeresen lefutott e. Ekkor választhatunk a következő lehetőségek közül:

  1. Drop lehetőség a kódunk törléséhez. Az opció lehetőséget ad nekünk a problémák javítására és a deploy folyamat újbóli futtatására.
  2. Kattinthatunk a Close lehetőségre is, amennyiben folytatni szeretnénk a publikálást. A Close-t követően válasszuk a Release lehetőséget a kód Maven central-ba való küldéséhez. A publikálás akár 1-3 órán át is tarthat. Miután a publikálás sikeresen megtörtént, ellenőrizzük le, hogy minden rendben zajlott-e. A sikeres release-t követően érdemes plusz egy kommentben megjegyezni az OSSRH felé, hogy sikeresen kiment az első verzió, így ők aktiválhatják a későbbi szinkronizációs folyamatot. Aktíválást követően az újabb éles verziók publikálása automatikusan megtörténik és körülbelül 15 percen belül használható is a frissen publikált kód. A friss verzó Maven central front-end-en való megjelenítése azonban több óráig is eltarthat. 

Végleges változatok

A licencre és a fejlesztőkre vonatkozó információkat még nem adtuk meg a függőségkezelőnkben, ezért ezeket most pótoljuk. Nézzük meg a fájlok végleges tartalmát: