A Gradle és a Github Actions használatával Java projektet publikálunk a Sonatype Maven Central Repository-ban.

Ebben a cikkben részletesen szeretném bemutatni a Java artefaktum nulláról történő közzétételének folyamatát Github Actions segítségével a Sonatype Maven Central Repository-ba, Gradle használatával.

Ezt a cikket azért írtam, mert hiányzott egy megfelelő útmutató egy helyen. Az összes információt különböző forrásokból kellett összegyűjtenem, ráadásul nem éppen frissek voltak. Aki érdeklődik, az szívesen látott a továbbiakban.

A repozitórium létrehozása a Sonatype-ban

Első lépésként létre kell hoznunk egy repozitóriumot a Sonatype Maven Central-ban. Ehhez lépjünk ide, regisztráljunk és hozzunk létre egy új feladatot, kérve, hogy hozzanak létre egy repozitóriumot számunkra. Írjuk be a GroupId projektet, A projekt URL a projekt linkje és SCM url a verziókezelő rendszer linkje, amelyben a projekt található. GroupId ennek a formátumú kell lennie: com.example, com.example.domain, com.example.testsupport, és lehet a Github profilod linkje is: github.com/yourusername -> io.github.yourusername. Minden esetben meg kell erősítened a domained vagy profilod tulajdonjogát. Ha a Github profilt adtad meg, kérni fognak, hogy hozz létre egy nyilvános repozitóriumot a szükséges névvel.

Néhány idő elteltével a tulajdonjog megerősítése után a GroupId-d meg fog jelenni, és áttérhetünk a következő lépésre, a Gradle konfigurálására.

Gradle konfigurálása

A cikk írásának időpontjában nem találtam olyan Gradle bővítményeket, amelyek segíthetnének az artefaktum közzétételében. Ez Az egyetlen bővítmény, amelyet találtam, azonban az írója lemondott a további támogatásáról. Így úgy döntöttem, hogy mindent magam csinálok, lévén, hogy ez nem túl bonyolult.

Az első dolog, amit meg kell tisztázni, az a Sonatype követelményei a közzétételhez. Az alábbiak:

  • Forráskód és JavaDoc megléte, azaz a következő fájloknak kell jelen lenniük: -sources.jar és-javadoc.jar fájlok. Ahogyan a dokumentációban olvasható, ha nincs lehetőség forráskódok vagy dokumentáció rendelkezésre bocsátására, lehet készíteni egy üres fájlt -sources.jar vagy -javadoc.jar egy egyszerű README fájlral benne, hogy átmenjünk az ellenőrzésen.
  • Minden fájl aláírásra kerül az GPG/PGP, és a .asc fájlnak, amely az aláírást tartalmazza, minden egyes fájlhoz be kell tartoznia.
  • A pom fájlt
  • Helyes értékek groupId, artifactId és version. A verzió lehet tetszőleges karakterlánc és nem végződhet -SNAPSHOT
  • Az engedély, a fejlesztők és a verziókezelő rendszer információinak megjelenése szükséges. name, leírás és url
  • Ezek a fő szabályok, amelyeket be kell tartani a közzététel során. A teljes információ elérhető

Ezeket a követelményeket valósítjuk meg a itt.

build.gradle build.gradle fájl. Kezdjük azzal, hogy hozzáadjuk a szükséges információkat a fejlesztőkről, a licencről, a verziókezelő rendszerről, valamint megadjuk az URL-t, a nevet és a projekt leírását. Ehhez írjunk egy egyszerű metódust:

def customizePom(pom) {
    pom.withXml {
        def root = asNode()

        root.dependencies.removeAll { dep ->
            dep.scope == "test"
        }

        root.children().last() + {
            resolveStrategy = DELEGATE_FIRST

            description 'A műtárgy néhány leírása'
            name 'Műtárgy neve'
            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.hu'
                }
            }
        }
    }
}

Ezután meg kell adnunk, hogy a build során generálódjanak -sources.jar és-javadoc.jar fájlok. Ehhez a szekcióba java kell a következőket hozzáadni:

java {
    withJavadocJar()
    withSourcesJar()
}

Térjünk át az utolsó követelményre, a GPG/PGP aláírás beállítására. Ehhez csatlakoztassuk a bővítményt signing:

plugins {
    id 'signing'
}

És adjuk hozzá a szekciót:

signing {
    sign publishing.publications
}

Végül adjuk hozzá a szekciót 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
            }
        }
    }
}

