ProHoster > Blogs > AdministrÄcija > Gradle un Github darbÄ«bu izmantoÅ”ana, lai publicÄtu Java projektu Sonatype Maven centrÄlajÄ repozitorijÄ
Gradle un Github darbÄ«bu izmantoÅ”ana, lai publicÄtu Java projektu Sonatype Maven centrÄlajÄ repozitorijÄ
Å ajÄ rakstÄ es vÄlos detalizÄti aplÅ«kot Java artefakta publicÄÅ”anas procesu no jauna, izmantojot Github Actions, Sonatype Maven centrÄlajÄ repozitorijÄ, izmantojot Gradle veidotÄju.
Es nolÄmu uzrakstÄ«t Å”o rakstu, jo trÅ«ka normÄlas apmÄcÄ«bas vienuviet. Visa informÄcija bija jÄvÄc pa gabalu no dažÄdiem avotiem, turklÄt ne gluži svaiga. Kam tas interesÄ, laipni lÅ«dzam zem kaÄ·a.
Repozitorija izveide programmÄ Sonatype
Pirmais solis ir izveidot repozitoriju Sonatype Maven Central. Å im nolÅ«kam mÄs ejam Å”eit, reÄ£istrÄjieties un izveidojiet jaunu uzdevumu, lÅ«dzot mums izveidot repozitoriju. Braucam savÄ Grupas ID projekts, Projekta URL projekta saite un SCM URL saite uz versiju kontroles sistÄmu, kurÄ atrodas projekts. Grupas ID Å”eit ir jÄbÅ«t formÄ com.example, com.example.domain, com.example.testsupport, un tas var bÅ«t arÄ« kÄ saite uz jÅ«su github: github.com/jÅ«sulietotÄjvÄrds -> io.github.jÅ«su lietotÄjvÄrds. JebkurÄ gadÄ«jumÄ jums bÅ«s jÄapstiprina Ŕī domÄna vai profila Ä«paÅ”umtiesÄ«bas. Ja esat norÄdÄ«jis github profilu, jums tiks lÅ«gts izveidot publisku repozitoriju ar vÄlamo nosaukumu.
KÄdu laiku pÄc apstiprinÄÅ”anas tiks izveidots jÅ«su GroupId, un mÄs varam pÄriet uz nÄkamo soli, Gradle konfigurÄciju.
Gradle konfigurÄÅ”ana
RakstÄ«Å”anas laikÄ es neatradu Gradle spraudÅus, kas varÄtu palÄ«dzÄt artefakta publicÄÅ”anÄ. TÄ vienÄ«gais spraudnis, ko atradu, tomÄr autors atteicÄs to turpmÄk atbalstÄ«t. TÄpÄc es nolÄmu visu darÄ«t pats, jo to izdarÄ«t nav pÄrÄk grÅ«ti.
PirmÄ lieta, kas jÄnoskaidro, ir Sonatype prasÄ«bas publicÄÅ”anai. Tie ir Å”Ädi:
Avota kodu un JavaDoc pieejamÄ«ba, ti. jÄpiedalÄs -sources.jar Šø-javadoc.jar failus. KÄ norÄdÄ«ts dokumentÄcijÄ, ja nav iespÄjams nodroÅ”inÄt avota kodus vai dokumentÄciju, varat izveidot manekenu -sources.jar vai -javadoc.jar ar vienkÄrÅ”u README iekÅ”pusÄ, lai nokÄrtotu testu.
Visiem failiem jÄbÅ«t parakstÄ«tiem ar GPG/PGPUn .asc katram failam ir jÄiekļauj fails, kurÄ ir paraksts.
pieejamība pom failu
Pareizas vÄrtÄ«bas groupId, artifactId Šø version. Versija var bÅ«t patvaļīga virkne, un tÄ nevar beigties ar -SNAPSHOT
InformÄcijas klÄtbÅ«tne par licenci, izstrÄdÄtÄjiem un versiju kontroles sistÄmu
Å ie ir pamatnoteikumi, kas jÄievÄro publicÄjot. Pieejama pilna informÄcija Å”eit.
MÄs Ä«stenojam Ŕīs prasÄ«bas build.gradle failu. Vispirms pievienosim visu nepiecieÅ”amo informÄciju par izstrÄdÄtÄjiem, licencÄm, versiju kontroles sistÄmu, kÄ arÄ« iestatÄ«sim projekta URL, nosaukumu un aprakstu. UzrakstÄ«sim vienkÄrÅ”u metodi Å”im nolÅ«kam:
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]'
}
}
}
}
}
TÄlÄk jums tas jÄnorÄda Ä£enerÄtÄs montÄžas laikÄ -sources.jar Šø-javadoc.jar failus. Å ai sadaļai java jums jÄpievieno sekojoÅ”ais:
java {
withJavadocJar()
withSourcesJar()
}
PÄriesim pie pÄdÄjÄs prasÄ«bas ā GPG/PGP paraksta iestatÄ«Å”anas. Lai to izdarÄ«tu, pievienojiet spraudni signing:
plugins {
id 'signing'
}
Un pievienojiet 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 sonatypeLietotÄjvÄrds Šø sonatypeParole mainÄ«gie, kas satur reÄ£istrÄcijas laikÄ izveidoto pieteikumvÄrdu un paroli sonatype.org.
LÄ«dz ar to finÄls build.gradle izskatÄ«sies Å”Ädi:
Pilns build.gradle kods
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]'
}
}
}
}
}
Es vÄlos atzÄ«mÄt, ka mÄs iegÅ«stam versiju no vides mainÄ«gÄ: System.getenv('RELEASE_VERSION'). MÄs to atklÄsim montÄžas laikÄ un Åemsim no taga nosaukuma.
PGP atslÄgu Ä£enerÄÅ”ana
Viena no Sonatype prasÄ«bÄm ir, ka visi faili ir jÄparaksta ar GPG/PGP atslÄgu. Å im nolÅ«kam mÄs ejam Å”eit un lejupielÄdÄjiet GnuPG utilÄ«tu savai operÄtÄjsistÄmai.
MÄs uzzinÄm id mÅ«su atslÄga ar komandu: gpg --list-secret-keys --keyid-format short. Id tiks norÄdÄ«ts aiz slÄ«psvÄ«tras, piemÄram: rsa2048/9B695056
MÄs eksportÄjam slepeno atslÄgu uz patvaļīgu vietu, mums tÄ bÅ«s nepiecieÅ”ama nÄkotnÄ: gpg --export-secret-key 9B695056 > D:\gpg\9B695056.gpg
Github darbību iestatīŔana
PÄrejam uz pÄdÄjo posmu, iestatÄ«sim bÅ«vniecÄ«bu un automÄtisku publicÄÅ”anu, izmantojot Github Actions.
Github Actions ir lÄ«dzeklis, kas ļauj automatizÄt darbplÅ«smu, ievieÅ”ot pilnu CI/CD ciklu. VeidoÅ”anu, testÄÅ”anu un izvietoÅ”anu var izraisÄ«t dažÄdi notikumi: koda nosÅ«tÄ«Å”ana, laidiena izveide vai problÄmas. Å Ä« funkcionalitÄte publiskajÄm krÄtuvÄm ir pilnÄ«gi bez maksas.
Å ajÄ sadaÄ¼Ä es jums parÄdÄ«Å”u, kÄ iestatÄ«t izveides un nosÅ«tÄ«Å”anas kodu un izvietot Sonatype repozitorijÄ izlaiÅ”anas laikÄ, kÄ arÄ« iestatÄ«t noslÄpumus.
MÄs izvirzÄm noslÄpumus
AutomÄtiskai montÄžai un izvietoÅ”anai mums ir nepiecieÅ”amas vairÄkas slepenas vÄrtÄ«bas, piemÄram, atslÄgas ID, parole, ko ievadÄ«jÄm, Ä£enerÄjot atslÄgu, pati PGP atslÄga un Sonatype pieteikÅ”anÄs/parole. Varat tos iestatÄ«t Ä«paÅ”Ä krÄtuves iestatÄ«jumu sadaļÄ:
MÄs iestatÄm Å”Ädus mainÄ«gos:
SONATYPE_USERNAME/SONATYPE_PASSWORD ā pieteikumvÄrds/parole, ko ievadÄ«jÄm, reÄ£istrÄjoties Sonatype
SIGNING_KEYID/SIGNING_PASSWORD ā Ä£enerÄÅ”anas laikÄ iestatÄ«ts PGP atslÄgas ID un parole.
Es vÄlos sÄ«kÄk pakavÄties pie mainÄ«gÄ GPG_KEY_CONTENTS. Fakts ir tÄds, ka publicÄÅ”anai mums ir nepiecieÅ”ama privÄta PGP atslÄga. Lai to ievietotu noslÄpumos, es izmantoju instrukcija un papildus veica vairÄkas darbÄ«bas.
Å ifrÄsim mÅ«su atslÄgu ar gpg: gpg --symmetric --cipher-algo AES256 9B695056.gpgievadot paroli. Tas jÄievieto mainÄ«gajÄ: SECRET_PASSPHRASE
Tulkosim saÅemto Å”ifrÄto atslÄgu teksta formÄ, izmantojot base64: base64 9B695056.gpg.gpg > 9B695056.txt. Saturs tiks ievietots mainÄ«gajÄ: GPG_KEY_CONTENTS.
Veidojiet iestatījumus, nospiežot kodu un veidojot PR
Vispirms jums ir jÄizveido mape sava projekta saknÄ: .github/workflows.
TajÄ atzÄ«mÄjiet failu, piemÄram, gradle-ci-build.yml ar Å”Ädu 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}}
Å Ä« darbplÅ«sma tiks izpildÄ«ta, virzot uz filiÄlÄm master, dev Šø testing, arÄ« veidojot izvilkÅ”anas pieprasÄ«jumus.
Darbu sadaÄ¼Ä ir norÄdÄ«tas darbÄ«bas, kas jÄveic norÄdÄ«tajos notikumos. Å ajÄ gadÄ«jumÄ mÄs izmantosim jaunÄko ubuntu versiju, izmantosim Java 8, kÄ arÄ« izmantosim Gradle spraudni. eskatos/gradle-command-action@v1kas, izmantojot jaunÄko veidotÄja versiju, izpildÄ«s komandas, kas norÄdÄ«tas arguments. MainÄ«gie lielumi secrets.SONATYPE_USERNAME Šø secrets.SONATYPE_PASSWORD Å”ie ir noslÄpumi, kurus mÄs jautÄjÄm iepriekÅ”.
BÅ«vÄÅ”anas rezultÄti tiks atspoguļoti cilnÄ DarbÄ«bas:
AutomÄtiska izvietoÅ”ana, kad tiek izlaists jauns laidiens
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}}
Fails ir gandrÄ«z identisks iepriekÅ”Äjam, izÅemot notikumu, kurÄ tas tiks aktivizÄts. Å ajÄ gadÄ«jumÄ tiek izveidots tags ar nosaukumu, kas sÄkas ar v.
Pirms izvietoÅ”anas mums ir jÄizÅem PGP atslÄga no noslÄpumiem un jÄievieto projekta saknÄ, kÄ arÄ« jÄatÅ”ifrÄ. TÄlÄk mums jÄiestata Ä«paÅ”s vides mainÄ«gais RELEASE_VERSION uz kuru mÄs atsaucamies gradle.build failu. Tas viss tiek darÄ«ts sadaÄ¼Ä Prepare to publish. MÄs iegÅ«stam savu atslÄgu no mainÄ«gÄ GPG_KEY_CONTENTS, tulkojam to gpg failÄ un pÄc tam atÅ”ifrÄjam, ievietojot to failÄ. secret.gpg.
TÄlÄk mÄs pievÄrÅ”amies Ä«paÅ”am mainÄ«gajam GITHUB_REF, no kuras mÄs varam iegÅ«t versiju, kuru iestatÄ«jÄm, veidojot tagu. Å is mainÄ«gais ir bÅ«tisks Å”ajÄ gadÄ«jumÄ. refs/tags/v0.0.2 no kuriem mÄs nogriezÄm pirmÄs 11 rakstzÄ«mes, lai iegÅ«tu konkrÄtu versiju. TÄlÄk publicÄÅ”anai izmantojam standarta Gradle komandas: test publish
Kad laidiens ir izveidots, jÄsÄk darbplÅ«sma, kas aprakstÄ«ta iepriekÅ”ÄjÄ sadaļÄ. Lai to izdarÄ«tu, izveidojiet laidienu:
taga nosaukumam jÄsÄkas ar v. Ja pÄc noklikŔķinÄÅ”anas uz PublicÄt laidienu darbplÅ«sma ir veiksmÄ«gi pabeigta, mÄs varam pÄriet uz Sonatype Nexus lai pÄrliecinÄtos, ka:
Artefakts parÄdÄ«jÄs Staging repozitorijÄ. Tas uzreiz parÄdÄs Open statusÄ, pÄc tam tas manuÄli jÄpÄrnes uz statusu Close, nospiežot atbilstoÅ”o pogu. PÄrbaudot, vai visas prasÄ«bas ir izpildÄ«tas, artefakts nonÄk statusÄ AizvÄrt un vairs nav pieejams modifikÄcijai. Å ajÄ formÄ tas nonÄks MavenCentral. Ja viss ir kÄrtÄ«bÄ, varat nospiest pogu Atlaidiet, un artefakts nonÄks Sonatype krÄtuvÄ.
Lai artefakts iekļūtu MavenCentral, jums tas ir jÄlÅ«dz uzdevumÄ, kuru izveidojÄm paÅ”Ä sÄkumÄ. Jums tas jÄdara tikai vienu reizi, tÄpÄc mÄs publicÄjam pirmo reizi. TurpmÄkajos laikos tas nav nepiecieÅ”ams, viss tiks sinhronizÄts automÄtiski. ViÅi man Ätri ieslÄdza sinhronizÄciju, taÄu pagÄja apmÄram 5 dienas, lÄ«dz artefakts kļuva pieejams MavenCentral.
Tas arÄ« viss, mÄs esam publicÄjuÅ”i savu artefaktu MavenCentral.