ProHoster > Dienoraštis > Administravimas > „Gradle“ ir „Github“ veiksmų naudojimas „Java“ projektui paskelbti „Sonatype Maven“ centrinėje saugykloje
„Gradle“ ir „Github“ veiksmų naudojimas „Java“ projektui paskelbti „Sonatype Maven“ centrinėje saugykloje
Šiame straipsnyje noriu išsamiai apžvelgti „Java“ artefakto publikavimo procesą nuo nulio iki „Github Actions“ iki „Sonatype Maven“ centrinės saugyklos naudojant „Gradle“ kūrimo priemonę.
Nusprendžiau parašyti šį straipsnį, nes vienoje vietoje trūko įprastos pamokos. Visą informaciją reikėjo rinkti po gabalėlį iš įvairių šaltinių, be to, ne visai šviežią. Kam rūpi, sveiki atvykę po katinu.
Saugyklos kūrimas „Sonatype“.
Pirmasis žingsnis yra sukurti saugyklą Sonatype Maven Central. Dėl to einame čia, užsiregistruokite ir sukurkite naują užduotį, prašydami mūsų sukurti saugyklą. Važiuojame savo Grupės ID projektas, Projekto URL projekto nuoroda ir SCM url nuoroda į versijų valdymo sistemą, kurioje yra projektas. Grupės ID čia turėtų būti com.example, com.example.domain, com.example.testsupport, taip pat gali būti nuoroda į jūsų github: github.com/yourusername -> io.github.yourusername. Bet kokiu atveju turėsite patvirtinti šio domeno ar profilio nuosavybės teisę. Jei nurodėte „github“ profilį, jūsų bus paprašyta sukurti viešą saugyklą norimu pavadinimu.
Praėjus šiek tiek laiko po patvirtinimo, jūsų grupės ID bus sukurtas ir galėsime pereiti prie kito veiksmo – „Gradle“ konfigūravimo.
„Gradle“ konfigūravimas
Rašymo metu neradau „Gradle“ papildinių, kurie galėtų padėti paskelbti artefaktą. Jis vienintelis įskiepis, kurį radau, tačiau autorius atsisakė toliau jį palaikyti. Todėl nusprendžiau viską daryti pats, nes tai padaryti nėra labai sunku.
Pirmas dalykas, kurį reikia išsiaiškinti, yra „Sonatype“ reikalavimai leidybai. Jie yra šie:
Šaltinio kodų ir JavaDoc prieinamumas, ty. privalo dalyvauti -sources.jar и-javadoc.jar failus. Kaip nurodyta dokumentacijoje, jei neįmanoma pateikti šaltinio kodų ar dokumentų, galite padaryti manekeną -sources.jar arba -javadoc.jar su paprastu README viduje, kad išlaikytumėte testą.
Visi failai turi būti pasirašyti GPG/PGPIr .asc prie kiekvieno failo turi būti įtrauktas failas su parašu.
Prieinamumas pom failą
Teisingos vertės groupId, artifactId и version. Versija gali būti savavališka eilutė ir negali baigtis -SNAPSHOT
Reikalingas buvimas name, description и url
Informacijos apie licenciją, kūrėjus ir versijų valdymo sistemą buvimas
Tai yra pagrindinės taisyklės, kurių privalu laikytis skelbiant. Yra visa informacija čia.
Šiuos reikalavimus įgyvendiname build.gradle failą. Pirmiausia pridėkime visą reikiamą informaciją apie kūrėjus, licencijas, versijų valdymo sistemą, taip pat nustatykime projekto URL, pavadinimą ir aprašymą. Parašykime paprastą metodą:
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]'
}
}
}
}
}
Tada turite tai nurodyti sugeneruoto surinkimo metu -sources.jar и-javadoc.jar failus. Šiam skyriui java reikia pridėti šiuos dalykus:
java {
withJavadocJar()
withSourcesJar()
}
Pereikime prie paskutinio reikalavimo – GPG/PGP parašo nustatymo. Norėdami tai padaryti, prijunkite priedą signing:
plugins {
id 'signing'
}
Ir pridėkite skyrių:
signing {
sign publishing.publications
}
Galiausiai pridėkime skyrių 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
}
}
}
}
Čia sonatype Vartotojo vardas и sonatypePassword kintamieji, kuriuose yra prisijungimo vardas ir slaptažodis, sukurti registracijos metu sonatype.org.
Taigi finalas build.gradle atrodys taip:
Visas build.gradle kodas
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]'
}
}
}
}
}
Noriu pažymėti, kad versiją gauname iš aplinkos kintamojo: System.getenv('RELEASE_VERSION'). Mes jį atskleisime surinkimo metu ir paimsime iš žymos pavadinimo.
PGP raktų generavimas
Vienas iš Sonatype reikalavimų yra tas, kad visi failai būtų pasirašyti GPG/PGP raktu. Dėl to einame čia ir atsisiųskite savo operacinei sistemai skirtą GnuPG priemonę.
Sukuriame raktų porą: gpg --gen-key, įveskite vartotojo vardą, el. pašto adresą ir taip pat nustatykite slaptažodį.
Sužinome id mūsų raktas su komanda: gpg --list-secret-keys --keyid-format short. ID bus nurodytas po pasvirojo brūkšnio, pavyzdžiui: rsa2048/9B695056
Viešojo rakto paskelbimas serveryje https://keys.openpgp.org pagal komandą: gpg --keyserver [https://keys.openpgp.org](https://keys.openpgp.org/) --send-keys 9B695056
Slaptąjį raktą eksportuojame į savavališką vietą, jo mums prireiks ateityje: gpg --export-secret-key 9B695056 > D:\gpg\9B695056.gpg
„Github“ veiksmų nustatymas
Pereikime prie paskutinio etapo, nustatykite kūrimą ir automatiškai paskelbkite naudodami „Github Actions“.
„Github Actions“ yra funkcija, leidžianti automatizuoti darbo eigą įgyvendinant visą CI / CD ciklą. Sukūrimą, testavimą ir diegimą gali suaktyvinti įvairūs įvykiai: kodo siuntimas, leidimo kūrimas ar problemos. Ši funkcija yra visiškai nemokama viešosioms saugykloms.
Šiame skyriuje parodysiu, kaip nustatyti kūrimo ir siuntimo kodą ir įdiegti į Sonatype saugyklą išleidus, taip pat nustatyti paslaptis.
Mes nustatome paslaptis
Automatiniam surinkimui ir diegimui mums reikia kelių slaptų reikšmių, tokių kaip rakto ID, slaptažodis, kurį įvedėme generuodami raktą, pats PGP raktas ir Sonatype prisijungimo/slaptažodis. Galite juos nustatyti specialioje saugyklos nustatymų skiltyje:
Mes nustatome šiuos kintamuosius:
SONATYPE_USERNAME / SONATYPE_PASSWORD – prisijungimo vardas / slaptažodis, kurį įvedėme registruodamiesi „Sonatype“
SIGNING_KEYID/SIGNING_PASSWORD – generuojant nustatytas PGP rakto ID ir slaptažodis.
Noriu pasilikti prie kintamojo GPG_KEY_CONTENTS išsamiau. Faktas yra tas, kad publikavimui mums reikia privataus PGP rakto. Norėdamas paskelbti jį paslaptyse, aš naudojau instrukcija ir papildomai atliko keletą veiksmų.
Užšifruokime savo raktą su gpg: gpg --symmetric --cipher-algo AES256 9B695056.gpgįvesdami slaptažodį. Jis turėtų būti įdėtas į kintamąjį: SECRET_PASSPHRASE
Išverskime gautą užšifruotą raktą į tekstinę formą naudodami base64: base64 9B695056.gpg.gpg > 9B695056.txt. Turinys bus patalpintas į kintamąjį: GPG_KEY_CONTENTS.
Sukurkite sąranką stumdami kodą ir kurdami PR
Pirmiausia turite sukurti aplanką savo projekto šaknyje: .github/workflows.
Jame pažymėkite failą, pavyzdžiui, gradle-ci-build.yml su tokiu turiniu:
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}}
Ši darbo eiga bus vykdoma stumiant į šakas master, dev и testing, taip pat kuriant ištraukimo užklausas.
Užduočių skiltyje nurodomi veiksmai, kurie turi būti atlikti su nurodytais įvykiais. Tokiu atveju mes remsimės naujausia ubuntu versija, naudosime Java 8, taip pat naudosime Gradle įskiepį eskatos/gradle-command-action@v1kuri, naudojant naujausią kūrimo priemonės versiją, vykdys komandas, nurodytas arguments. Kintamieji secrets.SONATYPE_USERNAME и secrets.SONATYPE_PASSWORD tai paslaptys, kurių klausėme anksčiau.
Kūrimo rezultatai bus rodomi skirtuke Veiksmai:
Automatinis diegimas, kai išleidžiamas naujas leidimas
Sukurkime atskirą darbo eigos failą automatiniam diegimui 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}}
Failas yra beveik identiškas ankstesniam, išskyrus įvykį, kurio metu jis bus suaktyvintas. Šiuo atveju tai yra žymos su pavadinimu, prasidedančiu raide v, sukūrimo įvykis.
Prieš diegdami turime išgauti PGP raktą iš paslapčių ir įdėti jį į projekto šaknį, taip pat iššifruoti. Tada turime nustatyti specialų aplinkos kintamąjį RELEASE_VERSION kuria mes remiamės gradle.build failą. Visa tai daroma skyriuje Prepare to publish. Mes gauname raktą iš kintamojo GPG_KEY_CONTENTS, išverčiame jį į gpg failą, tada iššifruojame įdėdami į failą secret.gpg.
Toliau kreipiamės į specialų kintamąjį GITHUB_REF, iš kurio galime gauti versiją, kurią nustatėme kurdami žymą. Šis kintamasis yra svarbus šiuo atveju. refs/tags/v0.0.2 iš kurių nupjauname pirmuosius 11 simbolių, kad gautume konkrečią versiją. Tada publikavimui naudojame standartines Gradle komandas: test publish
Tikrinami diegimo rezultatai „Sonatype“ saugykloje
Sukūrus leidimą, turėtų prasidėti ankstesniame skyriuje aprašyta darbo eiga. Norėdami tai padaryti, sukurkite leidimą:
žymos pavadinimas turi prasidėti raide v. Jei spustelėjus Paskelbti leidimą darbo eiga sėkmingai baigta, galime pereiti prie „Sonatype Nexus“ įsitikinti:
Artefaktas pasirodė „Stage“ saugykloje. Jis iš karto pasirodo „Open“ būsenoje, tada jį reikia rankiniu būdu perkelti į „Close“ būseną, paspaudus atitinkamą mygtuką. Patikrinus, ar tenkinami visi reikalavimai, artefaktas pereina į būseną Uždaryti ir jo nebegalima keisti. Šioje formoje jis pateks į MavenCentral. Jei viskas gerai, galite paspausti mygtuką Atleiskite, ir artefaktas pateks į Sonatype saugyklą.
Kad artefaktas patektų į MavenCentral, turite jo paprašyti užduotyje, kurią sukūrėme pačioje pradžioje. Tai padaryti reikia tik vieną kartą, todėl skelbiame pirmą kartą. Vėlesniais laikais to nereikia, viskas bus sinchronizuojama automatiškai. Jie man greitai įjungė sinchronizavimą, bet prireikė maždaug 5 dienų, kol artefaktas buvo pasiekiamas MavenCentral.
Tai viskas, mes paskelbėme savo artefaktą MavenCentral.