Itt sonatypeUsername és sonatypePassword változók, amelyek a regisztráció során létrehozott bejelentkezési adatokat és jelszót tartalmazzák sonatype.org.

Így a végső build.gradle a következőképpen fog kinézni:

A build.gradle teljes kódja

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'
                }
            }
        }
    }
}

Szeretném megjegyezni, hogy a verziót környezeti változóból kapjuk: System.getenv('RELEASE_VERSION'). Ezt a build során állítjuk be, és a címkenevéből vesszük.

PGP kulcs generálása

A Sonatype egyik követelménye, hogy minden fájl aláírásra kerüljön GPG/PGP kulccsal. Ehhez lépjünk ide és töltsük le a GnuPG eszközt a saját operációs rendszerünkhöz.

  • Generáljuk a kulcspárt: gpg --gen-key, adjuk meg a felhasználónevünket, e-mail címünket, valamint egy jelszót is.
  • Megállapítjuk id a kulcsunkat a következő parancs segítségével: gpg --list-secret-keys --keyid-format short. Az ID a perjel után lesz feltüntetve, például: rsa2048/9B695056
  • A nyilvános kulcsot közzé tesszük a szerveren https://keys.openpgp.org a következő parancs segítségével: gpg --keyserver [https://keys.openpgp.org](https://keys.openpgp.org/) --send-keys 9B695056
  • Exportáljuk a titkos kulcsot egy tetszőleges helyre, mert a továbbiakban szükségünk lesz rá: gpg --export-secret-key 9B695056 > D:\gpg\9B695056.gpg

Beállítjuk a Github Actions-t

Térjünk át a végső szakaszra, állítsuk be a buildet és az automatikus kiadást a Github Actions segítségével.
A Github Actions egy funkcionalitás, amely lehetővé teszi a munkafolyamat automatizálását, megvalósítva a teljes CI/CD ciklust. A build, tesztelés és telepítés különféle események által kiváltható: kód push, kiadás létrehozása vagy issue. Ez a funkcionalitás teljesen ingyenes a nyilvános repozitóriumok számára.

Ebben a szakaszban megmutatom, hogyan állíthatjuk be a buildet és a kód push-ot, valamint a kiadás során történő telepítést a Sonatype repozitóriumba, és a titkok beállítását is.

Titkok megadása

Az automatikus build és telepítés érdekében szükség lesz egy sor titkos értékre, például a kulcs azonosítójára, a jelszóra, amelyet a kulcs generálásakor adtunk meg, magára a PGP kulcsra, és a Sonatype-hoz szükséges bejelentkezési adatokra. Ezeket egy külön szakaszban lehet megadni a repozitórium beállításaiban:

A Gradle és a Github Actions használatával Java projektet publikálunk a Sonatype Maven Central Repository-ban.

A következő változókat állítjuk be:

  • SONATYPE_USERNAME/SONATYPE_PASSWORD — a Sonatype-ra való regisztrációkor megadott bejelentkezési adatok
  • SIGNING_KEYID/SIGNING_PASSWORD — a PGP kulcs azonosítója és a generáláskor beállított jelszó.

A GPG_KEY_CONTENTS változóra szeretnék kicsit részletesebben kitérni. Az a helyzet, hogy a közzétételhez szükségünk van a titkos PGP kulcsra. A kulcsot a titkok között történő elhelyezéshez utasítás használhattam, és további lépéseket tettem.

  • Titkosítjuk a kulcsunkat gpg segítségével: gpg --symmetric --cipher-algo AES256 9B695056.gpg, beírva a jelszót. Ezt a változóba kell tenni: SECRET_PASSPHRASE
  • A kapott titkosított kulcsot átkonvertáljuk szöveges formába base64 segítségével: base64 9B695056.gpg.gpg > 9B695056.txt. A tartalmát a változóban helyezzük el: GPG_KEY_CONTENTS.

A build beállítása kód push és PR létrehozásakor

Először létre kell hozni egy mappát a projekt gyökerében: .github/workflows.

Ebben elhelyezünk egy fájlt, például gradle-ci-build.yml a következő tartalommal:

name: build

on:
  push:
    branches:
      - master
      - dev
      - testing
  pull_request:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - name: JDK 8 beállítása
        uses: actions/setup-java@v1
        with:
          java-version: 8

      - name: Build Gradle-lel
        uses: eskatos/gradle-command-action@v1
        with:
          gradle-version: current
          arguments: build -PsonatypeUsername=${{secrets.SONATYPE_USERNAME}} -PsonatypePassword=${{secrets.SONATYPE_PASSWORD}}

