Uporabljamo Gradle in Github Actions za objavo Java projekta v Sonatype Maven Central Repository

V tem članku želim podrobno obravnavati postopek objave Java artefakta od začetka do konca prek Github Actions v Sonatype Maven Central Repository s pomočjo Gradle.

Ta članek sem se odločil napisati zaradi pomanjkanja normalnega priročnika na enem mestu. Vse informacije sem moral zbirati po delčkih iz različnih virov, ki niso bile povsem aktualne. Kdor je radoveden, je dobrodošel pod kat.

Ustvarjanje repozitorija v Sonatype

Prvi korak je ustvariti repozitorij v Sonatype Maven Central. Za to gremo na tukaj, se prijavimo in ustvarimo novo nalogo s prošnjo za ustvaritev repozitorija. Vnesite svoj GroupId projekta, Project URL povezavo na projekt in SCM url povezavo na sistem za nadzor različic, v katerem se projekt nahaja. GroupId tu mora biti v obliki com.example, com.example.domain, com.example.testsupport, lahko pa tudi v obliki povezave do vašega githuba: github.com/yourusername -> io.github.yourusername. V vsakem primeru boste morali potrditi lastništvo tega domene ali profila. Če ste navedli profil na githubu, vas bodo prosili, da ustvarite javni repozitorij z ustreznim imenom.

Čez nekaj časa po potrditvi bo vaš GroupId ustvarjen in lahko preidemo na naslednji korak, konfiguracijo Gradle.

Konfiguriramo Gradle

Ob trenutnem pisanju članka nisem našel vtičnikov za Gradle, ki bi lahko pomagali pri objavi artefakta. To Eden sam vtičnik, ki sem ga našel, pa je avtor opustil nadaljnjo podporo. Zato sem se odločil, da vse naredim sam, saj to ni prevelik izziv.

Prvo, kar je treba ugotoviti, so zahteve Sonatype za objavo. Te so naslednje:

  • Zadostovati morajo izvorne kode in JavaDoc, torej morajo biti prisotni -sources.jar in-javadoc.jar datoteke. Kot je zapisano v dokumentaciji, če ne morete predložiti izvornih kod ali dokumentacije, lahko naredite prazno datoteko -sources.jar ili -javadoc.jar z enostavnim README notranjosti, da preidete preverjanje.
  • Vse datoteke morajo biti podpisane s pomočjo GPG/PGP, i .asc datoteka, ki vsebuje podpis, mora biti vključena za vsako datoteko.
  • Postojanje pom datoteke
  • Pravilne vrednosti groupId, artifactId in version. Različica je lahko poljubna niza in se ne sme končati -SNAPSHOT
  • Zahtevana je prisotnost name, opis in url
  • Prisutnost informacij o licenci, razvijalcih in sistemu za nadzor različic

To so osnovna pravila, ki jih je treba upoštevati pri objavi. Celotne informacije so na voljo ovde.

Uresničimo te zahteve v build.gradle в файле. Для начала добавим всю необходимую информацию о разработчиках, лицензии, системе контроля версий, а также зададим URL, имя и описание проекта. Для этого напишем простой метод:

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

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

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

            description 'Некоторое описание артефакта'
            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 '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'
                }
            }
        }
    }
}

Далее нужно указать, чтобы при сборке сгенерировались -sources.jar in-javadoc.jar файлы. Для этого в секцию java нужно добавить следующее:

java {
    withJavadocJar()
    withSourcesJar()
}

Перейдем к последнему требованию, настройке GPG/PGP подписи. Для этого подключим плагин signing:

plugins {
    id 'signing'
}

И добавим секцию:

signing {
    sign publishing.publications
}

Наконец, добавим секцию 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
            }
        }
    }
}

Tukaj sonatypeUsername in sonatypePassword переменные, содержащие логин и пароль, созданные при регистрации на sonatype.org.

Таким образом, финальный build.gradle будет выглядеть следующим образом:

