GitHub Packagesへネイティブイメージをデプロイする
概要
GitHub ActionsでネイティブイメージをビルドしてGitHub Packagesへデプロイする方法を記載します。
要点は次の通りです。
- ネイティブイメージのビルドはNative Image Maven Pluginを使用して行う
- 生成されたネイティブイメージを
deploy:deploy-fileでデプロイする - GitHub ActionsでDeLaGuardo/setup-graalvmを使ってGraalVMのセットアップを行う
コード例は次のリポジトリです。
Native Image Maven Pluginの設定
まずネイティブビルドの設定です。
Native Image Maven Pluginを追加してpackageフェーズでnative-imageゴールが動くようにしています。
<plugin>
<groupId>org.graalvm.nativeimage</groupId>
<artifactId>native-image-maven-plugin</artifactId>
<version>${graalvm.version}</version>
<executions>
<execution>
<goals>
<goal>native-image</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
<configuration>
<imageName>${project.artifactId}</imageName>
<mainClass>com.example.App</mainClass>
<buildArgs>
--no-fallback
</buildArgs>
</configuration>
</plugin>
deploy:deploy-fileのための設定
次にApache Maven Deploy Pluginの設定です。
fileへネイティブイメージのパスを設定します。
urlはデプロイ先となるMavenリポジトリ(今回はGitHub Packages)のURLです。
これはdistributionManagementから読み取ってくれるんじゃないのか?と思ったんですが、そうでもないんですかね。
よくわかっていないです。
それからclassifier、packagingにそれぞれbinとexeを設定していますが、これで良いのかは実はよくわかっていません。
特にpackagingは決まった値がいくつかあるはずで、exeなんて値はないはず……でもこれでデプロイできたのでとりあえずまあいいかという感じです。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<repositoryId>github</repositoryId>
<file>${project.build.directory}/${project.artifactId}</file>
<url>${repository.url}</url>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<classifier>bin</classifier>
<packaging>exe</packaging>
</configuration>
</plugin>
なお、distributionManagementの設定はGitHub PackagesへJARをデプロイするを参考にしてください。
GitHub Actionsのビルドスクリプト
jobs.<job_id>.steps以下を説明します。
まずはactions/checkoutでソースコードをチェックアウトします。
それからDeLaGuardo/setup-graalvmでGraalVMをセットアップします。
さらにguコマンドでnative-imageコマンドをインストールしています。
最後にmvn packageしてdeploy:deploy-fileでデプロイしています。
- uses: actions/checkout@v2
- uses: DeLaGuardo/setup-graalvm@4.0
with:
graalvm: 21.2.0
java: java11
- name: Install native-image command
run: |
gu install native-image
native-image --version
- name: Cache local Maven repository
uses: actions/cache@v2
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
- name: Maven build and deploy
run: |
GITHUB_USERNAME=backpaper0 GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }} mvn -B -DskipTests package deploy:deploy-file -s settings.xml
これでgit pushすればGitHub Actionsによってビルドが行われてネイティブイメージがGitHub PackagesのMavenリポジトリへデプロイされます。
デプロイされたネイティブイメージの動作確認
ubuntu-latestでビルドしたのでUbuntuで動作確認してみます。
私はMacを使っているのでDockerを利用しようと思います。
まずコード例のリポジトリからネイティブイメージをダウンロードします。
それから実行権限を付けます。
chmod +x native-deploy-demo-1.0-20210920.091209-1-bin.exe
DockerでUbuntuを起動してネイティブイメージを実行します。
docker run --rm -v $PWD:/workspace ubuntu \
./workspace/native-deploy-demo-1.0-20210920.091209-1-bin.exe
Hello Worldと出力されたらOKです。
アーカイブにしてデプロイする
本記事の公開後にまきさんが教えてくれたのですが、アーカイブにしてデプロイすると便利そうです。
あと、-bin.exeみたいな違和感があるsuffixにしなくてもよくなりますね。
そういうわけでpom.xmlを修正して試してみたのですが、なぜかGitHub Packagesへデプロイしようとするとアーカイブファイルはデプロイされているのに409 Conflictが発生してビルドエラーとなりました……
ローカルに立てたSonatype Nexusへはエラーなくデプロイできるのですが……
ネイティブイメージをデプロイできたことで当面の目的は達成できているため、この課題は置いておきます。
それでまた気が向いたらトラブルシュートしようと思います。
以上です。
Discussion