Gradle un Github darbÄ«bu izmantoÅ”ana, lai publicētu Java projektu Sonatype Maven centrālajā repozitorijā

Å ajā rakstā es vēlos detalizēti aplÅ«kot Java artefakta publicÄ“Å”anas procesu no jauna, izmantojot Github Actions, Sonatype Maven centrālajā repozitorijā, izmantojot Gradle veidotāju.

Es nolēmu uzrakstÄ«t Å”o rakstu, jo trÅ«ka normālas apmācÄ«bas vienuviet. Visa informācija bija jāvāc pa gabalu no dažādiem avotiem, turklāt ne gluži svaiga. Kam tas interesē, laipni lÅ«dzam zem kaÄ·a.

Repozitorija izveide programmā Sonatype

Pirmais solis ir izveidot repozitoriju Sonatype Maven Central. Å im nolÅ«kam mēs ejam Å”eit, reÄ£istrējieties un izveidojiet jaunu uzdevumu, lÅ«dzot mums izveidot repozitoriju. Braucam savā Grupas ID projekts, Projekta URL projekta saite un SCM URL saite uz versiju kontroles sistēmu, kurā atrodas projekts. Grupas ID Å”eit ir jābÅ«t formā com.example, com.example.domain, com.example.testsupport, un tas var bÅ«t arÄ« kā saite uz jÅ«su github: github.com/jÅ«sulietotājvārds -> io.github.jÅ«su lietotājvārds. Jebkurā gadÄ«jumā jums bÅ«s jāapstiprina Ŕī domēna vai profila Ä«paÅ”umtiesÄ«bas. Ja esat norādÄ«jis github profilu, jums tiks lÅ«gts izveidot publisku repozitoriju ar vēlamo nosaukumu.

Kādu laiku pēc apstiprināŔanas tiks izveidots jÅ«su GroupId, un mēs varam pāriet uz nākamo soli, Gradle konfigurāciju.

Gradle konfigurēŔana

RakstÄ«Å”anas laikā es neatradu Gradle spraudņus, kas varētu palÄ«dzēt artefakta publicÄ“Å”anā. Tā vienÄ«gais spraudnis, ko atradu, tomēr autors atteicās to turpmāk atbalstÄ«t. Tāpēc es nolēmu visu darÄ«t pats, jo to izdarÄ«t nav pārāk grÅ«ti.

Pirmā lieta, kas jānoskaidro, ir Sonatype prasÄ«bas publicÄ“Å”anai. Tie ir Ŕādi:

  • Avota kodu un JavaDoc pieejamÄ«ba, ti. jāpiedalās -sources.jar Šø-javadoc.jar failus. Kā norādÄ«ts dokumentācijā, ja nav iespējams nodroÅ”ināt avota kodus vai dokumentāciju, varat izveidot manekenu -sources.jar vai -javadoc.jar ar vienkārÅ”u README iekÅ”pusē, lai nokārtotu testu.
  • Visiem failiem jābÅ«t parakstÄ«tiem ar GPG/PGPUn .asc katram failam ir jāiekļauj fails, kurā ir paraksts.
  • pieejamÄ«ba pom failu
  • Pareizas vērtÄ«bas groupId, artifactId Šø version. Versija var bÅ«t patvaļīga virkne, un tā nevar beigties ar -SNAPSHOT
  • NepiecieÅ”ama klātbÅ«tne name, description Šø url
  • Informācijas klātbÅ«tne par licenci, izstrādātājiem un versiju kontroles sistēmu

Å ie ir pamatnoteikumi, kas jāievēro publicējot. Pieejama pilna informācija Å”eit.

Mēs Ä«stenojam Ŕīs prasÄ«bas build.gradle failu. Vispirms pievienosim visu nepiecieÅ”amo informāciju par izstrādātājiem, licencēm, versiju kontroles sistēmu, kā arÄ« iestatÄ«sim projekta URL, nosaukumu un aprakstu. UzrakstÄ«sim vienkārÅ”u metodi Å”im nolÅ«kam:

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

Tālāk jums tas jānorāda Ä£enerētās montāžas laikā -sources.jar Šø-javadoc.jar failus. Å ai sadaļai java jums jāpievieno sekojoÅ”ais:

java {
    withJavadocJar()
    withSourcesJar()
}

Pāriesim pie pēdējās prasÄ«bas ā€” GPG/PGP paraksta iestatÄ«Å”anas. Lai to izdarÄ«tu, pievienojiet spraudni signing:

plugins {
    id 'signing'
}

Un pievienojiet sadaļu:

signing {
    sign publishing.publications
}

Visbeidzot pievienosim sadaļu 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
            }
        }
    }
}

Å eit sonatypeLietotājvārds Šø sonatypeParole mainÄ«gie, kas satur reÄ£istrācijas laikā izveidoto pieteikumvārdu un paroli sonatype.org.

