Uzante Gradle kaj Github-Agojn por Eldoni Java-Projekton al Sonatype Maven Centra Deponejo

En ĉi tiu artikolo, mi volas detalan rigardon al la procezo de publikigado de Java-artefakto de nulo per Github-Agoj al la Sonatype Maven Centra Deponejo uzante la Gradle-konstruilon.

Mi decidis skribi ĉi tiun artikolon pro la manko de normala lernilo en unu loko. Ĉiuj informoj devis esti kolektitaj peco post peco el diversaj fontoj, cetere, ne tute freŝaj. Kiu zorgas, bonvenon sub kato.

Kreante deponejon en Sonatype

La unua paŝo estas krei deponejon en Sonatype Maven Central. Por ĉi tio ni iras tie, registriĝu kaj kreu novan taskon, petante nin krei deponejon. Ni veturas en nia GroupId projekto, Projekta URL projekto ligo kaj SCM URL ligilo al la versio-kontrolsistemo en kiu troviĝas la projekto. GroupId ĉi tie devus esti de la formo com.example, com.example.domain, com.example.testsupport, kaj ankaŭ povas esti en la formo de ligilo al via github: github.com/via salutnomo -> io.github.yourusername. Ĉiukaze, vi devos kontroli la proprieton de ĉi tiu domajno aŭ profilo. Se vi specifis github-profilon, oni petos vin krei publikan deponejon kun la dezirata nomo.

Iom da tempo post konfirmo, via GroupId estos kreita kaj ni povas pluiri al la sekva paŝo, Gradle-agordo.

Agordante Gradle

Dum la skribado, mi ne trovis Gradle-kromaĵojn, kiuj povus helpi publikigi la artefakton. ĉi la sola kromaĵo kiun mi trovis, tamen, la aŭtoro rifuzis plu subteni ĝin. Tial mi decidis fari ĉion mem, ĉar fari ĉi tion ne estas tro malfacile.

La unua afero por ekscii estas la postuloj de Sonatype por eldonado. Ili estas la jenaj:

  • Havebleco de fontkodoj kaj JavaDoc, t.e. devas ĉeesti -sources.jar и-javadoc.jar dosierojn. Kiel dirite en la dokumentado, se ne eblas provizi fontkodojn aŭ dokumentadon, vi povas fari mentilon. -sources.jar-javadoc.jar kun simpla README interne por pasigi la teston.
  • Ĉiuj dosieroj devas esti subskribitaj kun GPG/PGPkaj .asc la dosiero enhavanta la subskribon devas esti enmetita por ĉiu dosiero.
  • havebleco pom dosiero
  • Ĝustaj valoroj groupId, artifactId и version. La versio povas esti arbitra ĉeno kaj ne povas finiĝi per -SNAPSHOT
  • Ĉeesto bezonata name, description и url
  • La ĉeesto de informoj pri la permesilo, programistoj kaj versio-kontrolsistemo

Ĉi tiuj estas la bazaj reguloj, kiujn oni devas sekvi dum eldonado. Plenaj informoj haveblaj tie.

Ni efektivigas ĉi tiujn postulojn en build.gradle dosiero. Unue, ni aldonu ĉiujn necesajn informojn pri la programistoj, permesiloj, versio-kontrolsistemo, kaj ankaŭ starigu la url, nomon kaj priskribon de la projekto. Ni skribu simplan metodon por ĉi tio:

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

Poste, vi devas specifi tion dum la asembleo generita -sources.jar и-javadoc.jar dosierojn. Por ĉi tiu sekcio java vi devas aldoni la jenon:

java {
    withJavadocJar()
    withSourcesJar()
}

Ni transiru al la lasta postulo, agordi GPG/PGP subskribon. Por fari tion, konektu la kromprogramon signing:

plugins {
    id 'signing'
}

Kaj aldonu sekcion:

signing {
    sign publishing.publications
}

Fine, ni aldonu sekcion 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
            }
        }
    }
}

estas sonatype Uzantnomo и sonatypePasvorto variabloj enhavantaj la ensaluton kaj pasvorton kreitan dum registrado sur sonatype.org.

Tiel la finalo build.gradle aspektos tiel:

Plena build.gradle-kodo

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

Mi volas noti, ke ni ricevas la version de la mediovariablo: System.getenv('RELEASE_VERSION'). Ni elmontros ĝin dum kunigo kaj prenos ĝin de la etikedo nomo.

PGP-ŝlosila generacio

Unu el la postuloj de Sonatype estas, ke ĉiuj dosieroj estu subskribitaj per GPG/PGP-ŝlosilo. Por ĉi tio ni iras tie kaj elŝutu la ilon GnuPG por via operaciumo.

  • Ni generas ŝlosilan paron: gpg --gen-key, enigu uzantnomon, retpoŝton, kaj ankaŭ agordu pasvorton.
  • Ni ekscias id nia ŝlosilo kun la komando: gpg --list-secret-keys --keyid-format short. Id estos specifita post la oblikvo, ekzemple: rsa2048/9B695056
  • Publikigante la publikan ŝlosilon al la servilo https://keys.openpgp.org kun la komando: gpg --keyserver [https://keys.openpgp.org](https://keys.openpgp.org/) --send-keys 9B695056
  • Ni eksportas la sekretan ŝlosilon al arbitra loko, ni bezonos ĝin estonte: gpg --export-secret-key 9B695056 > D:\gpg\9B695056.gpg

Agordi Github-Agojn

Ni transiru al la fina etapo, agordu la konstruon kaj aŭtomate-publikigon per Github-Agoj.
Github Actions estas trajto, kiu permesas vin aŭtomatigi la laborfluon efektivigante plenan CI / KD-ciklon. Konstruo, testi kaj deploji povas esti ekigitaj de diversaj eventoj: kodo-puŝo, liberigo-kreado aŭ problemoj. Ĉi tiu funkcio estas absolute senpaga por publikaj deponejoj.

En ĉi tiu sekcio, mi montros al vi kiel agordi konstrui kaj puŝi kodon kaj deploji al la deponejo de Sonatype post liberigo, kaj ankaŭ agordi sekretojn.

Ni starigas sekretojn

Por aŭtomata muntado kaj deplojo, ni bezonas kelkajn sekretajn valorojn, kiel ekzemple la ŝlosila id, la pasvorto, kiun ni enigis dum generado de la ŝlosilo, la PGP-ŝlosilo mem, kaj la Sonatype-ensaluto/pasvorto. Vi povas agordi ilin en speciala sekcio en la deponejaj agordoj:

Uzante Gradle kaj Github-Agojn por Eldoni Java-Projekton al Sonatype Maven Centra Deponejo

Ni starigas la sekvajn variablojn:

  • SONATYPE_USERNAME / SONATYPE_PASSWORD - ensaluto / pasvorto, kiun ni enigis dum registriĝo kun Sonatype
  • SIGNING_KEYID/SIGNING_PASSWORD — PGP-ŝlosila identigilo kaj pasvorto agordita dum generacio.

Mi volas pli detale pritrakti la variablon GPG_KEY_CONTENTS. La fakto estas, ke por publikigo ni bezonas privatan PGP-ŝlosilon. Por afiŝi ĝin en la sekretojn, mi uzis instrukcio kaj aldone faris kelkajn agojn.

  • Ni ĉifri nian ŝlosilon per gpg: gpg --symmetric --cipher-algo AES256 9B695056.gpgper enigo de pasvorto. Ĝi estu metita en variablon: SECRET_PASSPHRASE
  • Ni traduku la ricevitan ĉifritan ŝlosilon en tekstan formon uzante base64: base64 9B695056.gpg.gpg > 9B695056.txt. La enhavo estos metita en la variablon: GPG_KEY_CONTENTS.

Konstruu aranĝon dum puŝado de kodo kaj kreado de PR

Unue vi devas krei dosierujon en la radiko de via projekto: .github/workflows.

En ĝi, marku la dosieron, ekzemple, gradle-ci-build.yml kun la jena enhavo:

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 tiu laborfluo estos efektivigita kiam oni premas al branĉoj master, dev и testing, ankaŭ dum kreado de tirpetoj.

