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