Полный код 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 'Artifact 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.sl'
                }
            }
        }
    }
}

Želim napomenuti da verziju dobijamo iz promenljive okruženja: System.getenv('RELEASE_VERSION'). Postavićemo je prilikom gradnje i uzeti iz imena taga.

Generisanje PGP ključa

Jedan od zahteva Sonatype-a je potpisivanje svih fajlova putem GPG/PGP ključa. U tu svrhu tukaj preuzmite GnuPG alat za svoj operativni sistem.

  • Generišemo par ključeva: gpg --gen-key, unesite korisničko ime, e-mail, kao i postavite lozinku.
  • Otkrivamo id naš ključ komandom: gpg --list-secret-keys --keyid-format short. Id će biti naveden posle kose crte, na primer: rsa2048/9B695056
  • Objavljujemo javni ključ na server https://keys.openpgp.org komandom: gpg --keyserver [https://keys.openpgp.org](https://keys.openpgp.org/) --send-keys 9B695056
  • Eksportujemo tajni ključ na bilo koju lokaciju, biće nam potreban kasnije: gpg --export-secret-key 9B695056 > D:\gpg\9B695056.gpg

Podešavamo Github Actions

Prelazimo na završnu fazu, podešavamo gradnju i auto publikaciju koristeći Github Actions.
Github Actions – funkcionalnost, ki omogoča avtomatizacijo delovnega toka z izvajanjem celotnega cikla CI/CD. Gradnja, testiranje in uvajanje se lahko sprožijo z različnimi dogodki: push kode, ustvarjanje izdaj ali težav. Ta funkcionalnost je popolnoma brezplačna za javne repozitorije.

V tem razdelku bom pokazal, kako nastaviti gradnjo, push kode in uvajanje v Sonatype repozitorij ob izdaji, pa tudi nastavitev skrivnosti.

Nastavitev skrivnosti

Za samodejno gradnjo in uvajanje bomo potrebovali vrsto tajnih vrednosti, kot so id ključa, geslo, ki smo ga vnesli pri generiranju ključa, sam PGP ključ in prijava/geslo za Sonatype. Te lahko nastavite v posebnem razdelku v nastavitvah repozitorija:

Uporabljamo Gradle in Github Actions za objavo Java projekta v Sonatype Maven Central Repository

Nastavimo naslednje spremenljivke:

  • SONATYPE_USERNAME/SONATYPE_PASSWORD — prijava/geslo, ki smo ga vnesli pri registraciji v Sonatype
  • SIGNING_KEYID/SIGNING_PASSWORD — id PGP ključa in geslo, ki je bilo nastavljeno pri generiranju.

Na spremenljivki GPG_KEY_CONTENTS se bom nekoliko podrobneje ustavil. Dejstvo je, da za objavo potrebujemo tajni PGP ključ. Da bi ga vnesel v skrivnosti, sem uporabil navodili in izvedel vrsto dodatnih dejanj.

  • Šifrirajmo naš ključ s pomočjo gpg: gpg --symmetric --cipher-algo AES256 9B695056.gpg, vnesite geslo. To geslo je treba postaviti v spremenljivko: SECRET_PASSPHRASE
  • Pretvorimo pridobljen šifriran ključ v besedilno obliko s pomočjo base64: base64 9B695056.gpg.gpg > 9B695056.txt. Vsebino postavimo v spremenljivko: GPG_KEY_CONTENTS.

Nastavite gradnjo pri push kode in ustvarjanju PR

Najprej morate ustvariti mapo v korenu vašega projekta: .github/workflows.

V njej postavite datoteko, na primer, gradle-ci-build.yml s sledečo vsebino:

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

Ta delovni proces se bo izvedel pri pushu v veje master, dev in testing, prav tako pri ustvarjanju pull requestov.

