Ushbu maqolada men Gradle quruvchisi yordamida Github Actions orqali Sonatype Maven markaziy omboriga Java artefaktini noldan nashr qilish jarayonini batafsil ko'rib chiqmoqchiman.
Bir joyda tegishli o'quv qo'llanmasi yo'qligi sababli ushbu maqolani yozishga qaror qildim. Barcha ma'lumotlar turli manbalardan to'planishi kerak edi, ularning ba'zilari to'liq yangilanmagan. Agar qiziqsangiz, quyida xush kelibsiz.
Sonatype-da ombor yaratish
Birinchi qadam Sonatype Maven Central-da omborni yaratishdir. Buni amalga oshirish uchun quyidagi manzilga o'ting , ro'yxatdan o'ting va biz uchun ombor yaratishni so'rab, yangi vazifa yarating. O'zingizni kiriting GroupId loyiha, Loyiha manzili loyihaga havola va SCM url loyiha joylashgan versiyani boshqarish tizimiga havola. GroupId Bu com.example, com.example.domain, com.example.testsupport kabi bo'lishi kerak va GitHub-ga havola ham bo'lishi mumkin: -> io.github. foydalanuvchi ismingiz. Ikkala holatda ham ushbu domen yoki profilga egalik huquqini tasdiqlashingiz kerak bo‘ladi. Agar siz GitHub profilini ko'rsatgan bo'lsangiz, sizdan kerakli nom bilan umumiy ombor yaratishingiz so'raladi.
Tasdiqlashdan bir muncha vaqt o'tgach, sizning GroupIdingiz yaratiladi va biz keyingi bosqichga, Gradle konfiguratsiyasiga o'tishimiz mumkin.
Gradle sozlanmoqda
Yozish paytida men artefaktni nashr etishda yordam beradigan Gradle plaginlarini topmadim. Men topgan yagona plagin, lekin muallif uni qo'llab-quvvatlashdan bosh tortdi. Shuning uchun men buni o'zim qilishga qaror qildim, xayriyatki, bu unchalik qiyin emas edi.
Siz bilishingiz kerak bo'lgan birinchi narsa - Sonatype nashriyotiga qo'yiladigan talablar. Ular quyidagicha:
- Manba kodlari va JavaDoc mavjudligi, ya'ni mavjud bo'lishi kerak
-sources.jarи-javadoc.jarfayllar. Hujjatlarda aytilganidek, agar manba kodini yoki hujjatlarni taqdim etishning iloji bo'lmasa, qo'g'irchoq yaratilishi mumkin.-sources.jaryoki-javadoc.jarsinovdan o'tish uchun ichida oddiy README bilan. - Barcha fayllar bilan imzolangan bo'lishi kerak
GPG/PGPva.ascHar bir fayl uchun imzoni o'z ichiga olgan fayl kiritilishi kerak. - Mavjudlik
pomfayl - To'g'ri qiymatlar
groupId,artifactIdиversionVersiya har qanday satr bo'lishi mumkin va u bilan tugamaydi-SNAPSHOT - Mavjudlik talab qilinadi
name,descriptionиurl - Litsenziya, ishlab chiquvchilar va versiyalarni boshqarish tizimi haqida ma'lumotlarning mavjudligi
Nashr qilishda rioya qilish kerak bo'lgan asosiy qoidalar bu. To'liq ma'lumotlar mavjud. .
Biz ushbu talablarni amalga oshiramiz build.gradle fayl. Birinchidan, ishlab chiquvchilar, litsenziya, versiya boshqaruv tizimi haqida barcha kerakli ma'lumotlarni qo'shamiz, shuningdek, loyiha URL manzilini, nomini va tavsifini o'rnatamiz. Buning uchun oddiy usulni yozamiz:
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@dev.ru'
}
}
}
}
}Keyinchalik, yig'ish paytida quyidagilar yaratilishi kerakligini belgilashingiz kerak: -sources.jar и-javadoc.jar fayllar. Buning uchun bo'limga o'ting java quyidagilarni qo'shishingiz kerak:
java {
withJavadocJar()
withSourcesJar()
}Keling, oxirgi talabga o'tamiz: GPG/PGP imzosini o'rnatish. Buning uchun plaginni yoqamiz. signing:
plugins {
id 'signing'
}Va bo'limni qo'shamiz:
signing {
sign publishing.publications
}Va nihoyat, bo'limni qo'shamiz 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
}
}
}
}u sonatypeFoydalanuvchi nomi и sonatypeParol ro'yxatga olish paytida yaratilgan login va parolni o'z ichiga olgan o'zgaruvchilar .
Shunday qilib, final build.gradle quyidagicha ko'rinadi:
To'liq build.gradle kodi
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'
}
}
}
}
}Shuni ta'kidlashni istardimki, biz versiyani muhit o'zgaruvchisidan olamiz: System.getenv('RELEASE_VERSION')Biz uni yig'ish paytida o'rnatamiz va teg nomidan olamiz.
PGP kalitlarini yaratish
Sonatype talablaridan biri barcha fayllarni GPG/PGP kaliti bilan imzolashdir. Buni amalga oshirish uchun quyidagi manzilga o'ting va operatsion tizimingiz uchun GnuPG yordam dasturini yuklab oling.
- Kalitlar juftligini yarating:
gpg --gen-key, foydalanuvchi nomingizni, elektron pochtangizni kiriting va parol o'rnating. - Keling, bilib olaylik
idbuyruq bilan bizning kalitimiz:gpg --list-secret-keys --keyid-format shortID chiziqdan keyin ko'rsatiladi, masalan: rsa2048/9B695056 - Ochiq kalitni serverga e'lon qiling buyruq bilan:
gpg --keyserver [https://keys.openpgp.org](https://keys.openpgp.org/) --send-keys 9B695056 - Biz maxfiy kalitni istalgan joyga eksport qilamiz; bizga keyinroq kerak bo'ladi:
gpg --export-secret-key 9B695056 > D:\gpg\9B695056.gpg
Github amallarini sozlash
Yakuniy bosqichga o'tamiz: Github Actions yordamida qurish va avtomatik nashr qilishni sozlash.
Github Actions - bu to'liq CI/CD siklini amalga oshirib, ish jarayonini avtomatlashtiradigan xususiyatdir. Qurilishlar, testlar va tarqatishlar turli xil hodisalar, masalan, kodni surish, relizlar yaratish yoki muammolar tufayli yuzaga kelishi mumkin. Bu xususiyat ommaviy omborlar uchun mutlaqo bepul.
Ushbu bo'limda men sizga relizni chiqarishda Sonatype omboriga kod yaratish, surish va joylashtirishni qanday sozlashni, shuningdek, sirlarni qanday sozlashni ko'rsataman.
Biz sirlarni so'raymiz
Avtomatik qurish va joylashtirish uchun bizga kalit identifikatori, kalitni yaratishda biz kiritgan parol, PGP kalitining o'zi va Sonatype login/parol kabi bir qator maxfiy qiymatlar kerak bo'ladi. Ularni ombor sozlamalarining maxsus bo'limida sozlash mumkin:

Biz quyidagi o'zgaruvchilarni o'rnatamiz:
- SONATYPE_USERNAME/SONATYPE_PASSWORD — Sonatype bilan ro'yxatdan o'tishda biz kiritgan login/parol
- SIGNING_KEYID/SIGNING_PASSWORD — PGP kalit identifikatori va parol yaratish jarayonida o'rnatiladi.
Men GPG_KEY_CONTENTS o'zgaruvchisi haqida batafsil ma'lumot bermoqchiman. Gap shundaki, nashr qilish uchun bizga shaxsiy PGP kaliti kerak. Uni yashirincha joylashtirish uchun men foydalanardim va qo'shimcha ravishda bir qator harakatlarni amalga oshirdi.
- Gpg yordamida kalitimizni shifrlaymiz:
gpg --symmetric --cipher-algo AES256 9B695056.gpg, parolni kiritish. U o'zgaruvchiga joylashtirilishi kerak: SECRET_PASSPHRASE - Qabul qilingan shifrlangan kalitni base64 yordamida matn shakliga aylantiramiz:
base64 9B695056.gpg.gpg > 9B695056.txtTarkibni o'zgaruvchiga joylashtiramiz: GPG_KEY_CONTENTS.
Kodni bosish va PR yaratishda qurilishni sozlash
Birinchidan, loyihangizning ildizida papka yaratishingiz kerak: .github/workflows.
Unda faylni belgilang, masalan, gradle-ci-build.yml quyidagi tarkib bilan:
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}}Ushbu ish jarayoni filialga bosilganda amalga oshiriladi. master, dev и testing, shuningdek, tortish so'rovlarini yaratishda.
Ishlar bo'limi ko'rsatilgan voqealar asosida bajarilishi kerak bo'lgan qadamlarni belgilaydi. Bunday holda, biz Java 8 va Gradle plaginidan foydalangan holda Ubuntu-ning so'nggi versiyasini quramiz. eskatos/gradle-command-action@v1, bu kollektorning so'nggi versiyasidan foydalanib, da ko'rsatilgan buyruqlarni bajaradi arguments. O'zgaruvchilar secrets.SONATYPE_USERNAME и secrets.SONATYPE_PASSWORD Bu biz ilgari so'ragan sirlar.
Qurilish natijalari "Amallar" yorlig'ida aks etadi:

