Šajā rakstā es gribu detalizēti apskatīt Java artefakta publicēšanas procesu no nulles, izmantojot Github Actions Sonatype Maven Central Repository ar Gradle būvētāju.
Šo rakstu nolēmu uzrakstīt, ņemot vērā normāla pamācības trūkumu vienā vietā. Visiem pieejamajiem informācijas fragmentiem nācās tikt savāktiem no dažādiem avotiem, turklāt ne visai svaigiem. Kam interesē, laipni lūdzam zemāk.
Repotārija izveide Sonatype
Pirmajā posmā mums jāizveido repotārijs Sonatype Maven Central. Tādēļ dodamies , reģistrējamies un izveidojam jaunu uzdevumu, lūdzot izveidot mums repotāriju. Ievadām savu GroupId projekta, Projekta URL projekta saiti un SCM url saiti uz versiju kontroles sistēmu, kurā atrodas projekts. GroupId šim jābūt formātā com.example, com.example.domain, com.example.testsupport, kā arī var būt jūsu Github saite: -> io.github.yourusername. Jebkurā gadījumā jums būs jāapstiprina šī domēna vai profila īpašumtiesības. Ja norādījāt Github profilu, tiks lūgts izveidot publisku repotāriju ar nepieciešamo nosaukumu.
Pēc kāda laika pēc apstiprināšanas jūsu GroupId tiks izveidots, un mēs varam pāriet uz nākamo soli, Gradle konfigurāciju.
Konfigurējam Gradle
Raksta rakstīšanas brīdī es neatradu Gradle spraudņus, kas varētu palīdzēt publicēšanas procesā. vienīgais spraudnis, ko es atradu, bet autora atsakās no turpmākās atbalsta. Tādēļ es nolēmu visu izdarīt pats, jo to izdarīt nav tik grūti.
Pirmais, kas jānoskaidro, ir Sonatype pieprasījumi publicēšanai. Tie ir sekojoši:
- Būtiski ir nodrošināt avota kodus un JavaDoc, t.i., jābūt pieejamiem
-sources.jarun-javadoc.jarfailiem. Kā minēts dokumentācijā, ja nav iespējams nodrošināt avota kodus vai dokumentāciju, var izveidot tukšu failu-sources.jarvai-javadoc.jarar vienkāršu README iekšā, lai izietu pārbaudi. - Visiem failiem jābūt parakstītiem ar
GPG/PGP, un.ascfails, kas satur parakstu, jākļūst iekļautam katrā failā. - Nodrošina
pomfaila - Korekti vērtības
groupId,artifactIdunversion. Versijai var būt jebkāda virkne, un tai nedrīkst beigties-SNAPSHOT - Nepieciešama
name,aprakstsunurl - Informācijai par licencēm, izstrādātājiem un versiju kontroles sistēmu
Šie ir galvenie noteikumi, kas jāievēro publicēšanas procesā. Pilna informācija ir pieejama .
Ieviešam šos pieprasījumus build.gradle failā. Lai sāktu, pievienosim visu nepieciešamo informāciju par izstrādātājiem, licenci, versiju kontroli, kā arī norādīsim URL, nosaukumu un projekta aprakstu. Tādēļ uzrakstīsim vienkāršu metodi:
def customizePom(pom) {
pom.withXml {
def root = asNode()
root.dependencies.removeAll { dep ->
dep.scope == "test"
}
root.children().last() + {
resolveStrategy = DELEGATE_FIRST
description 'Kāds artefakta apraksts'
name 'Artefakta nosaukums'
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 '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.lv'
}
}
}
}
}Tālāk jānorāda, ka būvēšanas laikā nepieciešams ģenerēt -sources.jar un-javadoc.jar failus. Tādēļ sadaļā java jāievada sekojošais:
java {
withJavadocJar()
withSourcesJar()
}Pāriesim pie pēdējā prasība, GPG/PGP paraksta konfigurācija. Tādēļ pievienosim spraudni signing:
plugins {
id 'signing'
}Un pievienosim sadaļu:
signing {
sign publishing.publications
}Visbeidzot, pievienosim sadaļu 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
}
}
}
}Šeit sonatypeUsername un sonatypePassword mainīnes, kas satur lietotājvārdu un paroli, izveidotās reģistrējoties .
Tādējādi, galīgais build.gradle izskatīsies šādi:
Pilns kods build.gradle
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.lv'
}
}
}
}
}Vēlos piebilst, ka versiju iegūstam no vides mainīgā: System.getenv('RELEASE_VERSION'). Mēs to iestatīsim būvēšanas procesā un ņemsim no taga nosaukuma.
PGP atslēgas ģenerēšana
Viens no Sonatype prasībām ir visu failu parakstīšana, izmantojot GPG/PGP atslēgu. Tāpēc dodamies un lejupielādējam GnuPG utilītu savai operētājsistēmai.
- Ģenerējam atslēgu pāri:
gpg --gen-key, ievadām lietotāja vārdu, e-pastu un nosakām paroli. - Noskaidrojam
idmūsu atslēgas ar komandu:gpg --list-secret-keys --keyid-format short. Id tiks norādīts pēc slīpsvītras, piemēram: rsa2048/9B695056 - Publicējam publisko atslēgu uz serveri ar komandu:
gpg --keyserver [https://keys.openpgp.org](https://keys.openpgp.org/) --send-keys 9B695056 - Eksportējam slepeno atslēgu uz jebkuru vietu, tā mums noderēs nākotnē:
gpg --export-secret-key 9B695056 > D:\gpg\9B695056.gpg
Iestatām Github Actions
Pārejam uz noslēguma posmu, iestatīsim būvēšanu un automātisko publikāciju, izmantojot Github Actions.
Github Actions – funkcionalitāte, kas ļauj automatizēt darba procesus, realizējot pilnu CI/CD ciklu. Kompilācija, testēšana un izvietošana var tikt izsauktas ar dažādiem notikumiem: koda nosūtīšana, laidiena vai problēmu izveide. Šī funkcionalitāte ir pilnīgi bez maksas publiskajiem repozitorijiem.
Šajā sadaļā es parādīšu, kā iestatīt kompilāciju un koda nosūtīšanu, kā arī izvietošanu Sonatype repozitorijā, kad tiek laists klajā laidienu, un kā iestatīt slepenos datus.
Iestādām slepenos datus
Automātiskai kompilācijai un izvietošanai mums būs nepieciešami vairāki slepenie vērtības, piemēram, atslēgas ID, parole, kuru mēs ievadījām, ģenerējot atslēgu, pati PGP atslēga, kā arī lietotājvārds/parole uz Sonatype. Tos var iestatīt īpašā sadaļā repozitorija iestatījumos:

Iestādām šādas mainīgās:
- SONATYPE_USERNAME/SONATYPE_PASSWORD — lietotājvārds/parole, kuru mēs ievadījām reģistrējoties Sonatype
- SIGNING_KEYID/SIGNING_PASSWORD — PGP atslēgas ID un parole, kas iestatīta tās ģenerēšanas brīdī.
Par mainīgo GPG_KEY_CONTENTS vēlos apstāties sīkāk. Proti, mums publicēšanai nepieciešama privātā PGP atslēga. Lai to ievietotu slepenajos datus, es izmantoju un papildus veicu vairākus pasākumus.
- Iezīmēsim mūsu atslēgu, izmantojot gpg:
gpg --symmetric --cipher-algo AES256 9B695056.gpg, ievadot paroli. To vajadzētu ievietot mainīgajā: SECRET_PASSPHRASE - Pārvērsīsim iegūto šifrēto atslēgu tekstveidīgā formātā, izmantojot base64:
base64 9B695056.gpg.gpg > 9B695056.txt. Saturu izvietosim mainīgajā: GPG_KEY_CONTENTS.
Iestatīšana kompilācijai, nosūtot kodu un veidojot PR
Vispirms jāizveido mape jūsu projekta saknē: .github/workflows.
Tajā jānovieto fails, piemēram, gradle-ci-build.yml ar sekojošo saturu:
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}}Šis darba process tiks izpildīts, nosūtot uz zariem master, dev un testing, kā arī veidojot pull pieprasījumus.
Jobs sadaļā ir norādīti soļi, kas jāveic, ņemot vērā minētās izvēlētās darbības. Šajā gadījumā mēs kompilēsim uz jaunākās ubuntu versijas, izmantosim Java 8 un speciālo spraudni Gradle eskatos/gradle-command-action@v1, kas, izmantojot jaunāko versiju, palaiž komandas, kas norādītas arguments. Mainīgās secrets.SONATYPE_USERNAME un secrets.SONATYPE_PASSWORD tie ir noslēpumi, kurus mēs iepriekš iestatījām.
Veiksmīgā būvē rezultāti tiks atspoguļoti cilnē Actions:

