
GitHub Actions Advent Calendar 2019 18日目の記事です。
Javaのパッケージ(jar)はMaven Centralにアップするのが主流でした。しかし、GitHub Package Registryがリリースされて、Javaパッケージの公開のハードルが下がったような気がします。
今回は、GitHubにtagをpushすることで、GitHub ActionsでGitHub Package RegistryにJavaパッケージを自動で公開する方法を記します。
仕組み

上の画像のような仕組みで、tagをpushしたときのみ、自動でパッケージを公開できるように設定します。*1
環境
以下の環境で検証しました。
- Java 11
- Gradle 5.2.1
パッケージをGitHub Actionsで公開する
今回公開するパッケージ
Sampleという簡単なクラスを公開して、別のプロジェクトでMavenやGradleでSampleクラスを使えるようにします*2。

公開するための設定
settings.gradle
ファイル全体はこちら
artifactIdの設定
rootProject.name = 'publish'
rootProject.nameは公開後、artifactIdになります。
com.github.korosuke613.example.publish:v1.0.1の太字部分です。
build.gradle
GitHub公式のドキュメントを参考にしています。
plugins {
id 'java'
id "maven-publish" // 公開に必要なプラグイン
}
group 'com.github.korosuke613.example'
// GitHub Action上でタグ名がバージョンとなる
version = System.getenv("GRADLE_PUBLISH_VERSION") ?: "1.0-SNAPSHOT"
sourceCompatibility = 11
repositories {
mavenCentral()
}
// 公開設定
publishing {
repositories {
maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/korosuke613/java-plugin-publish-github-example")
credentials {
username = System.getenv("GITHUB_PACKAGE_USERNAME")
password = System.getenv("GITHUB_PACKAGE_TOKEN")
}
}
}
publications {
gpr(MavenPublication) {
from(components.java)
}
}
}
ファイル全体はこちら
プラグインの追加
plugins {
id 'java'
id "maven-publish"
}
GitHub Package Registryに公開するために、maven-publishプラグインをインストールする必要があります。
groupIdの設定
group 'com.github.korosuke613.example'
groupは公開後、groupIdになります。
com.github.korosuke613.example.publish:v1.0.1の太字部分です。((僕は、groupIdとartifactIdをどこで区切れば良いのかいまいちよくわかっていません。だれか教えてください))
versionの設定
version = System.getenv("GRADLE_PUBLISH_VERSION") ?: "1.0-SNAPSHOT"
System.getenv()で環境変数を取得できます。versionに取得した環境構築の値を代入するのですが、もし、指定した環境変数がなければ、1.0-SNAPSHOTを代入するようにしています。
GitHub Actionsでワークフローを実行中に、GRADLE_PUBLISH_VERSIONにタグ名を代入します。
versionは公開後、そのままversionになります。
com.github.korosuke613.example.publish:v1.0.1の太字部分です。
公開先と認証情報の設定
publishing {
repositories {
maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/korosuke613/java-plugin-publish-github-example")
credentials {
username = System.getenv("GITHUB_PACKAGE_USERNAME")
password = System.getenv("GITHUB_PACKAGE_TOKEN")
}
}
}
publications {
gpr(MavenPublication) {
from(components.java)
}
}
}
urlにはhttps://maven.pkg.github.com/GitHubユーザ名/リポジトリ名を設定します。usernameにはGitHubユーザ名を設定します。passwordにはGitHubのパーソナルアクセストークンを設定します。(GitHubのパスワードではありません!)もし、自分のPCでgradle publishするなら、パーソナルアクセストークンを作成する必要がありますが、GitHub Actionsでは、secrets.GITHUB_TOKENで代用できるので、パーソナルアクセストークンを改めて作成する必要はありません。
usernameとpasswordの設定で使っている環境変数は、GitHub Actionsでワークフローを実行中に設定します。
publish.yaml
GitHub Actionsのワークフローの設定です。
name: Publish
on:
push:
tags:
- v* # 'v'から始まるタグをpushしたときのみワークフローを実行する
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Set up JDK 11
uses: actions/setup-java@v1
with:
java-version: 11
- name: Get the tag version # タグ名を保存する
id: get_version
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
- name: Publish
env:
GITHUB_PACKAGE_USERNAME: korosuke613 # ユーザー名
GITHUB_PACKAGE_TOKEN: ${{ secrets.GITHUB_TOKEN }} # トークン
GRADLE_PUBLISH_VERSION: ${{ steps.get_version.outputs.VERSION }} # タグ名
run: ./gradlew publish
ファイル全体はこちら
トリガー設定
on:
push:
tags:
- v*
このワークフローを実行する条件を設定しています。
この設定は、vから始まる名前のtagをpushしたらトリガーするというものになります。この設定をしていることで、無駄にパッケージを公開せずにすみます。
tag名の保存
- name: Get the tag version
id: get_version
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
タグ名を保存しています。
こちらのサイトを参考にしました。
パッケージ公開
- name: Publish
env:
GITHUB_PACKAGE_USERNAME: korosuke613
GITHUB_PACKAGE_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GRADLE_PUBLISH_VERSION: ${{ steps.get_version.outputs.VERSION }}
run: ./gradlew publish
実際に./gradlew publishを実行して、GitHub Package Registryにパッケージを公開する設定です。
envブロックでは環境変数を設定することができます。
認証情報
GITHUB_PACKAGE_USERNAME、GITHUB_PACKAGE_TOKENは公開に必要な認証情報となります。(参照)
secrets.GITHUB_TOKENは「GitHub Actionsの代理で認証を受けるために利用できるトークン」*3です。GitHub Actions上で参照できるため、GitHub周りの認証で楽できます。
version
GRADLE_PUBLISH_VERSIONは、versionの設定に必要なtag名となります。(参照)
steps.get_version.outputs.VERSIONは、「tag名の保存」で設定したtag名を参照しています。
実際にtagをpushする
実際にtag(v0.0.5)をpushして、Actionsのページに行くと、Publishというワークフローが実行されていることが確認できます。(リンク)*4

