Ebben a cikkben részletesen szeretném bemutatni a Java artefaktum nulláról történő közzétételének folyamatát Github Actions segítségével a Sonatype Maven Central Repository-ba, Gradle használatával.
Ezt a cikket azért írtam, mert hiányzott egy megfelelő útmutató egy helyen. Az összes információt különböző forrásokból kellett összegyűjtenem, ráadásul nem éppen frissek voltak. Aki érdeklődik, az szívesen látott a továbbiakban.
A repozitórium létrehozása a Sonatype-ban
Első lépésként létre kell hoznunk egy repozitóriumot a Sonatype Maven Central-ban. Ehhez lépjünk , regisztráljunk és hozzunk létre egy új feladatot, kérve, hogy hozzanak létre egy repozitóriumot számunkra. Írjuk be a GroupId projektet, A projekt URL a projekt linkje és SCM url a verziókezelő rendszer linkje, amelyben a projekt található. GroupId ennek a formátumú kell lennie: com.example, com.example.domain, com.example.testsupport, és lehet a Github profilod linkje is: -> io.github.yourusername. Minden esetben meg kell erősítened a domained vagy profilod tulajdonjogát. Ha a Github profilt adtad meg, kérni fognak, hogy hozz létre egy nyilvános repozitóriumot a szükséges névvel.
Néhány idő elteltével a tulajdonjog megerősítése után a GroupId-d meg fog jelenni, és áttérhetünk a következő lépésre, a Gradle konfigurálására.
Gradle konfigurálása
A cikk írásának időpontjában nem találtam olyan Gradle bővítményeket, amelyek segíthetnének az artefaktum közzétételében. Az egyetlen bővítmény, amelyet találtam, azonban az írója lemondott a további támogatásáról. Így úgy döntöttem, hogy mindent magam csinálok, lévén, hogy ez nem túl bonyolult.
Az első dolog, amit meg kell tisztázni, az a Sonatype követelményei a közzétételhez. Az alábbiak:
- Forráskód és JavaDoc megléte, azaz a következő fájloknak kell jelen lenniük:
-sources.jarés-javadoc.jarfájlok. Ahogyan a dokumentációban olvasható, ha nincs lehetőség forráskódok vagy dokumentáció rendelkezésre bocsátására, lehet készíteni egy üres fájlt-sources.jarvagy-javadoc.jaregy egyszerű README fájlral benne, hogy átmenjünk az ellenőrzésen. - Minden fájl aláírásra kerül az
GPG/PGP, és a.ascfájlnak, amely az aláírást tartalmazza, minden egyes fájlhoz be kell tartoznia. - A
pomfájlt - Helyes értékek
groupId,artifactIdésversion. A verzió lehet tetszőleges karakterlánc és nem végződhet-SNAPSHOT - Az engedély, a fejlesztők és a verziókezelő rendszer információinak megjelenése szükséges.
name,leírásésurl - Ezek a fő szabályok, amelyeket be kell tartani a közzététel során. A teljes információ elérhető
Ezeket a követelményeket valósítjuk meg a .
build.gradle build.gradle fájl. Kezdjük azzal, hogy hozzáadjuk a szükséges információkat a fejlesztőkről, a licencről, a verziókezelő rendszerről, valamint megadjuk az URL-t, a nevet és a projekt leírását. Ehhez írjunk egy egyszerű metódust:
def customizePom(pom) {
pom.withXml {
def root = asNode()
root.dependencies.removeAll { dep ->
dep.scope == "test"
}
root.children().last() + {
resolveStrategy = DELEGATE_FIRST
description 'A műtárgy néhány leírása'
name 'Műtárgy neve'
url 'https://github.com/login/projectname'
organization {
name 'com.github.login'
url 'https://github.com/login'
}
issueManagement {
system 'GitHub'
url 'https://github.com/login/projectname/issues'
}
licenses {
license {
name 'The Apache License, Version 2.0'
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
}
scm {
url 'https://github.com/login/projectname'
connection 'scm:https://github.com/login/projectname.git'
developerConnection 'scm:git://github.com/login/projectname.git'
}
developers {
developer {
id 'dev'
name 'DevName'
email 'email@dev.hu'
}
}
}
}
}Ezután meg kell adnunk, hogy a build során generálódjanak -sources.jar és-javadoc.jar fájlok. Ehhez a szekcióba java kell a következőket hozzáadni:
java {
withJavadocJar()
withSourcesJar()
}Térjünk át az utolsó követelményre, a GPG/PGP aláírás beállítására. Ehhez csatlakoztassuk a bővítményt signing:
plugins {
id 'signing'
}És adjuk hozzá a szekciót:
signing {
sign publishing.publications
}Végül adjuk hozzá a szekciót publishing:
publishing {
publications {
mavenJava(MavenPublication) {
customizePom(pom)
groupId group
artifactId archivesBaseName
version version
from components.java
}
}
repositories {
maven {
url "https://oss.sonatype.org/service/local/staging/deploy/maven2"
credentials {
username sonatypeUsername
password sonatypePassword
}
}
}
}Itt sonatypeUsername és sonatypePassword változók, amelyek a regisztráció során létrehozott bejelentkezési adatokat és jelszót tartalmazzák .
Így a végső build.gradle a következőképpen fog kinézni:
A build.gradle teljes kódja
plugins {
id 'java'
id 'maven-publish'
id 'signing'
}
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
withJavadocJar()
withSourcesJar()
}
group 'io.github.githublogin'
archivesBaseName = 'projectname'
version = System.getenv('RELEASE_VERSION') ?: "0.0.1"
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.5.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.5.2'
}
test {
useJUnitPlatform()
}
jar {
from sourceSets.main.output
from sourceSets.main.allJava
}
signing {
sign publishing.publications
}
publishing {
publications {
mavenJava(MavenPublication) {
customizePom(pom)
groupId group
artifactId archivesBaseName
version version
from components.java
}
}
repositories {
maven {
url "https://oss.sonatype.org/service/local/staging/deploy/maven2"
credentials {
username sonatypeUsername
password sonatypePassword
}
}
}
}
def customizePom(pom) {
pom.withXml {
def root = asNode()
root.dependencies.removeAll { dep ->
dep.scope == "test"
}
root.children().last() + {
resolveStrategy = DELEGATE_FIRST
description 'Some description of artifact'
name 'Artifct name'
url 'https://github.com/login/projectname'
organization {
name 'com.github.login'
url 'https://github.com/githublogin'
}
issueManagement {
system 'GitHub'
url 'https://github.com/githublogin/projectname/issues'
}
licenses {
license {
name 'The Apache License, Version 2.0'
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
}
scm {
url 'https://github.com/githublogin/projectname'
connection 'scm:https://github.com/githublogin/projectname.git'
developerConnection 'scm:git://github.com/githublogin/projectname.git'
}
developers {
developer {
id 'dev'
name 'DevName'
email 'email@dev.ru'
}
}
}
}
}Szeretném megjegyezni, hogy a verziót környezeti változóból kapjuk: System.getenv('RELEASE_VERSION'). Ezt a build során állítjuk be, és a címkenevéből vesszük.
PGP kulcs generálása
A Sonatype egyik követelménye, hogy minden fájl aláírásra kerüljön GPG/PGP kulccsal. Ehhez lépjünk és töltsük le a GnuPG eszközt a saját operációs rendszerünkhöz.
- Generáljuk a kulcspárt:
gpg --gen-key, adjuk meg a felhasználónevünket, e-mail címünket, valamint egy jelszót is. - Megállapítjuk
ida kulcsunkat a következő parancs segítségével:gpg --list-secret-keys --keyid-format short. Az ID a perjel után lesz feltüntetve, például: rsa2048/9B695056 - A nyilvános kulcsot közzé tesszük a szerveren a következő parancs segítségével:
gpg --keyserver [https://keys.openpgp.org](https://keys.openpgp.org/) --send-keys 9B695056 - Exportáljuk a titkos kulcsot egy tetszőleges helyre, mert a továbbiakban szükségünk lesz rá:
gpg --export-secret-key 9B695056 > D:\gpg\9B695056.gpg
Beállítjuk a Github Actions-t
Térjünk át a végső szakaszra, állítsuk be a buildet és az automatikus kiadást a Github Actions segítségével.
A Github Actions egy funkcionalitás, amely lehetővé teszi a munkafolyamat automatizálását, megvalósítva a teljes CI/CD ciklust. A build, tesztelés és telepítés különféle események által kiváltható: kód push, kiadás létrehozása vagy issue. Ez a funkcionalitás teljesen ingyenes a nyilvános repozitóriumok számára.
Ebben a szakaszban megmutatom, hogyan állíthatjuk be a buildet és a kód push-ot, valamint a kiadás során történő telepítést a Sonatype repozitóriumba, és a titkok beállítását is.
Titkok megadása
Az automatikus build és telepítés érdekében szükség lesz egy sor titkos értékre, például a kulcs azonosítójára, a jelszóra, amelyet a kulcs generálásakor adtunk meg, magára a PGP kulcsra, és a Sonatype-hoz szükséges bejelentkezési adatokra. Ezeket egy külön szakaszban lehet megadni a repozitórium beállításaiban:

A következő változókat állítjuk be:
- SONATYPE_USERNAME/SONATYPE_PASSWORD — a Sonatype-ra való regisztrációkor megadott bejelentkezési adatok
- SIGNING_KEYID/SIGNING_PASSWORD — a PGP kulcs azonosítója és a generáláskor beállított jelszó.
A GPG_KEY_CONTENTS változóra szeretnék kicsit részletesebben kitérni. Az a helyzet, hogy a közzétételhez szükségünk van a titkos PGP kulcsra. A kulcsot a titkok között történő elhelyezéshez használhattam, és további lépéseket tettem.
- Titkosítjuk a kulcsunkat gpg segítségével:
gpg --symmetric --cipher-algo AES256 9B695056.gpg, beírva a jelszót. Ezt a változóba kell tenni: SECRET_PASSPHRASE - A kapott titkosított kulcsot átkonvertáljuk szöveges formába base64 segítségével:
base64 9B695056.gpg.gpg > 9B695056.txt. A tartalmát a változóban helyezzük el: GPG_KEY_CONTENTS.
A build beállítása kód push és PR létrehozásakor
Először létre kell hozni egy mappát a projekt gyökerében: .github/workflows.
Ebben elhelyezünk egy fájlt, például gradle-ci-build.yml a következő tartalommal:
name: build
on:
push:
branches:
- master
- dev
- testing
pull_request:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: JDK 8 beállítása
uses: actions/setup-java@v1
with:
java-version: 8
- name: Build Gradle-lel
uses: eskatos/gradle-command-action@v1
with:
gradle-version: current
arguments: build -PsonatypeUsername=${{secrets.SONATYPE_USERNAME}} -PsonatypePassword=${{secrets.SONATYPE_PASSWORD}}Ez a munkafolyamat a branch-ekbe való pushkor fog végrehajtódni master, dev és tesztelés, valamint pull requestek létrehozásakor.
A jobs szakaszban találhatóak azok a lépések, amelyeket a megadott eseményekre kell végrehajtani. Ebben az esetben a legújabb ubuntu verzión fogunk buildelni, Java 8-at használni, valamint a Gradle plugin-t is eskatos/gradle-command-action@v1, amely a legújabb verziójú build eszközt használva futtatja a megadott parancsokat, — választható argumentumok. Részletesebben lásd alább.. Változók secrets.SONATYPE_USERNAME és secrets.SONATYPE_PASSWORD ezek azok a titkok, amelyeket korábban beállítottunk.
A build eredményei az Actions fülön jelennek meg:

Automatikus telepítés új kiadás esetén
Az automatikus telepítéshez külön munkafolyamat fájlt hozunk létre gradle-ci-publish.yml:
name: publish
on:
push:
tags:
- 'v*'
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: JDK 8 telepítése
uses: actions/setup-java@v1
with:
java-version: 8
- name: Felkészülés a publikálásra
run: |
echo '${{secrets.GPG_KEY_CONTENTS}}' | base64 -d > publish_key.gpg
gpg --quiet --batch --yes --decrypt --passphrase="${{secrets.SECRET_PASSPHRASE}}"
--output secret.gpg publish_key.gpg
echo "::set-env name=RELEASE_VERSION::${GITHUB_REF:11}"
- name: Publikálás Gradle-lal
uses: eskatos/gradle-command-action@v1
with:
gradle-version: current
arguments: test publish -Psigning.secretKeyRingFile=secret.gpg -Psigning.keyId=${{secrets.SIGNING_KEYID}} -Psigning.password=${{secrets.SIGNING_PASSWORD}} -PsonatypeUsername=${{secrets.SONATYPE_USERNAME}} -PsonatypePassword=${{secrets.SONATYPE_PASSWORD}}A fájl gyakorlatilag az előzőhöz hasonló, a kiváltó esemény kivételével. Ebben az esetben a kiváltó esemény egy 'v'-re kezdődő címkének a létrehozása.
A telepítés előtt ki kell nyernünk a PGP kulcsot a titkok közül, el kell helyeznünk a projekt gyökérmappájában, és meg kell fejtenünk. Ezt követően be kell állítanunk egy speciális környezeti változót RELEASE_VERSION amelyre a gradle.build fájlban hivatkozunk. Mindez a Felkészülés a publikálásrarészben történik. A kulcsot a GPG_KEY_CONTENTS változóból nyerjük, átalakítjuk gpg fájllá, majd dekódoljuk, helyezve a fájlba secret.gpg.
Ezután egy különleges változónkhoz fordulunk, GITHUB_REF, amelyből kinyerhetjük a verziót, amit a címke létrehozásakor adtunk meg. Ez a változó ebben az esetben úgy néz ki, mint refs/tags/v0.0.2 , amiből levágjuk az első 11 karaktert, hogy pontosan a verziót kapjuk. Ezután a Gradle parancsokat a publikálásra használjuk: test publish
A telepítés eredményeinek ellenőrzése a Sonatype tárolóban
A kiadás létrehozása után el kell indulnia a korábban leírt munkafolyamatnak. Ehhez kiadást hozzunk létre:

a címkének 'v'-vel kell kezdődnie. Ha a Publikálás gombra kattintva a munkafolyamat sikeresen befejeződik, beléphetünk a felületen, hogy ezt ellenőrizzük:

Az artefaktus megjelent a Staging tárolóban. Azonnal Open státuszba kerül, ezután kézzel kell Closed státuszba állítani, a megfelelő gombra kattintva. Minden követelmény ellenőrzése után az artefaktus Closed státuszba kerül, és többé nem módosítható. Ilyen formában fog megjelenni a MavenCentralban. Ha minden rendben van, kattintson a gombra Kiadás, ezáltal az artefaktus bekerül a Sonatype tárolóba.
Ahhoz, hogy az artefaktus a MavenCentralba kerüljön, kérni kell ezt a feladatban, amelyet az elején létrehoztunk. Ezt csak egyszer szükséges megtenni, mivel először publikálunk. A későbbi alkalmak során erre már nincs szükség, minden automatikusan szinkronizálva lesz. Az én szinkronizálásomat gyorsan aktiválták, de ahhoz, hogy az artefaktus elérhető legyen a MavenCentralban, körülbelül 5 nap telt el.
Ezzel véget ért, publikáltuk az artefaktusunkat a MavenCentralban.
Hasznos linkek
- Hasonló , csak publikálás mavenen keresztül
- Staging Sonatype
- Sonatype, ahol feladatot kell létrehozni
- tároló, ahol mindez be van állítva
Forrás: habr.com
