GithubActionsのちょっとした応用|cache × actions-timeline
はじめに
先日のGithubActionsについてのカンファレンスで学んだことを復習及びアウトプットしようと思い、今回このような記事を書きました。
引用
先に今回参考にさせていただいた記事を載せておきます。
引用サイト
・Build CI/CD Pipeline for Java Maven Using GitHub Actions
・actions-timeline
ソースコードはこちら
目的と行うこと
目的
今回のゴール(目的)は以下の内容をインプットすることとします。
・cacheの活用方法
・Kesin11/actions-timelineの活用方法
行うこと
今回GithubActionsを解説するにあたってデモでJavaを扱い、以下の内容を行います。
Javaを知らない方でも理解できるような内容なのでぜひ見ていってください。
・mavenプロジェクトで作成したテストメソッドを用いた自動テスト
・jarファイルを生成し、エクスポート
実装例
プロジェクト構成は以下のとおりです。
Javaファイルは特に理解する必要はありません。さっと目を通す程度で問題ないです。
ここでは一番最後のmaven.yamlに注目してください。
フォルダ構成
作成したデモオブジェクト
package hello;
public class Greeter {
public String sayHello() {
return "Hello world!";
}
public String sayAnything(String word) {
return word + "が呼ばれた!";
}
}
mainメソッドを含むクラス
package hello;
import org.joda.time.LocalTime;
public class HelloWorld {
public static void main(String[] args) {
LocalTime currentTime = new LocalTime();
System.out.println("The current local time is: " + currentTime);
Greeter greeter = new Greeter();
System.out.println(greeter.sayHello());
}
}
テストクラス
package hello;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.*;
import org.junit.Test;
public class GreeterTest {
private final Greeter greeter = new Greeter();
@Test
public void greeterSaysHello() {
assertThat(greeter.sayHello(), containsString("Hello"));
}
@Test
public void greeterSaysAnyThing() {
String result = greeter.sayAnything("テストメソッド");
assertThat(result, containsString("テストメソッドが呼ばれた!"));
System.out.println(result);
}
}
GithubActionsで実行するジョブについて
name: Java Maven Build & Publish Artifact
on:
push:
branches: [ "main" ]
jobs:
build_test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
cache: maven # ポイント2
- name: Build and Run Tests with Maven
run: mvn clean package # Unitテストを実行してくれる
- name: Build with Maven
run: mvn -B package --file pom.xml # Mavenを使ってプロジェクトをビルド
publish-job:
runs-on: ubuntu-latest
needs: build_test
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
- run: mvn --batch-mode --update-snapshots verify
- run: mkdir staging && cp target/*.jar staging
- uses: actions/upload-artifact@v4
with:
name: Package
path: staging
actions-timeline:
needs: [build_test, publish-job]
runs-on: ubuntu-latest
steps:
- uses: Kesin11/actions-timeline@v2 # ポイント1
検証
cacheを使用した場合と使用しなかった場合の挙動を図ります。
なので今回はすでにソースコードがあるのでmainブランチに
「first commit」
「second commit」
と2回コミット&プッシュを行います。
まずは1回目の「first commit」でbuild_testジョブとpublish-jobジョブが動作しているか確認してみましょう。
build_testジョブでテストコードが呼び出されていることが確認できます。
また、publish-jobジョブでPackegeが出力され、jarファイルの生成も確認できました。
しかし、warningが出てしまいしました。
使用しているactions/checkout@v3
が古かったみたいなのでactions/checkout@v4
に修正して「second commit」をプッシュしてみます。(実装例のソースコードは既に修正済みのコードになります)
無事にwarningを削除できました。
解説
前提や検証を踏まえた説明が長くなってしまいましたが、ここから本題です。
まず、maven.yamlの内容はざっくりと下記についてです。
build_test ジョブ:
- プロジェクトのビルド
- JUnitテストの実行
- jarファイルの生成
publish-job ジョブ:
- build_testで成功した成果物の検証
- jarファイルをGithub上にアップロード
actions-timeline ジョブ:
- 各ジョブの時間を計測
ポイント1 actions-timelineの組み込み
workflow画面
actions-timelineを組み込むことで各ジョブの時間をグラフでわかりやすく見ることができます。
また、水色で表示されている箇所を見ればわかるように、ランナーの待機時間も表示することができます。
これにより、どのジョブのパフォーマンスが悪いかや、ジョブが起動するタイミングなど可視化することができ、クリティカルパスの表示やチューニングなどが行いやすくなります。
実際にこのグラフを見るとJDKのセットアップが他のジョブに比べ時間がかかっていることが確認できます。
ポイント2 キャッシュ化
1回目のコミット: Total duration 3m4s
2回目のコミット: Total duration 55s
1回目のコミットに比べ、2回目のコミットのジョブの時間が約2分も短いことがわかります。
今回、JDKのセットアップをキャッシュ化しました。
それにより、2回目のコミットでキャッシュを使用したことで、ジョブの実行時間を短縮することができました。
まとめ
・cacheを活用し、ジョブの実行時間を短縮させる
・Kesin11/actions-timelineを活用し、各ジョブを計測してチューニングができるような状態にする
最後に
執筆時点では、まだ私はGithubActionsを実務で構築したことはありませんが、ぜひ機会があればチャレンジしたいと思います。
今後、学びたい(やってみたい)ことは、AWSなどのサードパーティとうまく組み合わせて自動デプロイの方法についてもやってみたいです。
GithubActionsについてのカンファレンスではジョブの並列処理など他にも優良な技術の紹介がたくさんあったが、それはまた機会があれば行おうと思います。実際に実務を想定できるような具体例が発見できれば記事を書くかもしれません。
今回の記事に関して、フィードバックや改善点などがあればぜひコメントお待ちしております。
最後まで読んでくださりありがとうございました。
Discussion