GitHub Actionsと仲良くなったよ

2023年04月05日 水曜日


【この記事を書いた人】
うちやま

ぬるぽよりにるぽ、ヘビや宝石やイルカよりホリネズミやカニやアザラシが好きです。クジラに乗っていたらとある船の航海長に出会い意気投合しました。その後、帆船と衝突し大変な目にあいました。ペンギンとは未だにわかりあえません。

「GitHub Actionsと仲良くなったよ」のイメージ

はじめまして

はじめまして、うちやまです。バックエンドのアプリケーション開発を主にしています。

今回はCI/CDでGitHub Actionsに移行したことについてざっくばらんにお話しようと思います。私を含めチームメンバーはGitHub Actionsを知ってるけどそこまで使ってないし知らない状態です。GitHub Actionsに怒られイライラし、最終的に仲良くなっていった流れを書いていこうと思います。GitHub Actionsの深い技術要素というより、とりあえず移行してみて動くようになったよということを書いていくので、難しい話はしない予定です (というより、できません)。

難しい話はしないと言いながらGitHub Actionsのコマンドとかについてはあまり書きません。

結局なに書くんだ!
GitHub Actionsに移行するにもそのままサクッとはいかなかったよってことと、社内事情でいろいろあったよってことを書いていこうかと思います。

社内事情とゴール

ゴールは今まで行っていたCI/CD周りをGitHub Actionsで行うことですっといってもよくわからないと思うので、説明していきます。

IIJではGitHub Enterprise (以下、GHEと書きます) をオンプレで立てています。GHEの運用チームがおり、バージョンアップなどの対応をしています。この運用チームはDrone CIもオンプレでたてて運用しており、GitHub ActionsがなかったころはDrone CIがCI/CDツールとして推奨されていました。GHEとDrone CIの連携は Drone CI側でボタンを押せば自動的に連携できるようになっていて、かなり使いやすいものでした。
GHEにGitHub Actionsがリリースされてから、運用チームでRunnerを用意してくれています。しかし、このRunnerは手軽に使うような形で作られているためリソースが少ないです。各サービスで専用に使うには物足りなく、サービスごとにRunnerを動かすためのホストを自前で用意する形になっています。

私たちのチームでもDrone CIを使っていましたが、こちらは無償版ということもあって機能が足りない面などがありました。GHEでGitHub Actionsが使えるようになってからはRunner用のホストを用意して移行しようといった動きになりました。

具体的にCI/CDで何をやっているのかというと、そんなに多くはありません。単体テストとlintチェック、Dockerイメージの作成とプッシュだけです。成功 or 失敗の通知処理がありますが、そこは一旦省きます。これらDrone CIで行っていたことをGitHub Actionsに完全移行することがゴールです。

GitHub Actionsについて社内で知見もあるので簡単にいけるだろうと思っていたのですが、そんなに簡単にいくはずもなく。

移行について

主に二つについて書いていこうと思います。

  1. バックエンドアプリのCI
    • バックエンドアプリはGoを使用しています
    • Goの単体テスト、lintチェックを行います
  2. フロントエンドアプリのリリース
    • JSをビルドし、ビルド成果物をもつDockerイメージを作成します
    • 上のイメージをプッシュします

バックエンドアプリのCI

単体テストとlintチェックしかしてませんが、いろいろと厄介でした。

まずは単体テストについて話します。

バックエンドアプリはDBを持っていて、単体テストでは直接DBとやりとりしています (DB周りでMockは使ってないんです)。
テスト用のデータは単体テストを始めるときに投入し、テストが終わったらまっさらにしています。投入と削除処理はGoのテストコードで実装されているので、GitHub Actionsの処理として書くのはユーザとテーブル作成です。しかし、複数のCIが同時に走ることも想定すると、単体テストごとにDBを作らないとデータの状態がおかしくなりこけてしまいます。

こういう場合、CI/CDツールではよくサービスコンテナを使います。専用のDockerコンテナを立ち上げてそのコンテナを利用しましょうってことです。GitHub Actionsではジョブ内に「services」という設定があり、サービスコンテナを作ることができます。
DBはサービスコンテナで立ち上げ、CIごとにDockerコンテナを立ち上げてます。

これで何とかなりそうかと思いきや、そうはいかず。
サービスコンテナと通信するにはホスト側にポートを公開する必要があります。単体テストごとにサービスコンテナが作られるので、公開するポートが動的に変わってしまいサービスコンテナとうまく通信できなくなります。そのため、バックエンドアプリもDockerコンテナで起動しDocker内で完結するようにし、ホスト側にポートを公開しなくてもいいようにします。

うちやま

2023年04月05日 水曜日

ぬるぽよりにるぽ、ヘビや宝石やイルカよりホリネズミやカニやアザラシが好きです。クジラに乗っていたらとある船の航海長に出会い意気投合しました。その後、帆船と衝突し大変な目にあいました。ペンギンとは未だにわかりあえません。

Related
関連記事