V razdelku jobs so navedeni koraki, ki jih je treba izvesti ob navedenih dogodkih. V tem primeru bomo gradili na zadnji različici ubuntu, uporabili Java 8 in tako tudi uporabljali vtičnik za Gradle eskatos/gradle-command-action@v1, ki bo z uporabo najnovejše različice graditelja zagnal ukaze, navedene v argumenti. Spremenljivke secrets.SONATYPE_USERNAME in secrets.SONATYPE_PASSWORD to so skrivnosti, ki smo jih prej navedli.

Rezultati gradnje bodo prikazani na zavihku Dejavnosti:

Uporabljamo Gradle in Github Actions za objavo Java projekta v Sonatype Maven Central Repository

Samodejno nameščanje ob izdaji nove različice

Za samodejno nameščanje bomo ustvarili ločeno datoteko delovnega procesa gradle-ci-publish.yml:

name: publish

on:
  push:
    tags:
      - 'v*'

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - name: Nastavi JDK 8
        uses: actions/setup-java@v1
        with:
          java-version: 8

      - name: Pripravi za objavo
        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: Objavi z 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}}

Datoteka je praktično enaka prejšnji, razen dogodka, pri katerem bo sprožena. V tem primeru je to dogodek za ustvarjanje oznake z imenom, ki se začne na v.

Pred nameščanjem moramo pridobiti PGP ključ iz skrivnosti in ga postaviti v koren projekta, kot tudi dešifrirati. Nato moramo nastaviti posebno okoljsko spremenljivko RELEASE_VERSION na katero se sklicujemo v gradle.build datoteki. Vse to je narejeno v razdelku Pripravi za objavo. Naš ključ dobimo iz spremenljivke GPG_KEY_CONTENTS, ga preoblikujemo v gpg datoteko, nato ga dešifriramo in shranimo v datoteko secret.gpg.

Nato se sklicujemo na posebno spremenljivko GITHUB_REF, iz katere lahko pridobimo različico, ki smo jo navedli ob ustvarjanju oznake. Ta spremenljivka ima v tem primeru vrednost refs/tags/v0.0.2 , od katere odtrgamo prvih 11 znakov, da pridobimo specifično različico. Nato standardno uporabimo ukaze Gradle za objavo: test publish

Preverjanje rezultatov namestitve v Sonatype repozitorij

Po ustvarjanju različice se mora zagnati delovni proces, opisan v prejšnjem razdelku. Za to ustvarimo različico:

Uporabljamo Gradle in Github Actions za objavo Java projekta v Sonatype Maven Central Repository

pri čemer se mora ime oznake začeti z v. Če po kliku na Objavi različico delovni proces uspešno izvede, lahko vstopimo v Sonatype Nexus da se prepričamo o tem:

Uporabljamo Gradle in Github Actions za objavo Java projekta v Sonatype Maven Central Repository

Artefakt se je pojavil v Staging repozitoriju. Takoj se prikaže v statusu Open, nato ga je treba ročno prevesti v status Close, tako da pritisnete ustrezno tipko. Po preverjanju izpolnjevanja vseh zahtevkov, artefakt preide v status Close in ni več mogoče spremeniti. V takšni obliki bo prišel v MavenCentral. Če je vse v redu, lahko pritisnete gumb Release, pri čemer artefakt pride v repozitorij Sonatype.

Da artefakt pride v MavenCentral, je treba o tem zaprositi v nalogi, ki smo jo ustvarili na začetku. To je treba storiti samo enkrat, saj objavljamo prvič. V naslednjih primerih tega ne bo treba, vse se bo samodejno sinhroniziralo. Hitro so mi omogočili sinhronizacijo, toda da je artefakt postal dostopen v MavenCentral, je minilo približno 5 dni.

S tem končujemo, objavili smo naš artefakt v MavenCentral.

Koristne poveznice

  • Podoben članek, samo objava prek maven
  • Staging repozitorij Sonatype
  • Jira Sonatype, v katerem je potrebno ustvariti nalogo
  • Primer repozitorija, kjer je vse to nastavljeno

Izvor: habr.com

Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki 🔥 Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki | ProHoster