Līdz ar to fināls build.gradle izskatīsies Ŕādi:

Pilns build.gradle kods

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

Es vēlos atzīmēt, ka mēs iegūstam versiju no vides mainīgā: System.getenv('RELEASE_VERSION'). Mēs to atklāsim montāžas laikā un ņemsim no taga nosaukuma.

PGP atslēgu Ä£enerÄ“Å”ana

Viena no Sonatype prasÄ«bām ir, ka visi faili ir jāparaksta ar GPG/PGP atslēgu. Å im nolÅ«kam mēs ejam Å”eit un lejupielādējiet GnuPG utilÄ«tu savai operētājsistēmai.

  • Mēs Ä£enerējam atslēgu pāri: gpg --gen-key, ievadiet lietotājvārdu, e-pastu un arÄ« iestatiet paroli.
  • Mēs uzzinām id mÅ«su atslēga ar komandu: gpg --list-secret-keys --keyid-format short. Id tiks norādÄ«ts aiz slÄ«psvÄ«tras, piemēram: rsa2048/9B695056
  • Publiskās atslēgas publicÄ“Å”ana serverÄ« https://keys.openpgp.org pēc komandas: gpg --keyserver [https://keys.openpgp.org](https://keys.openpgp.org/) --send-keys 9B695056
  • Mēs eksportējam slepeno atslēgu uz patvaļīgu vietu, mums tā bÅ«s nepiecieÅ”ama nākotnē: gpg --export-secret-key 9B695056 > D:\gpg\9B695056.gpg

Github darbību iestatīŔana

Pārejam uz pēdējo posmu, iestatÄ«sim bÅ«vniecÄ«bu un automātisku publicÄ“Å”anu, izmantojot Github Actions.
Github Actions ir lÄ«dzeklis, kas ļauj automatizēt darbplÅ«smu, ievieÅ”ot pilnu CI/CD ciklu. VeidoÅ”anu, testÄ“Å”anu un izvietoÅ”anu var izraisÄ«t dažādi notikumi: koda nosÅ«tÄ«Å”ana, laidiena izveide vai problēmas. Å Ä« funkcionalitāte publiskajām krātuvēm ir pilnÄ«gi bez maksas.

Å ajā sadaļā es jums parādÄ«Å”u, kā iestatÄ«t izveides un nosÅ«tÄ«Å”anas kodu un izvietot Sonatype repozitorijā izlaiÅ”anas laikā, kā arÄ« iestatÄ«t noslēpumus.

Mēs izvirzām noslēpumus

Automātiskai montāžai un izvietoÅ”anai mums ir nepiecieÅ”amas vairākas slepenas vērtÄ«bas, piemēram, atslēgas ID, parole, ko ievadÄ«jām, Ä£enerējot atslēgu, pati PGP atslēga un Sonatype pieteikÅ”anās/parole. Varat tos iestatÄ«t Ä«paŔā krātuves iestatÄ«jumu sadaļā:

Gradle un Github darbÄ«bu izmantoÅ”ana, lai publicētu Java projektu Sonatype Maven centrālajā repozitorijā

Mēs iestatām Ŕādus mainÄ«gos:

  • SONATYPE_USERNAME/SONATYPE_PASSWORD ā€” pieteikumvārds/parole, ko ievadÄ«jām, reÄ£istrējoties Sonatype
  • SIGNING_KEYID/SIGNING_PASSWORD ā€” Ä£enerÄ“Å”anas laikā iestatÄ«ts PGP atslēgas ID un parole.

Es vēlos sÄ«kāk pakavēties pie mainÄ«gā GPG_KEY_CONTENTS. Fakts ir tāds, ka publicÄ“Å”anai mums ir nepiecieÅ”ama privāta PGP atslēga. Lai to ievietotu noslēpumos, es izmantoju instrukcija un papildus veica vairākas darbÄ«bas.

  • Å ifrēsim mÅ«su atslēgu ar gpg: gpg --symmetric --cipher-algo AES256 9B695056.gpgievadot paroli. Tas jāievieto mainÄ«gajā: SECRET_PASSPHRASE
  • Tulkosim saņemto Å”ifrēto atslēgu teksta formā, izmantojot base64: base64 9B695056.gpg.gpg > 9B695056.txt. Saturs tiks ievietots mainÄ«gajā: GPG_KEY_CONTENTS.

Veidojiet iestatījumus, nospiežot kodu un veidojot PR

Vispirms jums ir jāizveido mape sava projekta saknē: .github/workflows.

Tajā atzÄ«mējiet failu, piemēram, gradle-ci-build.yml ar Ŕādu saturu:

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

Å Ä« darbplÅ«sma tiks izpildÄ«ta, virzot uz filiālēm master, dev Šø testing, arÄ« veidojot izvilkÅ”anas pieprasÄ«jumus.

