概要
PhoenixアプリケーションをCI/CDする方法を学んだので、記事としてまとめます。
本記事では、PhoenixアプリケーションCI/CDのうちCIの実装方法を解説します。
今回は、基本的なCIの構築にとどめます。
また、今回は別の記事で紹介したGCPの構成のデプロイを見据えて、データベース(Cloud SQL)は使用せず、簡単なCIを実装する形で進めます。
また記事中の内容は下記のリポジトリで公開しています
以下、簡単な用語解説を行います。
Github Actionsとは
GitHub Actionsは、リポジトリのイベント(pushやpull request)をトリガーにして、
テストやデプロイなどの処理を自動で実行できるCI/CDツールです。
CIとは
CIとは、継続的インテグレーション(Continuous Integration)の略です。
またCIは、コードの変更が既存のコードと正しく統合されることを保証するための自動化プロセスを指します。
具体的には、開発者がコードを変更した際に、統一性を保ち、安全に取り込めるようにする仕組みです。
そのために、CIでは次の処理を自動で行います。
-
コードの品質チェック
- フォーマットや静的解析を行い、コードのスタイルや記述の統一性を確認
-
コードのテスト
- 変更による不具合がないかを検証し、期待通り動作することを確認
CIを導入することで、開発のスピードとコードの正確性を向上させることができます。
環境
本記事では、以下の環境で検証を行いました。
- OS: macOS 15.3.1
- Elixir: 1.18.2 (OTP 27)
- Erlang: 27.2.2
手順
PhoenixアプリケーションのCI/CDを構築するために、GitHub Actionsのワークフローテンプレートを利用し、カスタマイズします。
ワークフローを作成する流れは以下の通りです。
リポジトリの作成
リポジトリを作成し、次のコマンドでPhoenixプロジェクトを作成して、リポジトリにpushしてください
mix phx.new tutorial_github_actions --no-ecto
また、今後の作業で使用するElixirのイメージを確認しやすくするため、Dockerfileを生成しておきます。
mix phx.gen.release --docker
さらに、CIでコードの静的解析を行うために、Credoを依存に追加してください。
GitHub Actionsのワークフローテンプレートを取得
PhoenixのCIのワークフローを作成するために、Elixirのワークフローテンプレートを利用します。
リポジトリの「Actions」タブから、次の手順でワークフローを作成してください。
- 「Actions」タブを開く
- テンプレート一覧から「Elixir」を選択し、「Configure」ボタンを押す
- ファイル名を
ci.yaml
に設定し、内容を変更せずに「Commit changes」を押す
この時点では、GitHub Actionsがエラーを検出しますが、後ほど修正するため問題ありません。
コミット後、以下のディレクトリに ci.yaml
が生成されます。
% tree .github
.github
└── workflows
└── ci.yaml
次の修正作業へ進む前に、ローカルリポジトリを最新の状態に更新してください。
生成されたワークフローのon
設定により、mainブランチにpushまたはpull requestがあったときに自動で実行されます。
テンプレートの修正
Elixirのワークフローテンプレートは、そのままではPhoenixアプリケーションのCIを実行できません。
そのため、次の修正を行います。
- Elixirの公式コンテナイメージを指定
- 不要なElixirのセットアップを削除
- Phoenixの依存関係とHexをインストール
- フォーマットのチェックを追加
- Credoのチェックを追加
- 厳密なコードチェックを追加
まず、生成された ci.yaml
は以下のようになっています。
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
name: Elixir CI
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
permissions:
contents: read
jobs:
build:
name: Build and test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Elixir
uses: erlef/setup-beam@61e01a43a562a89bfc54c7f9a378ff67b03e4a21 # v1.16.0
with:
elixir-version: '1.15.2' # [Required] Define the Elixir version
otp-version: '26.0' # [Required] Define the Erlang/OTP version
- name: Restore dependencies cache
uses: actions/cache@v3
with:
path: deps
key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }}
restore-keys: ${{ runner.os }}-mix-
- name: Install dependencies
run: mix deps.get
- name: Run tests
run: mix test
Elixirの公式コンテナイメージを指定
GitHub Actionsのワークフローで、実行環境のElixirバージョンを統一するため、
container: image:
を追加し、Elixirの公式コンテナイメージ を指定します。
# 略
runs-on: ubuntu-latest
# 追加
container:
image: hexpm/elixir:1.18.2-erlang-27.2.2-debian-bullseye-20250203-slim
# 略
指定するElixirのイメージ名は、生成したDockerfileから取得できます
ARG ELIXIR_VERSION=1.18.2
ARG OTP_VERSION=27.2.2
ARG DEBIAN_VERSION=bullseye-20250203-slim
ARG BUILDER_IMAGE="hexpm/elixir:${ELIXIR_VERSION}-erlang-${OTP_VERSION}-debian-${DEBIAN_VERSION}"
不要なElixirのセットアップを削除
先ほど、Elixirの公式コンテナイメージを指定しました。
そのため、ワークフロー内でElixirのセットアップを行う必要がなくなります。
次のステップを削除してください。
- - name: Set up Elixir
- uses: erlef/setup-beam@61e01a43a562a89bfc54c7f9a378ff67b03e4a21 # v1.16.0
- with:
- elixir-version: '1.15.2' # [Required] Define the Elixir version
- otp-version: '26.0' # [Required] Define the Erlang/OTP version
Phoenixの依存関係とHexをインストール
Elixirの公式コンテナイメージには、Phoenixの実行に必要なパッケージやHexが含まれていません。
そのため、次のステップを追加し、必要なツールをインストールします。
- name: Install Dependency Packages
run: |
apt-get update -y && apt-get install -y build-essential inotify-tools git
- name: Setup Elixir Tools
run: |
mix local.rebar --force
mix local.hex --force
mix deps.get
フォーマットのチェックを追加
CIの要件には、コードのフォーマットが最適化されていることも含まれます。
そのため、フォーマットチェックを追加し、コードがmix format
によってフォーマット済みの状態になっているかを検証します。
以下のステップを追加してフォーマットチェックを追加してください。
- name: Check Code Format
run: mix format --check-formatted
Credoのチェックを追加
CI においてコードの潜在的な問題を検出するために、Credoを使用した静的解析を追加します。
以下のステップを追加してCredoによるチェックを追加してください。
- name: Credo Checks
run: |
mix credo
厳密なコードチェックを追加
デフォルトのワークフローでは、以下のように mix test
を実行しています。
- name: Run tests
run: mix test
しかし、CIの要件として、不具合を早期に洗い出すためのチェックが求められます。
そのため、以下のように修正し、コンパイル時およびテスト実行時の警告をエラーとして扱うようにします。
- name: Run tests with warnings as errors
run: |
mix deps.compile
mix compile --warnings-as-errors
mix test --warnings-as-errors
最終的なワークフロー
今回の修正を反映した、最終的なGitHub Actionsワークフローは以下の通りです。
name: Elixir CI
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
permissions:
contents: read
jobs:
build:
name: Build and test
runs-on: ubuntu-latest
container:
image: hexpm/elixir:1.18.2-erlang-27.2.2-debian-bullseye-20250203-slim
steps:
- uses: actions/checkout@v4
- name: Restore dependencies cache
uses: actions/cache@v3
with:
path: deps
key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }}
restore-keys: ${{ runner.os }}-mix-
- name: Install Dependency Packages
run: |
apt-get update -y && apt-get install -y build-essential inotify-tools git
- name: Setup Elixir Tools
run: |
mix local.rebar --force
mix local.hex --force
mix deps.get
- name: Check Code Format
run: mix format --check-formatted
- name: Credo Checks
run: |
mix credo
- name: Run tests with warnings as errors
run: |
mix deps.compile
mix compile --warnings-as-errors
mix test --warnings-as-errors
まとめ
本記事では、PhoenixアプリケーションにCIを導入する方法を解説しました。
要点を簡単に振り返ると、次のようなことを行いました。
- ワークフローのテンプレートを取得して設定を修正
- CI環境の実行方法を変更
- 必要なパッケージを追加
- コードのフォーマットとテストを自動化の追加
これにより、mainブランチへのpushやpull request時に、自動でコードの整合性をチェックできる環境が整いました。
今回はmainブランチのCIのみを扱いましたが、.github/workflows/*.yaml
に複数のワークフローを作成することで、ブランチごとに異なる自動化処理を設定 できます。
この仕組みを利用して、次回は CDの実装 を行います