はじめに
ソフトウェア開発の世界では、「CI/CD」という言葉を耳にする機会が非常に増えました。CI/CDは、継続的インテグレーション (Continuous Integration) と 継続的デリバリー/デプロイメント (Continuous Delivery/Deployment) の略で、ソフトウェア開発のプロセスを自動化し、より速く、より頻繁に、そしてより信頼性の高いリリースを実現するためのプラクティスです。
このCI/CDを実現するためのツールは数多く存在しますが、その中でも特に人気が高く、広く利用されているのが「CircleCI」です。
CircleCIは、クラウドベースのCI/CDサービスです。GitHubやBitbucketといったバージョン管理システムと連携し、コードの変更を検知して、ビルド、テスト、デプロイといった一連のプロセスを自動で実行してくれます。設定が比較的簡単で、多くのプログラミング言語やフレームワークに対応しているのが特徴です。
この記事では、CI/CDやCircleCIが初めての方でも理解できるように、以下の内容を順序立てて丁寧に解説していきます。
- CircleCIの基本的な概念 (パイプライン, ワークフロー, ジョブ, ステップなど)
- CircleCIアカウントの作成とプロジェクトの連携
- 設定ファイル
.circleci/config.yml
の基本的な書き方 - 簡単なパイプラインの実行例
- キャッシュや環境変数などの便利な機能
この記事を読み終える頃には、CircleCIの基本的な仕組みを理解し、ご自身のプロジェクトで簡単なCI/CDパイプラインを構築できるようになることを目指します。
CircleCIの基本概念
CircleCIを使いこなすためには、まずいくつかの重要な概念を理解しておく必要があります。
これらの概念の関係性を図で示すと、パイプライン > ワークフロー > ジョブ > ステップ という階層構造になっているとイメージすると分かりやすいでしょう。(今回は図は省略します)
CircleCIを使ってみよう!
それでは、実際にCircleCIを使ってみましょう。ここでは、GitHubアカウントとの連携を例に進めます。
1. アカウント登録
まずはCircleCIのウェブサイトにアクセスし、アカウントを登録します。
- CircleCIのサインアップページにアクセスします。
- 「Sign Up with GitHub」または「Sign Up with Bitbucket」を選択します。(ここではGitHubを選択)
- GitHubアカウントでの認証を求められるので、許可します。
- 簡単なアンケートに答えると、CircleCIのダッシュボードが表示されます。
これでCircleCIのアカウント作成とGitHub連携は完了です。簡単ですね!
2. プロジェクトの追加
次に、CI/CDを導入したいGitHubリポジトリをCircleCIに追加します。
- CircleCIダッシュボードの左側メニューから「Projects」を選択します。
- 連携しているGitHubアカウントのリポジトリ一覧が表示されるので、CI/CDを設定したいリポジトリの右側にある「Set Up Project」ボタンをクリックします。
- 設定方法を選択する画面が表示されます。「Fastest」を選ぶと、CircleCIが基本的な設定ファイルを自動で作成してコミットしてくれますが、ここでは「Use existing config」または後述する手順で手動で設定ファイルを作成することをおすすめします。(学習のため)
- もし「Use existing config」を選んだ場合、CircleCIはリポジトリの
.circleci/config.yml
に使われる設定ファイルを配置するように指示します。
3. 設定ファイル (.circleci/config.yml) の作成
CircleCIの動作は、リポジトリのルートディレクトリ直下にある .circleci
という隠しディレクトリ内の config.yml
というファイルで定義します。このファイルがCI/CDパイプラインの設計図となります。
まずは、非常にシンプルなconfig.yml
を作成してみましょう。リポジトリのルートに.circleci
ディレクトリを作成し、その中にconfig.yml
という名前で以下の内容を記述します。
# .circleci/config.yml
version: 2.1 # CircleCIのバージョンを指定 (2.1が推奨)
# jobsセクション: 実行するジョブを定義
jobs: say-hello: # ジョブ名 (任意) docker: # ExecutorとしてDockerを使用 - image: cimg/base:stable # ベースとなるDockerイメージを指定 (CircleCI提供のイメージ) steps: # ジョブ内で実行するステップ - run: echo "Hello, CircleCI! " # echoコマンドを実行
# workflowsセクション: ジョブの実行順序を定義
workflows: main: # ワークフロー名 (任意) jobs: - say-hello # 実行するジョブを指定
この設定ファイルは何をするものでしょうか?
version: 2.1
: CircleCIの設定ファイルフォーマットのバージョンを指定しています。最新の機能を利用するために2.1
が推奨されています。jobs
: 実行される可能性のあるジョブのリストを定義します。say-hello
:jobs
の中に定義されたジョブの名前です。docker: - image: cimg/base:stable
: このジョブがcimg/base:stable
というDockerイメージ上で実行されることを指定しています。これはCircleCIが提供する汎用のLinux環境イメージです。steps
: ジョブ内で実行される具体的な手順のリストです。run: echo "Hello, CircleCI! "
: シェルでecho
コマンドを実行し、”Hello, CircleCI! ”という文字列を出力するステップです。workflows
: どのジョブをどの順序で実行するかを定義します。main
: ワークフローの名前です。jobs: - say-hello
:main
ワークフローでは、say-hello
というジョブを実行することを指定しています。
このファイルをリポジトリの.circleci/config.yml
として追加し、GitHubにpush
してみましょう。
- ローカルリポジトリで
.circleci/config.yml
を作成・編集します。 - 変更をステージングします:
git add .circleci/config.yml
- コミットします:
git commit -m "Add initial CircleCI configuration"
- GitHubにプッシュします:
git push origin <branch-name>
プッシュ後、CircleCIのダッシュボードで該当プロジェクトを見てみると、自動的にパイプラインが開始され、say-hello
ジョブが実行されているのが確認できるはずです。ジョブが成功すると緑色のチェックマーク が表示されます。ジョブの詳細を開くと、”Hello, CircleCI! ” が出力されているログを確認できます。
これで、最初のCircleCIパイプラインが実行できました!
.circleci/config.yml の書き方
基本的な流れがわかったところで、config.yml
の主要な要素についてもう少し詳しく見ていきましょう。
主要なキー
キー | 説明 | 例 |
---|---|---|
version | 設定ファイルのバージョン。2.1 が推奨。 | version: 2.1 |
setup | パイプラインパラメータやパスフィルタリングなど、パイプライン全体の設定を行う。(2.1 で導入) | setup: true (動的設定で使用) |
orbs | 利用するOrbを定義します。<namespace>/<orb-name>@<version> の形式で指定。 | orbs: |
commands | 再利用可能なカスタムステップシーケンスを定義します。 | commands: |
parameters | パイプライン、ジョブ、コマンド、Executorで利用可能なパラメータを定義します。 | parameters: |
executors | 再利用可能なカスタム実行環境を定義します。 | executors: |
jobs | 実行するジョブの詳細を定義します。各ジョブはExecutorとステップを持ちます。 | jobs: |
workflows | ジョブの実行順序、依存関係、実行トリガーなどを定義します。 | workflows: |
jobs
の詳細
jobs
セクションでは、個々のジョブを定義します。
jobs: build: # ジョブ名 docker: # Executorの指定 (docker, machine, macos) - image: cimg/node:18.17 # 使用するDockerイメージ auth: # プライベートリポジトリの場合の認証情報 (オプション) username: mydockerhub-user password: $DOCKERHUB_PASSWORD # 環境変数を使用するのが一般的 environment: # コンテナ内で設定する環境変数 (オプション) TZ: "Asia/Tokyo" resource_class: medium # ジョブに割り当てるリソース (small, medium, large, etc.) parallelism: 4 # ジョブの並列実行数 (テスト分割などに利用) working_directory: ~/project # ジョブを実行するディレクトリ (デフォルト: ~/project) environment: # ジョブレベルで設定する環境変数 MY_JOB_VAR: "job_value" steps: # 実行するステップのリスト - checkout # コードをワーキングディレクトリにチェックアウト - run: npm install # コマンド実行 - save_cache: # キャッシュの保存 key: deps-{{ checksum "package-lock.json" }} # キャッシュキー paths: # キャッシュ対象のパス - node_modules - run: name: Run Tests # ステップに名前をつける (UIで見やすい) command: npm test - store_artifacts: # 成果物の保存 path: coverage # 保存するパス destination: coverage-report # 保存先の名前 (オプション) - store_test_results: # テスト結果の保存 (JUnit XML形式など) path: test-results
よく使われるステップには以下のようなものがあります。
checkout
: バージョン管理システムからソースコードをチェックアウトします。run
: シェルコマンドを実行します。name
でステップに名前を付けたり、command
で複数行のスクリプトを記述したりできます。restore_cache
: 以前にsave_cache
で保存したキャッシュを復元します。keys
で複数のキーを指定し、一致するものがあれば復元します。save_cache
: 指定したパスのファイルやディレクトリをキャッシュします。key
にはキャッシュの一意性を保つための文字列を指定します(例: 依存関係ファイルのチェックサム)。store_artifacts
: ビルド成果物(バイナリ、ログファイル、カバレッジレポートなど)を保存します。パイプライン完了後もCircleCIのUIからダウンロードできます。store_test_results
: テストランナーが出力したテスト結果ファイル(通常はXML形式)を収集します。CircleCIのUIでテストの成功/失敗を詳細に確認できます。persist_to_workspace
: ワークフロー内の後続ジョブで利用するために、ファイルやディレクトリを一時的なワークスペースに保存します。attach_workspace
:persist_to_workspace
で保存されたワークスペースを、現在のジョブの指定したパスにアタッチします。
workflows
の詳細
workflows
セクションでは、ジョブ間の連携を定義します。
workflows: version: 2 # ワークフローのバージョン (必須) build_and_test: # ワークフロー名 jobs: - build # buildジョブを実行 - test: # testジョブを実行 requires: # このジョブが依存するジョブを指定 - build # buildジョブが成功したらtestジョブを実行 filters: # ジョブを実行する条件を指定 (オプション) branches: only: # このブランチでのみ実行 - main - develop ignore: # このブランチでは実行しない - feature/.* tags: only: /v.*/ # 'v'で始まるタグでのみ実行 ignore: /.*/ # タグでは実行しない (上記onlyがある場合は不要なことが多い) - approve_deploy: # 手動承認ステップ type: approval # 承認タイプを指定 requires: - test # testジョブが成功したら承認待ちへ filters: branches: only: main # mainブランチのみ - deploy: # deployジョブを実行 requires: - approve_deploy # 手動承認されたら実行 context: # 事前定義された環境変数セットを使用 - aws-credentials
workflows
で重要な設定項目:
requires
: ジョブの依存関係を定義します。指定したジョブがすべて成功した場合に、現在のジョブが開始されます。これを指定しないジョブはワークフロー開始と同時に(並列に)実行されます。filters
: 特定のブランチやタグでのみジョブを実行/除外するためのフィルタを設定します。正規表現も使用可能です。context
: CircleCIのOrganization設定で事前に定義した環境変数のグループ(コンテキスト)を指定します。APIキーなどの機密情報を安全にジョブに渡すために使用します。type: approval
: 手動承認ステップを定義します。このステップに到達するとパイプラインは一時停止し、CircleCIのUI上で承認ボタンが押されるまで後続のジョブは実行されません。本番環境へのデプロイ前などに挟むことが多いです。
具体的な設定例
ここでは、もう少し実践的な例として、PythonプロジェクトとNode.jsプロジェクトの設定ファイル例を見てみましょう。
Python プロジェクトの例 (pytestを使用)
version: 2.1
orbs: python: circleci/python@2.0.3 # Python用のOrbを使用
jobs: build-and-test: executor: python/default # Orbで定義されたExecutorを使用 (Python環境がプリインストールされている) steps: - checkout - python/install-packages: # Orbのコマンドで依存関係をインストール pkg-manager: pip # pip-dependency-file: requirements.txt # requirements.txtを使う場合 (デフォルト) # cache-key: "pip-deps-{{ checksum \"requirements.txt\" }}" # カスタムキャッシュキー - run: name: Run Tests with Pytest command: pytest # pytestコマンドを実行
workflows: main: jobs: - build-and-test
この例では、circleci/python
Orbを利用しています。
orbs: python: circleci/python@2.0.3
でOrbをインポートします。executor: python/default
で、Orbが提供するPython環境がセットアップ済みのExecutorを指定しています。python/install-packages
はOrbが提供するコマンドで、pip install
とキャッシュの管理(restore_cache
,save_cache
)を自動で行ってくれます。- 最後に
pytest
コマンドを実行してテストを実施します。
Orbを使うことで、config.yml
が非常にシンプルになることがわかりますね。
Node.js プロジェクトの例 (npmを使用)
version: 2.1
orbs: node: circleci/node@5.0.2 # Node.js用のOrbを使用
jobs: build-and-test: executor: node/default # Orbで定義されたExecutorを使用 (Node.js環境がプリインストールされている) steps: - checkout - node/install-packages: # Orbのコマンドで依存関係をインストール (npm ci または yarn install) pkg-manager: npm # npmを使用 (yarnの場合は yarn) # cache-key: "npm-deps-{{ checksum \"package-lock.json\" }}" # カスタムキャッシュキー - run: name: Run Linter command: npm run lint - run: name: Run Tests command: npm test - run: name: Build application command: npm run build # ビルド成果物を保存する場合 # - store_artifacts: # path: dist
workflows: main: jobs: - build-and-test
こちらも同様に circleci/node
Orb を利用しています。
node/install-packages
コマンドがnpm ci
(またはyarn install
) とキャッシュの管理を行います。package-lock.json
(またはyarn.lock
) が存在する場合は、それに基づいて正確な依存関係をインストールするため、ビルドの再現性が高まります。- Lintチェック (
npm run lint
)、テスト実行 (npm test
)、ビルド (npm run build
) を順番に実行しています。
これらの例のように、多くの一般的なプロジェクトでは、公式のOrbを利用することで、設定の手間を大幅に削減できます。
便利な機能
CircleCIには、CI/CDパイプラインをより効率的かつ安全に運用するための便利な機能が多数搭載されています。
環境変数 (Environment Variables)
APIキーやパスワードなどの機密情報をconfig.yml
に直接書き込むのはセキュリティ上問題があります。CircleCIでは、プロジェクト設定やコンテキスト (Contexts) で環境変数を安全に管理できます。設定された環境変数は、ジョブ実行時に自動的に利用可能になります。
例: $MY_API_KEY
のように $
を付けて参照します。
キャッシュ (Caching)
npm install
や pip install
でダウンロードされる依存パッケージなど、頻繁には変更されないが取得に時間がかかるものをキャッシュできます。restore_cache
と save_cache
ステップを適切に使うことで、ビルド時間を大幅に短縮できます。キャッシュキーに依存関係ファイルのチェックサム (例: {{ checksum "package-lock.json" }}
) を含めるのが一般的です。
成果物 (Artifacts)
ビルドによって生成されたファイル(実行ファイル、圧縮ファイル、ログ、コードカバレッジレポートなど)を保存する機能です。store_artifacts
ステップで指定したファイルやディレクトリは、パイプライン完了後もCircleCIのUIからダウンロードしたり、API経由でアクセスしたりできます。デバッグやリリース配布に役立ちます。
テスト結果 (Test Results)
JUnit XML形式などで出力されたテスト結果ファイルを store_test_results
ステップで収集すると、CircleCIのUI上でテストの概要(成功数、失敗数、実行時間など)や、失敗したテストの詳細を確認できます。どのテストがなぜ失敗したのかを素早く特定するのに非常に便利です。
SSHデバッグ
ジョブが失敗した場合、そのジョブの実行環境にSSHで接続してデバッグすることができます。CircleCIのUIから「Rerun Job with SSH」を選択すると、SSH接続情報が表示され、ターミナルから接続してファイルを確認したり、コマンドを試したりできます。原因究明に非常に役立ちます。
ローカルCLI (Local CLI)
CircleCIにはコマンドラインインターフェース (CLI) ツールも提供されています。これを使うと、config.yml
の構文チェック (circleci config validate
) や、ローカルマシン上でジョブの実行 (circleci local execute --job <job_name>
) が可能です。設定ファイルをpush
する前に問題を検出できるため、開発サイクルを速めることができます。
料金プラン
CircleCIには、利用規模に応じた複数の料金プランがあります。
- Freeプラン:
- 小規模なプロジェクトや個人開発、学習目的に最適です。
- 毎月一定量の無料クレジットが付与され、その範囲内でビルドを実行できます。(クレジットはExecutorのリソースクラスや実行時間に応じて消費されます)
- 同時実行できるジョブ数に制限があります。
- 基本的な機能はほぼ利用可能です。
- Performanceプラン:
- より多くのクレジット、高い同時実行数、高速なマシンタイプが利用できます。
- チームでの開発や、ビルド頻度が高いプロジェクトに適しています。
- SSHデバッグなどの高度な機能も利用しやすくなります。
- Scaleプラン:
- 大規模な組織向けのカスタムプランです。
- さらに多くのリソース、専任サポートなどが提供されます。
多くのプロジェクトでは、まずFreeプランから始めて、必要に応じて有料プランに移行するのが良いでしょう。最新の料金体系や各プランの詳細は、公式サイトで確認してください。
まとめ
この記事では、CI/CDの基本からCircleCIの主要な概念、設定ファイルの書き方、具体的な使用例、そして便利な機能について解説しました。
- 簡単な導入: GitHub/Bitbucket連携と
.circleci/config.yml
の作成で始められる。 - 柔軟な設定: ワークフローによる複雑なパイプライン構築、多様なExecutorの選択が可能。
- 豊富な機能: キャッシュ、成果物、テスト結果、SSHデバッグ、環境変数管理など。
- Orbsによる拡張性: 再利用可能な設定パッケージで記述量を削減。
- Freeプランの存在: 無料から始められるため、導入のハードルが低い。
CircleCIを導入することで、コード変更後のビルドやテスト、さらにはデプロイまでのプロセスを自動化し、開発チームはより価値の高い作業に集中できるようになります。信頼性の高いソフトウェアを迅速にリリースするために、CI/CDは現代の開発に不可欠なプラクティスであり、CircleCIはその強力なツールの一つです。
まずは簡単なプロジェクトでCircleCIを試してみて、その便利さを体験してみてください。慣れてきたら、Orbsの活用、より複雑なワークフローの構築、様々な環境へのデプロイ戦略など、さらに深く学んでいくことをお勧めします。Happy building!