Sonatype Maven Central Repository рдореЗрдВ рдЬрд╛рд╡рд╛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЛ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЧреНрд░реИрдбрд▓ рдФрд░ рдЧрд┐рддреБрдм рдХреНрд░рд┐рдпрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛

рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВ рдЧреНрд░реИрдб рдХрд▓реЗрдХреНрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реЛрдирд╛рдЯрд╛рдЗрдк рдорд╛рд╡реЗрди рд╕реЗрдВрдЯреНрд░рд▓ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдЬреАрдердм рдПрдХреНрдЯреЗрд╢рди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕реНрдХреНрд░реИрдЪ рд╕реЗ рдЬрд╛рд╡рд╛ рдЖрд░реНрдЯрд╡рд░реНрдХ рдХреЛ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд░рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдкрд░ рдПрдХ рд╡рд┐рд╕реНрддреГрдд рдирдЬрд╝рд░ рдбрд╛рд▓рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред


рдореИрдВрдиреЗ рдПрдХ рдЬрдЧрд╣ рд╕рд╛рдорд╛рдиреНрдп рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдХреА рдХрдореА рдХреЗ рдХрд╛рд░рдг рдЗрд╕ рд▓реЗрдЦ рдХреЛ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред рд╕рднреА рдЬрд╛рдирдХрд╛рд░реА рд╡рд┐рднрд┐рдиреНрди рд╕реНрд░реЛрддреЛрдВ рд╕реЗ рдЯреБрдХрдбрд╝реЛрдВ рдореЗрдВ рдПрдХрддреНрд░ рдХреА рдЬрд╛рдиреА рдереА, рдЬрдмрдХрд┐ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рддрд╛рдЬрд╛ рдирд╣реАрдВ рдереАред рдХреМрди рдкрд░рд╡рд╛рд╣ рдХрд░рддрд╛ рд╣реИ, рдмрд┐рд▓реНрд▓реА рдореЗрдВ рдЖрдкрдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИред


рд╕реЛрдирд╛рдЯрд╛рдЗрдк рдореЗрдВ рдПрдХ рднрдВрдбрд╛рд░ рдХрд╛ рдирд┐рд░реНрдорд╛рдг


рдкрд╣рд▓рд╛ рдХрджрдо рд╕реЛрдирд╛рдЯрд╛рдЗрдк рдорд╛рд╡реЗрди рд╕реЗрдВрдЯреНрд░рд▓ рдореЗрдВ рдПрдХ рднрдВрдбрд╛рд░ рдмрдирд╛рдирд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдпрд╣рд╛рдВ рдЬрд╛рдПрдВ , рдкрдВрдЬреАрдХрд░рдг рдХрд░реЗрдВ рдФрд░ рдПрдХ рдирдпрд╛ рдХрд╛рд░реНрдп рдмрдирд╛рдПрдВ, рдЬрд┐рд╕рд╕реЗ рд╣рдореЗрдВ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдПрдХ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рд╛ рдЬрд╛ рд╕рдХреЗред рд╣рдо рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЗ рд╣рдорд╛рд░реЗ GroupId , Project URL рдХреЛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдФрд░ SCM url рд▓рд┐рдВрдХ рдХреЛ рдЙрд╕ рд╕рдВрд╕реНрдХрд░рдг рдирд┐рдпрдВрддреНрд░рдг рдкреНрд░рдгрд╛рд▓реА рдореЗрдВ рдЪрд▓рд╛рддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдирд┐рд╣рд┐рдд рд╣реИред рдпрд╣рд╛рдВ GroupId рдХреЙрдо рдХрд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред com.example, com.example.domain, com.example.testsupport, рдФрд░ рдпрд╣ рдЖрдкрдХреЗ github: github.com/yourusername -> jio.github.yourusername рдХрд╛ рд▓рд┐рдВрдХ рднреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ ред рдХрд┐рд╕реА рднреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдЖрдкрдХреЛ рдЗрд╕ рдбреЛрдореЗрди рдпрд╛ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдХреЗ рд╕реНрд╡рд╛рдорд┐рддреНрд╡ рдХреА рдкреБрд╖реНрдЯрд┐ рдХрд░рдиреА рд╣реЛрдЧреАред рдпрджрд┐ рдЖрдкрдиреЗ рдПрдХ рдЬреАрдереВрдм рдкреНрд░реЛрдлрд╛рдЗрд▓ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдпрд╛ рд╣реИ, рддреЛ рд╡реЗ рдЖрдкрдХреЛ рд╡рд╛рдВрдЫрд┐рдд рдирд╛рдо рдХреЗ рд╕рд╛рде рдПрдХ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рднрдВрдбрд╛рд░ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣реЗрдВрдЧреЗред