Darbu sadaļā ir norādÄ«tas darbÄ«bas, kas jāveic norādÄ«tajos notikumos. Å ajā gadÄ«jumā mēs izmantosim jaunāko ubuntu versiju, izmantosim Java 8, kā arÄ« izmantosim Gradle spraudni. eskatos/gradle-command-action@v1kas, izmantojot jaunāko veidotāja versiju, izpildÄ«s komandas, kas norādÄ«tas arguments. MainÄ«gie lielumi secrets.SONATYPE_USERNAME Šø secrets.SONATYPE_PASSWORD Å”ie ir noslēpumi, kurus mēs jautājām iepriekÅ”.

BÅ«vÄ“Å”anas rezultāti tiks atspoguļoti cilnē DarbÄ«bas:

Gradle un Github darbÄ«bu izmantoÅ”ana, lai publicētu Java projektu Sonatype Maven centrālajā repozitorijā

Automātiska izvietoŔana, kad tiek izlaists jauns laidiens

Izveidosim atseviŔķu darbplūsmas failu automātiskai izvietoŔanai 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}}

Fails ir gandrÄ«z identisks iepriekŔējam, izņemot notikumu, kurā tas tiks aktivizēts. Å ajā gadÄ«jumā tiek izveidots tags ar nosaukumu, kas sākas ar v.

Pirms izvietoÅ”anas mums ir jāizņem PGP atslēga no noslēpumiem un jāievieto projekta saknē, kā arÄ« jāatÅ”ifrē. Tālāk mums jāiestata Ä«paÅ”s vides mainÄ«gais RELEASE_VERSION uz kuru mēs atsaucamies gradle.build failu. Tas viss tiek darÄ«ts sadaļā Prepare to publish. Mēs iegÅ«stam savu atslēgu no mainÄ«gā GPG_KEY_CONTENTS, tulkojam to gpg failā un pēc tam atÅ”ifrējam, ievietojot to failā. secret.gpg.

Tālāk mēs pievērÅ”amies Ä«paÅ”am mainÄ«gajam GITHUB_REF, no kuras mēs varam iegÅ«t versiju, kuru iestatÄ«jām, veidojot tagu. Å is mainÄ«gais ir bÅ«tisks Å”ajā gadÄ«jumā. refs/tags/v0.0.2 no kuriem mēs nogriezām pirmās 11 rakstzÄ«mes, lai iegÅ«tu konkrētu versiju. Tālāk publicÄ“Å”anai izmantojam standarta Gradle komandas: test publish

IzvietoŔanas rezultātu pārbaude Sonatype repozitorijā

Kad laidiens ir izveidots, jāsāk darbplÅ«sma, kas aprakstÄ«ta iepriekŔējā sadaļā. Lai to izdarÄ«tu, izveidojiet laidienu:

Gradle un Github darbÄ«bu izmantoÅ”ana, lai publicētu Java projektu Sonatype Maven centrālajā repozitorijā

taga nosaukumam jāsākas ar v. Ja pēc noklikŔķināŔanas uz Publicēt laidienu darbplÅ«sma ir veiksmÄ«gi pabeigta, mēs varam pāriet uz Sonatype Nexus lai pārliecinātos, ka:

Gradle un Github darbÄ«bu izmantoÅ”ana, lai publicētu Java projektu Sonatype Maven centrālajā repozitorijā

Artefakts parādÄ«jās Staging repozitorijā. Tas uzreiz parādās Open statusā, pēc tam tas manuāli jāpārnes uz statusu Close, nospiežot atbilstoÅ”o pogu. Pārbaudot, vai visas prasÄ«bas ir izpildÄ«tas, artefakts nonāk statusā Aizvērt un vairs nav pieejams modifikācijai. Å ajā formā tas nonāks MavenCentral. Ja viss ir kārtÄ«bā, varat nospiest pogu Atlaidiet, un artefakts nonāks Sonatype krātuvē.

Lai artefakts iekļūtu MavenCentral, jums tas ir jālÅ«dz uzdevumā, kuru izveidojām paŔā sākumā. Jums tas jādara tikai vienu reizi, tāpēc mēs publicējam pirmo reizi. Turpmākajos laikos tas nav nepiecieÅ”ams, viss tiks sinhronizēts automātiski. Viņi man ātri ieslēdza sinhronizāciju, taču pagāja apmēram 5 dienas, lÄ«dz artefakts kļuva pieejams MavenCentral.

Tas arÄ« viss, mēs esam publicējuÅ”i savu artefaktu MavenCentral.

Noderīgas saites

  • LÄ«dzÄ«gi raksts, publicēt tikai caur maven
  • Inscenējums krātuve Sonatips
  • JIRA Sonatype, kurā izveidot uzdevumu
  • Piemērs krātuve, kurā tas viss ir iestatÄ«ts

Avots: www.habr.com