Slide 1

Slide 1 text

Java で作る カスタム GitHub Actions 2022-06-19 (Sun) Tetsuya Morimoto

Slide 2

Slide 2 text

2 Kazamori LLC © 2022 ● 森本 哲也 (もりもと てつや) ● 神戸市在住 ●   カザモリ合同会社 ○ 2019年12月に設立 (いま第4期目) ○ フルリモートワークで他社の開発のお手伝いをしている ● 課題管理 (課題管理システム) に関心がある ● 言語歴は Python → Java → Go をそれぞれ5年ほどの実務経験 ● プログラミングや OSS 文化が好き 自己紹介

Slide 3

Slide 3 text

3 Kazamori LLC © 2022 目次 GitHub Actions とカスタムアクション 01. Docker container action によるカスタムアクション 02. Java アプリケーションと Docker イメージのビルド 04. カスタムアクションの開発、テストやデバッグのコツ 05. まとめ 06. Java の CLI アプリケーションと Docker container action の境界 03.

Slide 4

Slide 4 text

4 GitHub Actions と カスタムアクション

Slide 5

Slide 5 text

5 Kazamori LLC © 2022 GitHub プラットフォーム上でソフトウェア開発のワークフロー自動化などを行うための機能 ● 一般的な用途として CI/CD を実現するためのツールと理解しても概ね間違ってない 使い始めやすい理由がたくさんある ● 多くの開発者が GitHub リポジトリを利用している ● GitHub プラットフォームの様々なイベントをトリガーにできる ● 料金も安い (About billing for GitHub Actions から引用) ○ public リポジトリの利用は無料 ○ private リポジトリではプロダクトごとに無料枠 ■ GitHub Free : ストレージ 500MB、2,000時間まで無料 ■ GitHub Team: ストレージ 2GB、3,000時間まで無料 ■ … GitHub Actions とは

Slide 6

Slide 6 text

6 Kazamori LLC © 2022 処理の単位として3段階ある ● ワークフロー (ファイル単位) ○ ジョブ (ホスト単位) ■ ステップ (スクリプト単位) ステップが処理を記述する最小の単位になる ステップ単位で処理を実行する外部モジュールをカスタムアクションと呼ぶ 最もよく使われているカスタムアクションに checkout がある GitHub Actions のワークフローと実行単位 ワークフローは YAML で定義 steps: - uses: actions/checkout@v3 with: ref: main

Slide 7

Slide 7 text

7 Kazamori LLC © 2022 現時点では3つの種別がある ● Docker container action ← 本稿の話題 ○ Docker コンテナーでカスタムアクションを実装 ○ あまり使われていないかも?マイナー? ● JavaScript action ○ JavaScript でカスタムアクションを実装する ○ GitHub 社の公式アクションの多くは JavaScript で実装されているようにみえる ■ サンプルコードも多く、ライブラリも提供されている ● Composite actions ○ 複数ステップからなるカスタムアクションを実装する ○ 簡単なものならシェルスクリプトで実装できる ○ 複数のカスタムアクションを組み合わせることもできる カスタムアクションの種別

Slide 8

Slide 8 text

8 Kazamori LLC © 2022 Versions Maven Plugin を使った依存ライブラリの自動更新のための Composite actions を作った ● HoshinoResort/hr-library-auto-update ● maven コマンドを実行するシェルスクリプトのみで実装 実際の運用では1週間に1回ワークフローをスケジュール実行している ● 依存ライブラリのバージョンチェック処理は時間がかかる ● private リポジトリで運用する場合、 頻繁に実行すると課金の無料枠を浪費してしまう (余談) Composite actions のサンプル OSS なので よかったら 使ってください

Slide 9

Slide 9 text

9 Docker container action によるカスタムアクション

Slide 10

Slide 10 text

10 Kazamori LLC © 2022 ヌーラボ社の Backlog というタスク管理ツールがある 開発のお手伝い先で Backlog を利用しているが、イシューと GitHub の情報を連携する機能がない ● Pull Request を作ったときにリンク情報をイシューのカスタムフィールドに追記したい ● main ブランチにマージしたときにコミット情報をイシューのコメントに追記したい この2つの機能を実現するためにカスタムアクションを作成した ● kazamori/backlog-github-integration-action (余談) Java で実装した理由 ● ヌーラボ社が公式提供しているライブラリが Java のみだった ○ nulab/backlog4j Backlog-GitHub integration action 構想: 1ヶ月 実装: 2日