Yangi versiya chiqqanda avtomatik joylashtirish
Autodeployment uchun biz alohida ish jarayoni faylini yaratamiz 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}}Fayl avvalgisi bilan deyarli bir xil, uni ishga tushiradigan hodisa bundan mustasno. Bu holda, bu v harfidan boshlanadigan nomli teg yaratishdir.
Joylashtirishdan oldin biz PGP kalitini sirlardan ajratib olishimiz va uni loyiha ildiziga joylashtirishimiz, shuningdek shifrini ochishimiz kerak. Keyinchalik, biz maxsus muhit o'zgaruvchisini o'rnatishimiz kerak. RELEASE_VERSION biz unga murojaat qilamiz gradle.build fayl. Bularning barchasi bo'limda amalga oshiriladi Prepare to publishBiz kalitni GPG_KEY_CONTENTS o'zgaruvchisidan olamiz, uni gpg fayliga tarjima qilamiz, so'ng shifrini hal qilamiz va faylga joylashtiramiz. secret.gpg.
Keyinchalik biz maxsus o'zgaruvchiga murojaat qilamiz GITHUB_REF, undan biz teg yaratishda ko'rsatgan versiyani olishimiz mumkin. Bu holda bu o'zgaruvchi qiymatga ega refs/tags/v0.0.2 Muayyan versiyani olish uchun biz dastlabki 11 ta belgini kesib tashlaymiz. Keyinchalik, nashr qilish uchun standart Gradle buyruqlaridan foydalanamiz: test publish
O'rnatishni tekshirish natijasida Sonatype ombori paydo bo'ladi
Chiqarish yaratilgandan so'ng, oldingi bo'limda tasvirlangan ish jarayoni boshlanishi kerak. Buning uchun reliz yarating:

bu holda teg nomi v harfi bilan boshlanishi kerak. Agar nashr etish tugmasini bosgandan so'ng ish jarayoni muvaffaqiyatli bo'lsa, biz o'tishimiz mumkin Bunga ishonch hosil qilish uchun:

Artefakt Staging omborida paydo bo'ldi. U dastlab Ochish holatida paydo bo'ladi, lekin keyin tegishli tugmani bosish orqali Yopish holatiga qo'lda o'zgartirilishi kerak. Barcha talablar tekshirilgandan so'ng, artefakt Yopish holatiga o'tkaziladi va endi o'zgartirish uchun mavjud emas. Bu shtatda MavenCentral-ga qo'shiladi. Agar hamma narsa yaxshi bo'lsa, tugmani bosishingiz mumkin. ozod qilish, va artefakt Sonatype omboriga qo'shiladi.
MavenCentral-ga artefaktni olish uchun siz uni boshida yaratgan vazifamizda so'rashingiz kerak. Buni faqat bir marta qilishingiz kerak, chunki biz buni birinchi marta shunday nashr qilamiz. Keyingi paytlarda buni qilish shart emas; hamma narsa avtomatik ravishda sinxronlanadi. Ular men uchun sinxronlashni tezda yoqdi, ammo artefakt MavenCentral-da mavjud bo'lishi uchun taxminan besh kun kerak bo'ldi.
Mana, biz o'z artefaktimizni MavenCentral-da nashr qildik.
Foydali havolalar
- O'xshash , faqat maven orqali nashr etiladi
- Staging Sonatip
- Sonatype, unda siz vazifa yaratishingiz kerak
- hammasi sozlangan ombor
Manba: www.habr.com
