🗣️

GithubActionsのちょっとした応用|cache × actions-timeline

2024/08/28に公開

はじめに

先日のGithubActionsについてのカンファレンスで学んだことを復習及びアウトプットしようと思い、今回このような記事を書きました。

引用

先に今回参考にさせていただいた記事を載せておきます。

引用サイト
・Build CI/CD Pipeline for Java Maven Using GitHub Actions
・actions-timeline

ソースコードはこちら
https://github.com/abe12hudekimo/java_maven_demo_project

目的と行うこと

目的

今回のゴール(目的)は以下の内容をインプットすることとします。
・cacheの活用方法
・Kesin11/actions-timelineの活用方法

行うこと

今回GithubActionsを解説するにあたってデモでJavaを扱い、以下の内容を行います。
Javaを知らない方でも理解できるような内容なのでぜひ見ていってください。
・mavenプロジェクトで作成したテストメソッドを用いた自動テスト
・jarファイルを生成し、エクスポート

実装例

プロジェクト構成は以下のとおりです。
Javaファイルは特に理解する必要はありません。さっと目を通す程度で問題ないです。
ここでは一番最後のmaven.yamlに注目してください。


フォルダ構成

作成したデモオブジェクト

Greeter.java
package hello;

public class Greeter {
  public String sayHello() {
    return "Hello world!";
  }

  public String sayAnything(String word) {
    return word + "が呼ばれた!";
  }
}

mainメソッドを含むクラス

HelloWorld.java
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());
  }
}

テストクラス

GreeterTest.java
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で実行するジョブについて

maven.yaml
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