Automātiska izvietošana jaunā laidiena izdošanas laikā
Automātiskai izvietošana izveidosim atsevišķu darba procesa failu gradle-ci-publish.yml:
name: publish
on:
push:
tags:
- 'v*'
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Iestatīt JDK 8
uses: actions/setup-java@v1
with:
java-version: 8
- name: Sagatavot publikācijai
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ācija ar 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}}Fails praktiski ir identisks iepriekšējam, izņemot notikumu, kad tas tiks izpildīts. Šajā gadījumā tas ir notikums, kad tiek izveidots tag, kura nosaukums sākas ar v.
Pirms izvietošanas mums ir jāņem PGP atslēga no noslēpumiem un jānovieto to projekta saknē, kā arī jāatšifrē. Turpmāk mums ir jāiestata īpaša vides mainīgā RELEASE_VERSION , kuru mēs izmantojam gradle.build failā. Viss šis process tiek veikts sadaļā Sagatavot publikācijai. Mēs iegūstam mūsu atslēgu no maiņīgā GPG_KEY_CONTENTS, pārvēršam to gpg failā, pēc tam to atšifrējam, ievietojot failā secret.gpg.
Tālāk mēs piekļūstam īpašajai maiņīgajai GITHUB_REF, no kuras varam iegūt versiju, kuru mēs iestatījām, izveidojot tagu. Šai maiņīgajai šajā gadījumā ir vērtība refs/tags/v0.0.2 , no kuras mēs noņemam pirmos 11 simbolus, lai iegūtu tieši versiju. Pēc tam standartā izmantojam Gradle komandas publikācijai: test publish
Pārbaudīt rezultātus izvietošanai Sonatype krātuvē
Pēc laidiena izveidošanas vajadzētu uzsākt darba procesu, kas aprakstīts iepriekšējā sadaļā. Lai to izdarītu, izveidojam laidienu:

šajā gadījumā tagam jāuzsākas ar v. Ja pēc Publish release nospiešanas darba process veiksmīgi noslēdzas, mēs varam doties uz , lai to pārliecinātos:

Artifacts aparecās Staging repozitorijā. Tas sākotnēji parādās ar statusu Open, pēc tam to manuāli jāmaina uz statusu Close, nospiežot attiecīgo pogu. Pēc visu prasību izpildes pārbaudes artifacts tiek pārvērsts statusā Close un vairs nav pieejams izmaiņām. Šādā formā tas nonāks MavenCentral. Ja viss ir labi, varat nospiest pogu Izlaidums, šajā gadījumā artifacts nonāks Sonatype repozitorijā.
Lai artifacts nonāktu MavenCentral, ir jāpiesakās tam uz uzdevumu, kuru mēs izveidojām sākumā. Tas jādara tikai vienu reizi, jo mēs publicējam to pirmo reizi. Nākamajās reizēs tas nav nepieciešams, viss tiks sinhronizēts automātiski. Sinhronizācija tika ieslēgta ātri, taču, lai artifacts kļūtu pieejams MavenCentral, pagāja apmēram 5 dienas.
Šeit viss ir paveikts, mēs esam publicējuši savu artifact MavenCentral.
Noderīgas saites
- Līdzīgs , tikai publicēšana caur maven
- Staging Sonatype
- Sonatype, kurā ir jāizveido uzdevums
- repozitorijā, kur viss ir iestatīts
Avots: habr.com