Slide 11

Slide 11 text

11 Kazamori LLC © 2022 実際に開発してみた個人的な所感から ● 自分の 好きな言語 で実装できる ● 実行時に docker pull & docker run で実行される ● GitHub プラットフォーム上のインフラですべて構築できる Docker container action の特徴 Java で 開発したい!

Slide 12

Slide 12 text

12 Kazamori LLC © 2022 Docker container action の振る舞い すべて GitHub インフラ

Slide 13

Slide 13 text

13 Java の CLI アプリケーションと Docker container action の境界

Slide 14

Slide 14 text

14 Kazamori LLC © 2022 Backlog-GitHub integration action は CLI アプリケーションとして実装 ● 単体で実行可能 ○ gradle run でも実行可能 ○ java -jar でも実行可能 ○ docker run でも実行可能 ● 複数のイベントに対応可能 ○ サブコマンドがイベントに対応 ○ 要件に応じて拡張しやすい ● GitHub プラットフォームに依存しない ○ 環境変数ではなく CLI パラメーター ○ デバッグや検証の大半をローカルで行う CLI アプリケーションと設計の狙い テストや デバッグ が容易

Slide 15

Slide 15 text

15 Kazamori LLC © 2022 ターミナルからコマンドラインで実行できると安心する ● IDE とか難しくて使いこなせないので、ターミナルとコマンドで操作できると嬉しい ● (私の場合) コードは IDE で書くが、ターミナルで実行する ● ターミナルのシェルで動くならどこでも動かせるはず? ○ ローカルで実行できる ○ Docker コンテナーで実行できる ○ GitHub Actions で実行できる ● 実行コンテキストや環境設定をなるべく減らしたい 単体で実行可能 GitHub Actions から実行しない 用途でも使える

Slide 16

Slide 16 text

16 Kazamori LLC © 2022 GitHub Actions は GitHub のイベントをトリガーに実行される ● CLI のサブコマンドがイベントに対応 ● イベントに対する要件に応じて拡張しやすい ○ pull_request イベント ○ push イベント ● 複数イベントを同じカスタムアクションで扱える ○ Backlog のカスタムアクションは他にもあるが、 pull_request イベントと push イベントの両方に 対応するカスタムアクションはない (はず) ○ 複数のカスタムアクションを使いたい理由はない 複数のイベントに対応可能 GitHub Actions で 使えるイベント一覧

Slide 17

Slide 17 text

17 Kazamori LLC © 2022 GitHub Actions で使うことを前提としているが、仕様はアプリケーションで決めたい ● CLI パラメーターで明示的に渡さなくても 環境変数を経由してアプリケーション内で読み込むことも可能ではある ● 環境変数に依存してしまうと、テストやデバッグにおいて 必ず GitHub Actions から呼び出さないと検証できない ● CLI アプリケーションが GitHub Actions 専用になってしまう GitHub プラットフォームに依存しない デフォルトの 環境変数一覧

Slide 18

Slide 18 text

18 Java アプリケーションと Docker イメージのビルド

Slide 19

Slide 19 text

19 Kazamori LLC © 2022 Java アプリケーション向けに Docker デーモンを使わずに 最適化された Docker/OCI イメージをビルドするためのツール ● GoogleContainerTools/jib ● maven や gradle プラグインから利用できる 目的 ● 高速: マルチステージビルドを使ってビルドを最適化して高速 ● 再現性: 同じコンテンツから同じイメージを生成 ● デーモン要らず: イメージのビルド環境構築を maven/gradle のみで構築         依存関係の管理コストが低い Jib とは

Slide 20

Slide 20 text

