ProHoster > Blog > uprava > Korištenje Gradle i Github radnji za objavljivanje Java projekta u Sonatype Maven Central Repository
Korištenje Gradle i Github radnji za objavljivanje Java projekta u Sonatype Maven Central Repository
U ovom članku želim detaljno pogledati proces objavljivanja Java artefakta od nule kroz Github Actions do Sonatype Maven Central Repository pomoću Gradle buildera.
Odlučio sam napisati ovaj članak zbog nedostatka normalnog tutorijala na jednom mjestu. Sve informacije trebalo je prikupljati dio po dio iz raznih izvora, štoviše, ne posve svježih. Koga briga, dobrodošao pod kat.
Stvaranje repozitorija u Sonatypeu
Prvi korak je stvaranje repozitorija u Sonatype Maven Central. Za ovo idemo ovdje, registrirajte se i kreirajte novi zadatak, tražeći od nas da stvorimo spremište. Vozimo se u našem GroupId projekt, URL projekta veza projekta i SCM url poveznica na sustav kontrole verzija u kojem se projekt nalazi. GroupId ovdje treba biti u obliku com.example, com.example.domain, com.example.testsupport, a može biti i u obliku veze na vaš github: github.com/vašekorisničkoime -> io.github.vašekorisničkoime. U svakom slučaju, morat ćete potvrditi vlasništvo nad ovom domenom ili profilom. Ako ste naveli github profil, od vas će se tražiti da stvorite javno spremište sa željenim nazivom.
Neko vrijeme nakon potvrde, vaš GroupId će biti kreiran i možemo prijeći na sljedeći korak, Gradle konfiguraciju.
Konfiguriranje Gradle
U vrijeme pisanja nisam pronašao Gradle dodatke koji bi mogli pomoći u objavljivanju artefakta. ovo jedini dodatak koji sam pronašao, međutim, autor ga je odbio dalje podržavati. Stoga sam odlučio sve učiniti sam, jer to nije previše teško učiniti.
Prvo što treba shvatiti su Sonatypeovi zahtjevi za objavljivanje. Oni su sljedeći:
Dostupnost izvornih kodova i JavaDoc-a, tj. mora prisustvovati -sources.jar и-javadoc.jar datoteke. Kao što je navedeno u dokumentaciji, ako nije moguće osigurati izvorne kodove ili dokumentaciju, možete izraditi lutku -sources.jar ili -javadoc.jar s jednostavnim README unutra kako biste prošli test.
Sve datoteke moraju biti potpisane s GPG/PGPI .asc datoteka koja sadrži potpis mora biti uključena za svaku datoteku.
Dostupnost pom datoteka
Ispravne vrijednosti groupId, artifactId и version. Verzija može biti proizvoljan niz i ne može završavati s -SNAPSHOT
Potrebna prisutnost name, description и url
Prisutnost informacija o licenci, programerima i sustavu kontrole verzija
Ovo su osnovna pravila kojih se morate pridržavati prilikom objave. Sve informacije dostupne здесь.
Ove zahtjeve implementiramo u build.gradle datoteka. Prvo, dodajmo sve potrebne informacije o programerima, licencama, sustavu kontrole verzija, a također postavimo url, naziv i opis projekta. Napišimo jednostavnu metodu za ovo:
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/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 protected]'
}
}
}
}
}
Zatim morate to navesti tijekom generiranog sklopa -sources.jar и-javadoc.jar datoteke. Za ovaj odjeljak java morate dodati sljedeće:
java {
withJavadocJar()
withSourcesJar()
}
Prijeđimo na posljednji zahtjev, postavljanje GPG/PGP potpisa. Da biste to učinili, spojite dodatak signing:
plugins {
id 'signing'
}
I dodajte odjeljak:
signing {
sign publishing.publications
}
Na kraju, dodajmo odjeljak 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
}
}
}
}
Ovdje sonatypeKorisničkoime и sonatypePassword varijable koje sadrže prijavu i lozinku stvorene tijekom registracije na sonatype.org.
Dakle, finale build.gradle izgledat će ovako:
Potpuni build.gradle kod
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 protected]'
}
}
}
}
}
Želim napomenuti da verziju dobivamo iz varijable okruženja: System.getenv('RELEASE_VERSION'). Izložit ćemo ga tijekom montaže i uzeti iz naziva oznake.
Generiranje PGP ključa
Jedan od Sonatypeovih zahtjeva je da sve datoteke budu potpisane GPG/PGP ključem. Za ovo idemo ovdje i preuzmite uslužni program GnuPG za svoj operativni sustav.
Generiramo par ključeva: gpg --gen-key, unesite korisničko ime, e-mail i također postavite lozinku.
Saznavši id naš ključ s naredbom: gpg --list-secret-keys --keyid-format short. Id će biti naveden nakon kose crte, na primjer: rsa2048/9B695056
Objavljivanje javnog ključa na poslužitelju https://keys.openpgp.org sa naredbom: gpg --keyserver [https://keys.openpgp.org](https://keys.openpgp.org/) --send-keys 9B695056
Tajni ključ izvozimo na proizvoljno mjesto, trebat će nam u budućnosti: gpg --export-secret-key 9B695056 > D:\gpg\9B695056.gpg
Postavljanje Github radnji
Prijeđimo na završnu fazu, postavimo izgradnju i automatsko objavljivanje pomoću Github Actions.
Github Actions je značajka koja vam omogućuje automatizaciju tijeka rada implementacijom punog CI/CD ciklusa. Izrada, testiranje i implementacija mogu biti potaknuti raznim događajima: guranje koda, stvaranje izdanja ili problemi. Ova je funkcija potpuno besplatna za javna spremišta.
U ovom odjeljku, pokazat ću vam kako postaviti kod za izgradnju i push i implementirati u repozitorij Sonatype nakon izdavanja, kao i postaviti tajne.
Mi postavljamo tajne
Za automatsku montažu i implementaciju trebamo niz tajnih vrijednosti, kao što je ID ključa, lozinka koju smo unijeli prilikom generiranja ključa, sam PGP ključ i Sonatype prijava/lozinka. Možete ih postaviti u posebnom odjeljku u postavkama repozitorija:
Postavili smo sljedeće varijable:
SONATYPE_USERNAME / SONATYPE_PASSWORD - prijava / lozinka koju smo unijeli prilikom registracije na Sonatype
SIGNING_KEYID/SIGNING_PASSWORD — ID PGP ključa i lozinka postavljeni tijekom generiranja.
Želim se detaljnije osvrnuti na varijablu GPG_KEY_CONTENTS. Činjenica je da nam je za objavljivanje potreban privatni PGP ključ. Kako bih ga objavio u tajnama, koristio sam instrukcije te dodatno napravio niz akcija.
Kriptirajmo naš ključ pomoću gpg-a: gpg --symmetric --cipher-algo AES256 9B695056.gpgunosom lozinke. Treba je smjestiti u varijablu: SECRET_PASSPHRASE
Prevedimo primljeni šifrirani ključ u tekstualni oblik koristeći base64: base64 9B695056.gpg.gpg > 9B695056.txt. Sadržaj će biti smješten u varijablu: GPG_KEY_CONTENTS.
Postavljanje izgradnje prilikom guranja koda i stvaranja PR-a
Prvo trebate stvoriti mapu u korijenu vašeg projekta: .github/workflows.
U njemu označite datoteku, npr. gradle-ci-build.yml sa sljedećim sadržajem:
name: build
on:
push:
branches:
- master
- dev
- testing
pull_request:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Set up JDK 8
uses: actions/setup-java@v1
with:
java-version: 8
- name: Build with Gradle
uses: eskatos/gradle-command-action@v1
with:
gradle-version: current
arguments: build -PsonatypeUsername=${{secrets.SONATYPE_USERNAME}} -PsonatypePassword=${{secrets.SONATYPE_PASSWORD}}
Ovaj tijek rada izvršit će se prilikom guranja u grane master, dev и testing, također prilikom kreiranja zahtjeva za povlačenjem.
Odjeljak poslova specificira korake koje treba izvršiti na navedenim događajima. U ovom slučaju gradit ćemo na najnovijoj verziji ubuntua, koristiti Javu 8, a također ćemo koristiti dodatak za Gradle eskatos/gradle-command-action@v1koji će pomoću najnovije verzije alata za izgradnju pokrenuti naredbe navedene u arguments. Varijable secrets.SONATYPE_USERNAME и secrets.SONATYPE_PASSWORD ovo su tajne koje smo ranije pitali.
Rezultati izgradnje odrazit će se na kartici Radnje:
Automatska implementacija kada se objavi novo izdanje
Kreirajmo zasebnu datoteku tijeka rada za automatsku implementaciju gradle-ci-publish.yml:
name: publish
on:
push:
tags:
- 'v*'
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Set up JDK 8
uses: actions/setup-java@v1
with:
java-version: 8
- name: Prepare to publish
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: Publish with Gradle
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}}
Datoteka je gotovo identična prethodnoj, osim događaja u kojem će se pokrenuti. U ovom slučaju, to je događaj stvaranja oznake s nazivom koji počinje s v.
Prije implementacije moramo izdvojiti PGP ključ iz tajni i smjestiti ga u root projekta, kao i dešifrirati ga. Zatim moramo postaviti posebnu varijablu okoline RELEASE_VERSION na koje se pozivamo gradle.build datoteka. Sve se to radi u odjeljku Prepare to publish. Naš ključ dobivamo iz varijable GPG_KEY_CONTENTS, prevodimo ga u gpg datoteku, a zatim ga dekriptiramo stavljanjem u datoteku secret.gpg.
Zatim se okrećemo posebnoj varijabli GITHUB_REF, iz kojeg možemo dobiti verziju koju smo postavili prilikom izrade oznake. Ova varijabla je relevantna u ovom slučaju. refs/tags/v0.0.2 iz kojeg smo odrezali prvih 11 znakova kako bismo dobili specifičnu verziju. Zatim koristimo standardne Gradle naredbe za objavljivanje: test publish
Provjera rezultata implementacije u Sonatype repozitoriju
Nakon što se izdanje izradi, tijek rada opisan u prethodnom odjeljku trebao bi se pokrenuti. Da biste to učinili, izradite izdanje:
ime oznake mora počinjati s v. Ako nakon klika na Objavi izdanje tijek rada uspješno završi, možemo prijeći na Sonatip Nexus kako bi bili sigurni:
Artefakt se pojavio u repozitoriju Staging. Odmah se pojavljuje u statusu Otvoreno, zatim ga je potrebno ručno prebaciti u status Zatvori pritiskom na odgovarajuću tipku. Nakon provjere jesu li ispunjeni svi zahtjevi, artefakt prelazi u status Zatvori i više nije dostupan za izmjene. U ovom će obliku završiti u MavenCentralu. Ako je sve u redu, možete pritisnuti gumb Pustite, a artefakt će završiti u skladištu Sonatype.
Da bi artefakt ušao u MavenCentral, morate ga zatražiti u zadatku koji smo kreirali na samom početku. Ovo trebate učiniti samo jednom, pa objavljujemo prvi put. U sljedećim vremenima to nije potrebno, sve će se automatski sinkronizirati. Brzo su mi uključili sinkronizaciju, ali je trebalo oko 5 dana da artefakt postane dostupan u MavenCentralu.
To je sve, objavili smo naš artefakt u MavenCentralu.