CI/CD 環境: Buddy と GitHub Actions

CI/CD ツールの BuddyGitHub Actions を試験導入し、 評価してみました。

背景

このブログでは変更内容を GitHub のリポジトリに push すると、 Travis CI が変更を検知して、 次の処理を行うように設定してありました。

  1. 仮想マシンを立ち上げてリポジトリをチェックアウト
  2. 仮想マシンに hugo をインストール、hugo を実行して HTML ファイルを作成
  3. 生成されたファイルをホスティング先の Firebase にデプロイ

しかし先日から Travis CI の挙動がおかしく、 最終的に出力されたファイルから最新のコミット内容が漏れています。 手動で再実行させると問題なく動くので、 どこかで同期をとるのに失敗している模様。

原因が Travis CI と GitHub リポジトリのどちらにあるのか切り分けるために、 他の CI/CD 環境として Buddy と GitHub Actions を設定することに。

結論

Travis CI の設定の問題のようで、 他の CI/CD 環境では問題なく動きました。 今のところ Travis CI 固有の機能も使っていないので、 問題解決に時間を割くのではなく当面 Buddy を使うことにしました。

ただし Buddy は無料枠が渋めなので、 ファイルが増えたりして無料枠で動かなくなったら GitHub Actions に切り替えると思います(動作確認済み)。

製品比較

Buddy

利点

  • UI がよくできている。
  • 事前定義されている豊富なアクション。

欠点

  • 無料プランの制約が厳しめ。有料プランは月75USDからと、趣味で使うには高い。

設定方法

Buddy では個々の処理、 たとえば hugo を使ってサイトをビルドしたり、 ビルドした生成物を Firebase にデプロイする処理を「アクション」と呼び、 それを組み合わせて「パイプライン」を作成します。 GitHub リポジトリに対するイベントをトリガーとして、 作成したパイプランを実行します。

Buddy パイプライン設定

一般的な CI/CD ツールではテキストファイルでパイプラインの設定を行いますが、 Buddy は Web から対話的に行います。 各アクションの細かい設定、 たとえばインストールするアプリケーションのバージョンや実行時に引き渡すマンドライン引数などの設定も直感的。

Buddy パイプライン設定

たとえば上のスクリーンショットでは hugo コマンド実行時にコマンドライン引数 --cleanDestinationDir --minify を渡し、 サイト構築後に RSS ファイルを別名のファイルにコピーするよう設定してあります。

実行環境

アクションの実行には Docker を使用しており、 実行ファイルのパッケージや CI/CD 対象の Git リポジトリもキャッシュしているため、 実行に要する時間が短い。

たとえば hugo アクションは次の4ステップを踏みますが、 hugo パッケージ (hugo_*.deb) がキャッシュされている状況だと7秒程度で終わります。

  1. Linux の Docker コンテナイメージを取得して起動
  2. Linux コンテナ内の環境更新 (apt-get update など)
  3. hugo パッケージ取得、インストール
  4. hugo コマンドを実行してサイトを構築

Travis CI だと仮想マシンの割当・起動も含めると5分近くかかります。

料金プラン

無料プランはパイプライン実行回数が一ヶ月あたり120回まで、 ストレージ500MBと厳しめ。 有料プランは月75USDからなので、趣味で使うには高い。

もう少しライトなプランがほしいところ。

参考:Buddy Pricing & Features

GitHub Actions

利点

  • 安い。パブリックレポジトリであれば無料。
  • 有志によって提供されている豊富なアクション。
  • GitHub との密な統合。

欠点

  • アクションには公式なサポートがないケースが多い。
  • ジョブ間のファイルのやり取りにやや時間がかかる。

設定方法

公式ドキュメント: GitHub Actions 入門

GitHub リポジトリへのイベントをトリガーとして実行される一連の処理を「ワークフロー」と呼び、 テキストファイル (YAML) でワークフローを定義します。 ワークフローは並列に実行可能な「ジョブ」の集合、 各ジョブは逐次実行される複数の「ステップ」で構成されます。

  • ワークフロー
    • ジョブ1
      • ステップ1-1
      • ステップ1-2
    • ジョブ2
      • ステップ2-1

ステップにはシェルコマンドに加えて、 公開されている再利用可能な「アクション」を使うことができます。 たとえばファイルを Firebase にデプロイするには FirebaseExtended/action-hosting-deploy アクションを使うことで、 自分で一からスクリプトを書く代わりに、 すでに他人が作成して動作検証済みの処理を再利用できます(参考)。

ただし公式にサポートされているアクションはまだ少ない。 上の Firebase へのデプロイ処理を行うアクションも、 Google 社員が作っているものの非公式ツールという位置づけで、 保証もサポートもありません。

アクション公開に際してのレビュープロセスなども存在しないため、 悪意あるアクションが紛れ込む可能性もあります。

ざっとドキュメントを眺めただけですが、 GitHub の一機能として開発されているだけあり、 GitHub との統合は極めて密です。 特定ディレクトリに push された場合のみにアクションを実行したいといった細かい要望に答えられます。

実行環境

ジョブの実行には仮想マシンが使われます。 ステップの実行は、 単純なスクリプトコマンドであれば仮想マシン内で直接実行されますが、 複雑なアクションであれば Docker コンテナを利用することもできます。

実行速度に影響を与える点。

  1. GitHub リポジトリはキャッシュされないため、 ジョブごとに毎回 fetch と checkout が何もない状態から行われます。
  2. ジョブ間ではファイルが共有されないため、 サイトのビルドとデプロイを別ジョブに分けたい場合には、 明示的にファイルをアーティファクトとしてアップロード・ダウンロードする必要があります(参考: Storing workflow data as artifacts)。

このブログ程度だと単一ジョブでビルドからデプロイまで行うと1分程度、 ビルドとデプロイでジョブを分けると2分程度かかります。

料金プラン

GitHub のパブリックレポジトリであれば無料、 プライベートレポジトリでも月2000分まで無料と格安です。 有料プランが必要な場合でも、 月に4 USDのプランで制限がかなり緩和されます。

参考: GitHub: Choose the plan that’s right for you.