GeekFactory

int128.hatenablog.com

GradleでMaven Central Repositoryに成果物をリリースする

Gradleでビルドした成果物をMaven Central Repositoryにリリースする方法を説明します。

成果物の公開にあたってはSonatype OSSRHで申請が必要です。こちらのイケメンな記事が大変参考になります。こちらの記事ではMavenを使っていますが、本稿ではGradleを使います。

PGP鍵を確認する

成果物の署名に使うPGP鍵を確認します。まだ作成していない場合は先ほどの記事やSonatypeの公式ドキュメントを参考にしてください。gpgコマンドはbrew installでインストールできます。

$ gpg --list-keys
/Users/hidetake/.gnupg/pubring.gpg
----------------------------------
pub   4096R/1234ABCD 2012-12-14
uid                  ikemen <ikemen@example.com>
sub   4096R/FEDC9876 2012-12-14

共通プロパティファイルを作る

ホームディレクトリに .gradle/gradle.properties というファイルを作ります。このファイルでは全プロジェクトで共通で使うプロパティを定義します。

signing.keyId=1234ABCD
signing.secretKeyRingFile=/home/ikemen/.gnupg/secring.gpg
sonatypeUsername=ikemen
sonatypeFullname=ikemen

内容は下記の通りです。

キー
signing.keyId gpgコマンドで確認したPGP
signing.secretKeyRingFile 通常はホームディレクトリの .gnupg/secring.gpg
sonatypeUsername Sonatype OSSRHのユーザID(成果物のメタデータに入ります)
sonatypeFullname 名前(成果物のメタデータに入ります)

プロジェクトのビルドスクリプトを変更する

ビルドが通って成果物を生成できる前提とします。ここでは私が公開している gradle-ssh-plugin のビルドスクリプトを例に話を進めます。

ビルドスクリプトでは以下の点に気を付けます:

  • グループや名称が設定されていること。
  • 依存関係がMaven Central Repositoryで閉じていること。
  • ドキュメントJARが生成されること。
  • ソースJARが生成されること。

例えば、Groovyビルドの場合は下記のようになります。

// build.gradle
apply plugin: 'groovy'

description = 'Gradle SSH Plugin provides remote execution and file transfer capabilities'
group = 'org.hidetake'
version = '0.1.6'

repositories {
  mavenCentral()
}

task javadocJar(type: Jar, dependsOn: groovydoc) {
  classifier = 'javadoc'
  from "${buildDir}/javadoc"
}

task sourcesJar(type: Jar) {
  from sourceSets.main.allSource
  classifier = 'sources'
}

artifacts {
  archives jar
  archives javadocJar
  archives sourcesJar
}

if (gradle.startParameter.taskNames.contains('uploadArchives')) {
  apply from: 'build.publish.gradle'
}

成果物のリリースに必要な部分は別のスクリプトに切り出しておくと見通しがよくなります。タスクに uploadArchive が指定された場合のみリリーススクリプトを読み込むようにしておきます(最後の3行)。

リリーススクリプトは下記です。PGP鍵やSonatype OSSRHのパスワードをスクリプトに書かず、毎回聞くようにしています。POMのメタデータはプロジェクトに合わせて変更してください。

// build.publish.gradle
apply plugin: 'signing'
apply plugin: 'maven'

boolean validProperty(propertyName) {
  try { project.property(propertyName) != null }
  catch (MissingPropertyException) { false }
}
assert validProperty('signing.keyId'),             'properties for signing must be provided'
assert validProperty('signing.secretKeyRingFile'), 'properties for signing must be provided'
assert validProperty('sonatypeUsername'),          'properties for publish must be provided'
assert validProperty('sonatypeFullname'),          'properties for publish must be provided'

String askPassword(prompt) {
  "${System.console().readPassword(prompt)}"
}
ext.'signing.password' = askPassword("Enter password for PGP key ${property('signing.keyId')}: ")
ext.'sonatypePassword' = askPassword("Enter password for ${sonatypeUsername}@oss.sonatype.org: ")

signing {
  sign configurations.archives
}

uploadArchives {
  repositories.mavenDeployer {
    repository(url: 'https://oss.sonatype.org/service/local/staging/deploy/maven2/') {
      authentication(userName: sonatypeUsername, password: sonatypePassword)
    }
    beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
    pom.project {
      name 'Gradle SSH Plugin'
      packaging 'jar'
      description project.description
      url 'https://github.com/int128/gradle-ssh-plugin'
      scm {
        url 'git@github.com:int128/gradle-ssh-plugin.git'
        connection 'scm:git:git@github.com:int128/gradle-ssh-plugin.git'
        developerConnection 'scm:git:git@github.com:int128/gradle-ssh-plugin.git'
      }
      licenses {
        license {
          name 'The Apache Software License, Version 2.0'
          url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
          distribution 'repo'
        }
      }
      developers {
        developer {
          id sonatypeUsername
          name sonatypeFullname
        }
      }
    }
  }
}

リリースする

gradle uploadArchivesで成果物をアップロードできます。

$ gradle uploadArchives
> LoadingEnter password for PGP key 1234ABCD: 
Enter password for ikemen@oss.sonatype.org: 
:compileJava UP-TO-DATE
:compileGroovy UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:jar UP-TO-DATE
:groovydoc UP-TO-DATE
:javadocJar UP-TO-DATE
:sourcesJar UP-TO-DATE
:signArchives
:uploadArchives
Uploading: org/hidetake/gradle-ssh-plugin/0.1.6/gradle-ssh-plugin-0.1.6.jar to repository remote at https://oss.sonatype.org/service/local/staging/deploy/maven2/
Transferring 109K from remote
Uploaded 109K
...

BUILD SUCCESSFUL

Total time: 31.132 secs

アップロードできたらSonatypeでリリースの操作を行いましょう。詳細はドキュメント参照で!

まとめ

以下のステップでGradleでMaven Central Repositoryに成果物をリリースできます。皆さんもぜひライブラリを公開しましょう。

  1. Sonatype OSSRHに申請を出す。
  2. PGP鍵を作る。
  3. ビルドスクリプトを書く。
  4. リリースする。