画像のように、Task :publishが正常に実行されていたら、パッケージがアップロードされているはずです。(リンク)

パッケージを利用する
公開したパッケージを利用しましょう。
利用するための設定
build.gradle
plugins {
id 'java'
}
group 'com.github.korosuke613.example'
version '1.0-SNAPSHOT'
sourceCompatibility = 11
repositories {
maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/korosuke613/java-plugin-publish-github-example")
credentials {
username = System.getenv("GITHUB_PACKAGE_USERNAME")
password = System.getenv("GITHUB_PACKAGE_TOKEN")
}
}
mavenCentral()
}
dependencies {
implementation "com.github.korosuke613.example:publish:v1.0.1"
implementation "com.github.korosuke613:pict4java:v2.0.0"
}
GitHub Package Registryにログインする
repositories {
maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/korosuke613/java-plugin-publish-github-example")
credentials {
username = System.getenv("GITHUB_PACKAGE_USERNAME")
password = System.getenv("GITHUB_PACKAGE_TOKEN")
}
}
mavenCentral()
}
パッケージを公開したのと同じように、GitHub Package Registryにログインする必要があります。
Publicなリポジトリでパッケージを公開していたとしても、認証作業が必要です。
なぜこういう作りになっているのかはわかりません。実際、GitHub Communityで議論になっています。
urlには、先ほどと同じようなURLを設定していますが、設定したURLとは別のリポジトリのパッケージも、問題なく利用できたことから、別のリポジトリのURLでも良さそうです。一回認証すれば良いということなのでしょうか。
(ここら辺は僕も良くわかっていないので、だれか教えてください...)
。
dependenciesに追加
dependencies {
implementation "com.github.korosuke613.example:publish:v1.0.1"
implementation "com.github.korosuke613:pict4java:v2.0.0"
}
dependenciesに先ほど公開したパッケージを記述しています。
今回は、<groupId>:<artifactId>:<version>というルールで記述しています。*5
ちなみに、com.github.korosuke613:pict4java:v2.0.0は僕が既に同じ方法で公開している別のパッケージです。
実際に使ってみる
本当に使えるか確認するため、以下のソースコードを実行しました。
Main.java
package com.github.korosuke613.example.publish.use; import com.github.korosuke613.example.publish.Sample; public class Main { public static void main(String[] args) { Sample sample = new Sample(); System.out.println(sample.sum(1, 2)); System.out.println(sample.sum("Hello ", "GitHub Package Registry")); } }
実行結果
$ ./gradlew run > Task :run 3 Hello GitHub Package Registry BUILD SUCCESSFUL in 1s 2 actionable tasks: 1 executed, 1 up-to-date
ちゃんと、3、Hello GitHub Package Registryと出力されているので、正しくインポートできていることが確認できました!
おわりに
今回は、tagをpushすることで、Javaのパッケージを自動でGitHub Package Registryに公開してみました😎
もっと良い方法があれば、ぜひ教えてくださいm(__)m