20 Kazamori LLC © 2022 Jib Gradle プラグイン jib { from { image = 'eclipse-temurin:17-jre-alpine' platforms { platform { architecture = 'amd64' os = 'linux' } } } to { image = 'ghcr.io/kazamori/backlog-github-integration-action' tags = ['latest'] } container { jvmFlags = [ "--add-opens", "java.base/sun.net.www.protocol.https=ALL-UNNAMED", "--add-opens", "java.base/java.net=ALL-UNNAMED" ] labels = [ 'org.opencontainers.image.description': "GitHub custom action integrates with Nulab's backlog", 'org.opencontainers.image.licenses': 'Apache-2.0', 'org.opencontainers.image.source': 'https://github.com/kazamori/backlog-github-integration-action', 'org.opencontainers.image.title': 'backlog-github-integration-action', 'org.opencontainers.image.url': 'https://github.com/kazamori/backlog-github-integration-action/pkgs/container/backlog-github-integration-action' ] format = 'OCI' } } jib の設定例

Slide 21

Slide 21 text

21 Kazamori LLC © 2022 JVM のビルドイメージは何を使えばいいのか? Backlog-GitHub integration action は Eclipse Temurin の Docker イメージを使っている ● Eclipse Foundation の Adoptium プロジェクトがビルドした JVM を利用 ● 17-jre-alpine のイメージサイズ: 47.52 MiB 信頼できるコミュニティの Docker イメージを使うメリット ● 脆弱性対応の保守への安心感 ○ OpenJDK Vulnerability Advisory: 2022/04/19 ○ April 2022 Release Status per Platform, Version & Binary Type · Issue #140 Adoptium プロジェクトと Docker イメージ

Slide 22

Slide 22 text

22 カスタムアクションの開発、 テストやデバッグのコツ

Slide 23

Slide 23 text

23 Kazamori LLC © 2022 すぐ使えて便利なテクニック Contexts - GitHub Docs GitHub Context の dump steps: - name: dump github context run: | echo "$GITHUB_CONTEXT" env: GITHUB_CONTEXT: ${{ toJson(github) }}

Slide 24

Slide 24 text

24 Kazamori LLC © 2022 Expressions - GitHub Docs ${{ と }} で囲まれた情報を式として評価できる ● 算術演算や論理演算 ● if 文の条件式 ○ ワークフローの制御に便利 ● 環境変数の設定 ○ カスタムアクションの戻り値を後続ステップで参照 ● 組み込み関数 ○ 一通りみておくと自前で実装しなくて済むかも? GitHub Actions の Expressions ${{ }}

Slide 25

Slide 25 text

25 Kazamori LLC © 2022 複雑な文字列操作をすると、いまどのコンテキストかを把握するのが困難 なるべくシンプルに文字列を扱うのがプラクティスと言える 複数のコンテキストがワークフローファイルに記述される ● yaml 設定の文字列 ● GitHub Actions の expressions ● シェル上の文字列 ワークフローにおける複数のコンテキスト steps: - name: dump github context run: | echo "$GITHUB_CONTEXT" env: GITHUB_CONTEXT: ${{ toJson(github) }} GitHub Actions のオブジェクト GitHub Actions の expression シェル上の文字列 JSON 文字列の エスケープを やると混乱する

Slide 26

Slide 26 text

26 まとめ

Slide 27

Slide 27 text

27 Kazamori LLC © 2022 Java でカスタムアクションを実装するために必要な知識やコツについて説明した ● Docker container action なら Java で実装できる ● GitHub イベントごとに機能実装できると拡張性が高い ○ 設計例の1つとして CLI アプリケーションを紹介 ● 逆説的ではあるが、GitHub Actions に依存しないアプリケーションとして実装する ○ テストやデバッグで GitHub Actions を実行するのは労力を要する ● GitHub Actions の Expressions を覚えておこう ○ ワークフロー制御や文字列操作を簡単にできる可能性 まとめ

Slide 28

Slide 28 text

28 Kazamori LLC © 2022 GitHub 社のドキュメントや GitHub Actions に関するブログ記事など ● GitHub Actions Documentation ● Creating actions - GitHub Docs ● Supercharging GitHub Actions with Job Summaries ● GitHub Actions: Input types for manual workflows カザモリ社の Backlog-GitHub integration action の紹介記事 ● Backlog GitHub integration action ● Commits integrate with Backlog issue その他、開発中に参考にしたブログ記事など ● GitHub Actions入門 ── ワークフローの基本的な構造からOIDCによる外部サービス認証まで ● GitHub Actions で学ぶシェル芸 ● JavaのDockerイメージ何選ぶ? | フューチャー技術ブログ リファレンス