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