ãã®èšäºã§ã¯ãGradle ãã«ããŒã䜿çšããŠãGithub Actions ãéã㊠Java ã¢ãŒãã£ãã¡ã¯ããæåãã Sonatype Maven Central Repository ã«å ¬éããããã»ã¹ã詳ããèŠãŠãããããšæããŸãã
éåžžã®ãã¥ãŒããªã¢ã«ã XNUMX ãæã«ãªãããããã®èšäºãæžãããšã«ããŸããã ããã«ããã¹ãŠã®æ å ±ã¯ããŸããŸãªãœãŒã¹ããå°ããã€åéããå¿ èŠãããããŸã£ããæ°ãããã®ã§ã¯ãããŸããã§ããã æ°ã«ããªãã§ãã ãããç«ã®äžã«ããããã
Sonatype ã§ã®ãªããžããªã®äœæ
æåã®ã¹ãããã¯ãSonatype Maven Central ã§ãªããžããªãäœæããããšã§ãã ãã®ããã«ç§ãã¡ã¯è¡ããŸã
確èªåŸãã°ãããããšãGroupId ãäœæããã次ã®ã¹ãããã§ãã Gradle æ§æã«é²ãããšãã§ããŸãã
Gradleã®æ§æ
ãã®èšäºã®å·çæç¹ã§ã¯ãã¢ãŒãã£ãã¡ã¯ãã®å
¬éã«åœ¹ç«ã€ Gradle ãã©ã°ã€ã³ã¯èŠã€ãããŸããã§ããã
æåã«ç解ããå¿ èŠãããã®ã¯ãSonatype ã®åºçèŠä»¶ã§ãã ãããã¯æ¬¡ã®ãšããã§ãã
- ãœãŒã¹ ã³ãŒããš 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 protected]'
}
}
}
}
}
次ã«ãçæãããã¢ã»ã³ããªäžã«ãããæå®ããå¿
èŠããããŸã -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
}
}
}
}
ãã㯠sonatypeãŠãŒã¶ãŒå О sonatypeãã¹ã¯ãŒã ç»é²æã«äœæããããã°ã€ã³ãšãã¹ã¯ãŒããå«ãå€æ°
ãããã£ãŠãæçµç㪠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 protected]'
}
}
}
}
}
ç°å¢å€æ°ããããŒãžã§ã³ãååŸããŠããããšã«æ³šæããŠãã ããã System.getenv('RELEASE_VERSION')
ã çµã¿ç«ãŠæã«å
¬éããã¿ã°åããååŸããŸãã
PGP ããŒã®çæ
Sonatype ã®èŠä»¶ã® XNUMX ã€ã¯ããã¹ãŠã®ãã¡ã€ã«ã GPG/PGP ããŒã§çœ²åãããŠããããšã§ãã ãã®ããã«ç§ãã¡ã¯è¡ããŸã
- ããŒãã¢ãçæããŸãã
gpg --gen-key
ããŠãŒã¶ãŒåãé»åã¡ãŒã«ãå ¥åãããã¹ã¯ãŒããèšå®ããŸãã - 確èªããŠã¿ãŸããã
id
ã³ãã³ãã§ããŒãå ¥åããŸããgpg --list-secret-keys --keyid-format short
ã ID ã¯ã¹ã©ãã·ã¥ã®åŸã«æå®ãããŸã (äŸ: rsa2048/9B695056)ã - å
¬éããŒããµãŒããŒã«å
¬éãã
https://keys.openpgp.org ã³ãã³ãã§:gpg --keyserver [https://keys.openpgp.org](https://keys.openpgp.org/) --send-keys 9B695056
- ç§å¯éµãä»»æã®å Žæã«ãšã¯ã¹ããŒãããŸããå°æ¥å¿
èŠã«ãªããŸãã
gpg --export-secret-key 9B695056 > D:\gpg\9B695056.gpg
Github ã¢ã¯ã·ã§ã³ã®ã»ããã¢ãã
æçµæ®µéã«é²ã¿ãGithub Actions ã䜿çšããŠãã«ããšèªåå
¬éãèšå®ããŸãã
Github Actions ã¯ãå®å
šãª CI / CD ãµã€ã¯ã«ãå®è£
ããããšã§ã¯ãŒã¯ãããŒãèªååã§ããæ©èœã§ãã ãã«ãããã¹ãããããã€ã¯ãã³ãŒãã®ããã·ã¥ããªãªãŒã¹ã®äœæãåé¡ãªã©ã®ããŸããŸãªã€ãã³ãã«ãã£ãŠããªã¬ãŒã§ããŸãã ãã®æ©èœã¯ãããªã㯠ãªããžããªã§ã¯å®å
šã«ç¡æã§ãã
ãã®ã»ã¯ã·ã§ã³ã§ã¯ããã«ããšããã·ã¥ ã³ãŒããèšå®ãããªãªãŒã¹æã« Sonatype ãªããžããªã«ãããã€ããæ¹æ³ãšãã·ãŒã¯ã¬ãããèšå®ããæ¹æ³ã説æããŸãã
ç§ãã¡ã¯ç§å¯ãèšå®ããŸã
èªåã¢ã»ã³ããªãšãããã€ã¡ã³ãã«ã¯ãã㌠IDãããŒçææã«å ¥åãããã¹ã¯ãŒããPGP ããŒèªäœãSonatype ãã°ã€ã³/ãã¹ã¯ãŒããªã©ãå€æ°ã®ã·ãŒã¯ã¬ããå€ãå¿ èŠã§ãã ãããã¯ãªããžããªèšå®ã®ç¹å¥ãªã»ã¯ã·ã§ã³ã§èšå®ã§ããŸãã
次ã®å€æ°ãèšå®ããŸãã
- SONATYPE_USERNAME / SONATYPE_PASSWORD - Sonatype ã«ç»é²ãããšãã«å ¥åãããã°ã€ã³/ãã¹ã¯ãŒã
- SIGNING_KEYID/SIGNING_PASSWORD â çææã«èšå®ããã PGP ã㌠ID ãšãã¹ã¯ãŒãã
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
ããã«ãªã¯ãšã¹ããäœæãããšããåæ§ã§ãã
ãžã§ã ã»ã¯ã·ã§ã³ã§ã¯ãæå®ãããã€ãã³ãã«å¯ŸããŠå®è¡ãããã¹ããããæå®ããŸãã ãã®å Žåãææ°ããŒãžã§ã³ã® ubuntu äžã«æ§ç¯ããJava 8 ã䜿çšããGradle çšã®ãã©ã°ã€ã³ã䜿çšããŸãã eskatos/gradle-command-action@v1
ããã¯ããã«ããŒã®ææ°ããŒãžã§ã³ã䜿çšããŠãã§æå®ãããã³ãã³ããå®è¡ããŸãã arguments
ã å€æ° secrets.SONATYPE_USERNAME
О secrets.SONATYPE_PASSWORD
ãããã¯ç§ãã¡ã以åã«å°ããç§å¯ã§ãã
ãã«ãçµæ㯠[ã¢ã¯ã·ã§ã³] ã¿ãã«åæ ãããŸãã
æ°ãããªãªãŒã¹ããªãªãŒã¹ããããšãã«èªåãããã€ãã
èªåãããã€çšã«å¥ã®ã¯ãŒã¯ãã㌠ãã¡ã€ã«ãäœæããŸããã 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 ã§å§ãŸãå¿
èŠããããŸãã [ãªãªãŒã¹ã®å
¬é] ãã¯ãªãã¯ããåŸãã¯ãŒã¯ãããŒãæ£åžžã«å®äºããå Žåã¯ã次ã®æé ã«é²ãããšãã§ããŸãã
ã¢ãŒãã£ãã¡ã¯ããã¹ããŒãžã³ã° ãªããžããªã«è¡šç€ºãããŸããã ããã«ããªãŒãã³ãã¹ããŒã¿ã¹ã衚瀺ãããŸãããé©åãªãã¿ã³ãæŒããŠæåã§ãã¯ããŒãºãã¹ããŒã¿ã¹ã«ç§»è¡ããå¿ èŠããããŸãã ãã¹ãŠã®èŠä»¶ãæºããããŠããããšã確èªããåŸãã¢ãŒãã£ãã¡ã¯ã㯠Close ã¹ããŒã¿ã¹ã«ãªããå€æŽã§ããªããªããŸãã ãã®åœ¢åŒã§ã¯ãæçµçã« MavenCentral ã«é 眮ãããŸãã ãã¹ãŠåé¡ãªããã°ããã¿ã³ãæŒããŠãã ãã ãªãªãŒã¹ãã¢ãŒãã£ãã¡ã¯ã㯠Sonatype ãªããžããªã«ä¿åãããŸãã
ã¢ãŒãã£ãã¡ã¯ãã MavenCentral ã«åã蟌ãã«ã¯ãæåã«äœæããã¿ã¹ã¯ã§ã¢ãŒãã£ãã¡ã¯ããèŠæ±ããå¿ èŠããããŸãã ãããè¡ãå¿ èŠãããã®ã¯ 5 åã ããªã®ã§ãåããŠå ¬éããŸãã 次å以éãããã¯å¿ èŠãããŸããããã¹ãŠãèªåçã«åæãããŸãã 圌ãã¯ããã«åæãæå¹ã«ããŠãããŸããããã¢ãŒãã£ãã¡ã¯ãã MavenCentral ã§å©çšã§ããããã«ãªããŸã§ã«çŽ XNUMX æ¥ããããŸããã
ããã§ãã¢ãŒãã£ãã¡ã¯ãã MavenCentral ã«å ¬éã§ããŸããã
䟿å©ãªãªã³ã¯é
- 䌌ãŠãã
èšäº ãMaven çµç±ã§ã®ã¿å ¬éããŸã - äžæŒ
ãªããžã㪠ãœãã¿ã€ã JIRA ã¿ã¹ã¯ãäœæãã SonatypeäŸ ãã¹ãŠãèšå®ããããªããžããª
åºæïŒ habr.com