La sekcio de laborpostenoj specifas la paŝojn por esti efektivigitaj en la specifitaj eventoj. En ĉi tiu kazo, ni konstruos la plej novan version de ubuntu, uzos Java 8, kaj ankaŭ uzos la kromprogramon por Gradle. eskatos/gradle-command-action@v1kiu, uzante la plej novan version de la konstruanto, ruligos la komandojn specifitajn en arguments. Variabloj secrets.SONATYPE_USERNAME и secrets.SONATYPE_PASSWORD jen la sekretoj, kiujn ni pli frue demandis.

La konstrurezultoj estos reflektitaj en la langeto Agoj:

Uzante Gradle kaj Github-Agojn por Eldoni Java-Projekton al Sonatype Maven Centra Deponejo

Aŭtomate disfaldi kiam nova eldono estas publikigita

Ni kreu apartan laborfludosieron por aŭtodeplojado 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}}

La dosiero estas preskaŭ identa al la antaŭa, krom la evento en kiu ĝi estos ekigita. En ĉi tiu kazo, ĉi tio estas la okazaĵo de kreado de etikedo kun nomo komencanta per v.

Antaŭ deplojo, ni devas ĉerpi la PGP-ŝlosilon el la sekretoj kaj meti ĝin en la radikon de la projekto, kaj ankaŭ malĉifri ĝin. Poste, ni devas agordi specialan mediovariablon RELEASE_VERSION kiun ni referencas gradle.build dosiero. Ĉio ĉi estas farita en la sekcio Prepare to publish. Ni ricevas nian ŝlosilon de la variablo GPG_KEY_CONTENTS, tradukas ĝin en gpg-dosieron, poste deĉifri ĝin metante ĝin en la dosieron. secret.gpg.

Poste, ni turnas nin al speciala variablo GITHUB_REF, de kiu ni povas akiri la version, kiun ni agordis dum kreado de la etikedo. Ĉi tiu variablo estas grava en ĉi tiu kazo. refs/tags/v0.0.2 el kiu ni fortranĉis la unuajn 11 signojn por ricevi specifan version. Poste, ni uzas la normajn Gradle-komandojn por eldonado: test publish

Kontrolante deplojajn rezultojn en Sonatype-deponejo

Post kiam la eldono estas kreita, la laborfluo priskribita en la antaŭa sekcio devus komenciĝi. Por fari tion, kreu eldonon:

Uzante Gradle kaj Github-Agojn por Eldoni Java-Projekton al Sonatype Maven Centra Deponejo

la etikedo nomo devas komenci per v. Se, post klakado de Publiki eldono, la laborfluo sukcese finiĝas, ni povas iri al Sonatype Nexus certigi:

Uzante Gradle kaj Github-Agojn por Eldoni Java-Projekton al Sonatype Maven Centra Deponejo

La artefakto aperis en la Staging-deponejo. Ĝi tuj aperas en la Malferma stato, tiam ĝi devas esti permane transdonita al la Ferma statuso premante la taŭgan butonon. Post kontrolo, ke ĉiuj postuloj estas plenumitaj, la artefakto iras en la Fermi-statuson kaj ne plu disponeblas por modifo. En ĉi tiu formo, ĝi finiĝos en MavenCentral. Se ĉio estas en ordo, vi povas premi la butonon ĵeto, kaj la artefakto finiĝos en la Sonatype-deponejo.

Por ke la artefakto eniru en MavenCentral, vi devas peti ĝin en la tasko, kiun ni kreis komence. Vi devas fari ĉi tion nur unufoje, do ni publikigas la unuan fojon. En postaj tempoj, ĉi tio ne estas postulata, ĉio estos aŭtomate sinkronigita. Ili ŝaltis sinkronigon por mi rapide, sed daŭris ĉirkaŭ 5 tagojn por ke la artefakto fariĝis havebla en MavenCentral.

Jen ĉio, ni publikigis nian artefakton en MavenCentral.

utilaj ligoj

  • Simile artikolo, nur eldonas per maven
  • Surscenigo deponejo Sonatipo
  • Jira Sonatipo en kiu krei la taskon
  • Ekzemplo: deponejo kie ĉio estas agordita

fonto: www.habr.com