рдкреБрд╖реНрдЯрд┐ рдХреЗ рдХреБрдЫ рд╕рдордп рдмрд╛рдж, рдЖрдкрдХрд╛ GroupId рдмрдирд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рд╣рдо рдЕрдЧрд▓реЗ рдЪрд░рдг, рдЧреНрд░реИрдбрд▓ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝ рд╕рдХрддреЗ рд╣реИрдВред


рдЧреНрд░реЗрдбрд┐рдВрдЧ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдирд╛


рдЗрд╕ рд▓реЗрдЦрди рдХреЗ рд╕рдордп, рдореБрдЭреЗ рдЧреНрд░реИрдбрд▓ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдкреНрд▓рдЧрдЗрдиреНрд╕ рдирд╣реАрдВ рдорд┐рд▓рд╛ рдЬреЛ рдЖрд░реНрдЯрд╡рд░реНрдХ рдХреЗ рдкреНрд░рдХрд╛рд╢рди рдореЗрдВ рдорджрдж рдХрд░ рд╕рдХреЗред рдпрд╣ рдПрдХрдорд╛рддреНрд░ рдкреНрд▓рдЧрдЗрди рд╣реИ рдЬреЛ рдореИрдВрдиреЗ рдкрд╛рдпрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рд▓реЗрдЦрдХ рдиреЗ рдЕрдкрдиреЗ рдЖрдЧреЗ рдХреЗ рд╕рдорд░реНрдерди рд╕реЗ рдЗрдирдХрд╛рд░ рдХрд░ рджрд┐рдпрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдореИрдВрдиреЗ рдЦреБрдж рд╣реА рд╕рдм рдХреБрдЫ рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдХрд░рдирд╛ рдмрд╣реБрдд рдореБрд╢реНрдХрд┐рд▓ рдирд╣реАрдВ рд╣реИред


рдкрд╣рд▓реА рдмрд╛рдд рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдирд╛ рд╣реИ рдХрд┐ рд╕реЛрдирд╛рдЯрд╛рдЗрдк рдХреА рдкреНрд░рдХрд╛рд╢рди рдЖрд╡рд╢реНрдпрдХрддрд╛рдПрдВ рд╣реИрдВред рд╡реЗ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИрдВ:


  • рд╕реНрд░реЛрдд рдХреЛрдб рдФрд░ JavaDoc рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐, рдЕрд░реНрдерд╛рдд рдореМрдЬреВрдж рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП -sources.jarрдФрд░ -javadoc.jarрдлрд╝рд╛рдЗрд▓реЗрдВред рдЬреИрд╕рд╛ рдХрд┐ рдкреНрд░рд▓реЗрдЦрди рдореЗрдВ рдХрд╣рд╛ рдЧрдпрд╛ рд╣реИ, рдпрджрд┐ рд╕реНрд░реЛрдд рдХреЛрдб рдпрд╛ рдкреНрд░рд▓реЗрдЦрди рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реИ, рддреЛ рдЖрдк рдкрд░реАрдХреНрд╖рдг рдкрд╛рд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдбрдореА -sources.jarрдпрд╛ -javadoc.jarрдПрдХ рд╕рд╛рдзрд╛рд░рдг README рдХреЗ тАЛтАЛрд╕рд╛рде рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ ред
  • GPG/PGP, .asc , , .
  • pom
  • groupId, artifactId version. -SNAPSHOT
  • name, description url
  • ,

, . .


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

, -sources.jar -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
            }
        }
    }
}

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

, : System.getenv('RELEASE_VERSION'). .


PGP


Sonatype GPG/PGP . GnuPG .


  • : gpg --gen-key, , e-mail, .
  • id : gpg --list-secret-keys --keyid-format short. Id , : rsa2048/9B695056
  • https://keys.openpgp.org : gpg --keyserver https://keys.openpgp.org/ --send-keys 9B695056
  • , : gpg --export-secret-key 9B695056 > D:\\gpg\\9B695056.gpg

Github Actions


, , Github Actions.
Github Actions тАУ , , CI/CD. , : , issues. .


Sonatype , .



, id , , , PGP , / Sonatype. :



:


  • SONATYPE_USERNAME/SONATYPE_PASSWORD тАФ /, Sonatype
  • SIGNING_KEYID/SIGNING_PASSWORD тАФ id PGP , .

GPG_KEY_CONTENTS . , PGP . , , .


  • gpg: gpg --symmetric --cipher-algo AES256 9B695056.gpg, . : SECRET_PASSPHRASE
  • base64: base64 9B695056.gpg.gpg > 9B695056.txt. : GPG_KEY_CONTENTS.

PR


: .github/workflows.


, , gradle-ci-build.yml :


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

master, dev testing, .


jobs , . ubuntu, Java 8, Gradle eskatos/gradle-command-action@v1, , arguments. secrets.SONATYPE_USERNAME secrets.SONATYPE_PASSWORD , .


Actions:




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

, . , v.


PGP , . RELEASE_VERSION gradle.build . Prepare to publish. GPG_KEY_CONTENTS, gpg , , secret.gpg.


GITHUB_REF, , . refs/tags/v0.0.2 11 , . Gradle : test publish


Sonatype


, . :



v. Publish release, , Sonatype Nexus :



Staging . Open, Close, . , Close . MavenCentral. , Release, Sonatype.


, MavenCentral, , . , . , . , MavenCentral 5 .


рдмрд╕ рдЗрддрдирд╛ рд╣реА, рд╣рдордиреЗ рдЕрдкрдиреА рдХрд▓рд╛рдХреГрддрд┐рдпреЛрдВ рдХреЛ рдорд╛рд╡рдирд╕реЗрдиреНрдЯреНрд░рд▓ рдореЗрдВ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд┐рдпрд╛ред


рдЙрдкрдпреЛрдЧреА рдХрдбрд╝рд┐рдпрд╛рдБ


  • рдЗрд╕реА рддрд░рд╣ рдХрд╛ рд▓реЗрдЦ , рдХреЗрд╡рд▓ рдорд╛рд╡реЗрди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкреНрд░рдХрд╛рд╢рди
  • рд╕реНрдЯреЗрдЬрд┐рдВрдЧ рд░рд┐рдкреЛрдЬрд┐рдЯрд░реА рд╕реЛрдирд╛рдЯрд╛рдЗрдк
  • рдЬреАрд░рд╛ рд╕реЛрдирд╛рдЯрд╛рдЗрдк, рдЬрд┐рд╕рдореЗрдВ рдЖрдкрдХреЛ рдПрдХ рдХрд╛рд░реНрдп рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ
  • рдПрдХ рдЙрджрд╛рд╣рд░рдг рднрдВрдбрд╛рд░ рдЬрд╣рд╛рдВ рдпрд╣ рд╕рдм рд╕реНрдерд╛рдкрд┐рдд рд╣реИ

All Articles