Ez a munkafolyamat a branch-ekbe való pushkor fog végrehajtódni master, dev és tesztelés, valamint pull requestek létrehozásakor.

A jobs szakaszban találhatóak azok a lépések, amelyeket a megadott eseményekre kell végrehajtani. Ebben az esetben a legújabb ubuntu verzión fogunk buildelni, Java 8-at használni, valamint a Gradle plugin-t is eskatos/gradle-command-action@v1, amely a legújabb verziójú build eszközt használva futtatja a megadott parancsokat, — választható argumentumok. Részletesebben lásd alább.. Változók secrets.SONATYPE_USERNAME és secrets.SONATYPE_PASSWORD ezek azok a titkok, amelyeket korábban beállítottunk.

A build eredményei az Actions fülön jelennek meg:

A Gradle és a Github Actions használatával Java projektet publikálunk a Sonatype Maven Central Repository-ban.

Automatikus telepítés új kiadás esetén

Az automatikus telepítéshez külön munkafolyamat fájlt hozunk létre gradle-ci-publish.yml:

name: publish

on:
  push:
    tags:
      - 'v*'

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - name: JDK 8 telepítése
        uses: actions/setup-java@v1
        with:
          java-version: 8

      - name: Felkészülés a publikálásra
        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álás Gradle-lal
        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}}

A fájl gyakorlatilag az előzőhöz hasonló, a kiváltó esemény kivételével. Ebben az esetben a kiváltó esemény egy 'v'-re kezdődő címkének a létrehozása.

A telepítés előtt ki kell nyernünk a PGP kulcsot a titkok közül, el kell helyeznünk a projekt gyökérmappájában, és meg kell fejtenünk. Ezt követően be kell állítanunk egy speciális környezeti változót RELEASE_VERSION amelyre a gradle.build fájlban hivatkozunk. Mindez a Felkészülés a publikálásrarészben történik. A kulcsot a GPG_KEY_CONTENTS változóból nyerjük, átalakítjuk gpg fájllá, majd dekódoljuk, helyezve a fájlba secret.gpg.

Ezután egy különleges változónkhoz fordulunk, GITHUB_REF, amelyből kinyerhetjük a verziót, amit a címke létrehozásakor adtunk meg. Ez a változó ebben az esetben úgy néz ki, mint refs/tags/v0.0.2 , amiből levágjuk az első 11 karaktert, hogy pontosan a verziót kapjuk. Ezután a Gradle parancsokat a publikálásra használjuk: test publish

A telepítés eredményeinek ellenőrzése a Sonatype tárolóban

A kiadás létrehozása után el kell indulnia a korábban leírt munkafolyamatnak. Ehhez kiadást hozzunk létre:

A Gradle és a Github Actions használatával Java projektet publikálunk a Sonatype Maven Central Repository-ban.

a címkének 'v'-vel kell kezdődnie. Ha a Publikálás gombra kattintva a munkafolyamat sikeresen befejeződik, beléphetünk a Sonatype Nexus felületen, hogy ezt ellenőrizzük:

A Gradle és a Github Actions használatával Java projektet publikálunk a Sonatype Maven Central Repository-ban.

Az artefaktus megjelent a Staging tárolóban. Azonnal Open státuszba kerül, ezután kézzel kell Closed státuszba állítani, a megfelelő gombra kattintva. Minden követelmény ellenőrzése után az artefaktus Closed státuszba kerül, és többé nem módosítható. Ilyen formában fog megjelenni a MavenCentralban. Ha minden rendben van, kattintson a gombra Kiadás, ezáltal az artefaktus bekerül a Sonatype tárolóba.

Ahhoz, hogy az artefaktus a MavenCentralba kerüljön, kérni kell ezt a feladatban, amelyet az elején létrehoztunk. Ezt csak egyszer szükséges megtenni, mivel először publikálunk. A későbbi alkalmak során erre már nincs szükség, minden automatikusan szinkronizálva lesz. Az én szinkronizálásomat gyorsan aktiválták, de ahhoz, hogy az artefaktus elérhető legyen a MavenCentralban, körülbelül 5 nap telt el.

Ezzel véget ért, publikáltuk az artefaktusunkat a MavenCentralban.

Hasznos linkek

  • Hasonló cikk, csak publikálás mavenen keresztül
  • Staging tárhely Sonatype
  • Jira Sonatype, ahol feladatot kell létrehozni
  • támadásra tároló, ahol mindez be van állítva

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster