CircleCI入門:基本から学ぶCI/CDパイプライン構築 ✨

クラウド / インフラ

はじめに 👋

ソフトウェア開発の世界では、「CI/CD」という言葉を耳にする機会が非常に増えました。CI/CDは、継続的インテグレーション (Continuous Integration)継続的デリバリー/デプロイメント (Continuous Delivery/Deployment) の略で、ソフトウェア開発のプロセスを自動化し、より速く、より頻繁に、そしてより信頼性の高いリリースを実現するためのプラクティスです。

このCI/CDを実現するためのツールは数多く存在しますが、その中でも特に人気が高く、広く利用されているのが「CircleCI」です。

この記事では、CI/CDやCircleCIが初めての方でも理解できるように、以下の内容を順序立てて丁寧に解説していきます。

  • CircleCIの基本的な概念 (パイプライン, ワークフロー, ジョブ, ステップなど)
  • CircleCIアカウントの作成とプロジェクトの連携
  • 設定ファイル .circleci/config.yml の基本的な書き方
  • 簡単なパイプラインの実行例
  • キャッシュや環境変数などの便利な機能

この記事を読み終える頃には、CircleCIの基本的な仕組みを理解し、ご自身のプロジェクトで簡単なCI/CDパイプラインを構築できるようになることを目指します。🚀

CircleCIの基本概念 📚

CircleCIを使いこなすためには、まずいくつかの重要な概念を理解しておく必要があります。

主要な概念

  1. パイプライン (Pipeline)

    パイプラインは、CircleCIにおける一連のプロセスの全体像を表します。通常、GitHubやBitbucketのリポジトリへのコードのpushなどをトリガーとして開始されます。1つのパイプラインは、1つ以上のワークフローで構成されます。

  2. ワークフロー (Workflow)

    ワークフローは、パイプライン内で実行されるジョブの実行順序や依存関係を定義するものです。例えば、「ビルドジョブが成功したら、テストジョブを実行し、テストジョブも成功したらデプロイジョブを実行する」といった流れを定義できます。ジョブを並列に実行したり、特定のブランチでのみ実行したりといった制御も可能です。これにより、複雑なプロセスも効率的に管理できます。

  3. ジョブ (Job)

    ジョブは、特定のタスクを実行する単位です。例えば、「コードのビルド」「単体テストの実行」「Dockerイメージの作成」「サーバーへのデプロイ」などがそれぞれジョブとして定義されます。各ジョブは、指定されたExecutor(実行環境)上で、一連のステップを実行します。

  4. ステップ (Step)

    ステップは、ジョブ内で実行される個々のコマンドやアクションです。シェルのコマンドを実行するrunステップ、ソースコードをチェックアウトするcheckoutステップ、キャッシュを保存・復元するsave_cache/restore_cacheステップなど、様々な種類のステップが用意されています。

  5. Executor (実行環境)

    Executorは、ジョブが実行される環境を指定します。CircleCIでは、主に以下のExecutorが利用可能です。

    • docker: 指定したDockerイメージ内でジョブを実行します。最も一般的に利用されます。
    • machine: Linux, Windows, macOS の仮想マシン上でジョブを実行します。Dockerが利用できない場合や、より多くのリソースが必要な場合に使用します。
    • macos: macOSアプリの開発など、macOS環境が必要な場合に使用します。

    プロジェクトの要件に合わせて適切なExecutorを選択することが重要です。

  6. オーブ (Orb) 💡

    オーブは、再利用可能な設定のパッケージです。よく使われるタスク(例: AWSへのデプロイ、Slackへの通知、特定のフレームワークのテスト設定)がオーブとして提供されており、config.ymlに数行追加するだけで簡単に利用できます。自分でオーブを作成して共有することも可能です。これにより、設定ファイルの記述量を削減し、メンテナンス性を向上させることができます。

これらの概念の関係性を図で示すと、パイプライン > ワークフロー > ジョブ > ステップ という階層構造になっているとイメージすると分かりやすいでしょう。(今回は図は省略します)

CircleCIを使ってみよう! 🚀

それでは、実際にCircleCIを使ってみましょう。ここでは、GitHubアカウントとの連携を例に進めます。

1. アカウント登録

まずはCircleCIのウェブサイトにアクセスし、アカウントを登録します。

  1. CircleCIのサインアップページにアクセスします。
  2. 「Sign Up with GitHub」または「Sign Up with Bitbucket」を選択します。(ここではGitHubを選択)
  3. GitHubアカウントでの認証を求められるので、許可します。
  4. 簡単なアンケートに答えると、CircleCIのダッシュボードが表示されます。

これでCircleCIのアカウント作成とGitHub連携は完了です。簡単ですね!😊

2. プロジェクトの追加

次に、CI/CDを導入したいGitHubリポジトリをCircleCIに追加します。

  1. CircleCIダッシュボードの左側メニューから「Projects」を選択します。
  2. 連携しているGitHubアカウントのリポジトリ一覧が表示されるので、CI/CDを設定したいリポジトリの右側にある「Set Up Project」ボタンをクリックします。
  3. 設定方法を選択する画面が表示されます。「Fastest」を選ぶと、CircleCIが基本的な設定ファイルを自動で作成してコミットしてくれますが、ここでは「Use existing config」または後述する手順で手動で設定ファイルを作成することをおすすめします。(学習のため)
  4. もし「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してみましょう。

  1. ローカルリポジトリで.circleci/config.ymlを作成・編集します。
  2. 変更をステージングします: git add .circleci/config.yml
  3. コミットします: git commit -m "Add initial CircleCI configuration"
  4. 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:
node: circleci/node@5.0.2
commands 再利用可能なカスタムステップシーケンスを定義します。 commands:
my-command:
steps:
- run: echo "My custom command"
parameters パイプライン、ジョブ、コマンド、Executorで利用可能なパラメータを定義します。 parameters:
greeting:
type: string
default: "Hello"
executors 再利用可能なカスタム実行環境を定義します。 executors:
my-executor:
docker:
- image: cimg/python:3.10
jobs 実行するジョブの詳細を定義します。各ジョブはExecutorとステップを持ちます。 jobs:
build:
docker: ...
steps: ...
workflows ジョブの実行順序、依存関係、実行トリガーなどを定義します。 workflows:
build-test-deploy:
jobs:
- build
- test: requires: [build]

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 installpip install でダウンロードされる依存パッケージなど、頻繁には変更されないが取得に時間がかかるものをキャッシュできます。restore_cachesave_cache ステップを適切に使うことで、ビルド時間を大幅に短縮できます。キャッシュキーに依存関係ファイルのチェックサム (例: {{ checksum "package-lock.json" }}) を含めるのが一般的です。

成果物 (Artifacts) 📦

ビルドによって生成されたファイル(実行ファイル、圧縮ファイル、ログ、コードカバレッジレポートなど)を保存する機能です。store_artifacts ステップで指定したファイルやディレクトリは、パイプライン完了後もCircleCIのUIからダウンロードしたり、API経由でアクセスしたりできます。デバッグやリリース配布に役立ちます。

テスト結果 (Test Results) 📊

JUnit XML形式などで出力されたテスト結果ファイルを store_test_results ステップで収集すると、CircleCIのUI上でテストの概要(成功数、失敗数、実行時間など)や、失敗したテストの詳細を確認できます。どのテストがなぜ失敗したのかを素早く特定するのに非常に便利です。

ローカルCLI (Local CLI) 💻

CircleCIにはコマンドラインインターフェース (CLI) ツールも提供されています。これを使うと、config.ymlの構文チェック (circleci config validate) や、ローカルマシン上でジョブの実行 (circleci local execute --job <job_name>) が可能です。設定ファイルをpushする前に問題を検出できるため、開発サイクルを速めることができます。

料金プラン 💰

CircleCIには、利用規模に応じた複数の料金プランがあります。

  • Freeプラン:
    • 小規模なプロジェクトや個人開発、学習目的に最適です。
    • 毎月一定量の無料クレジットが付与され、その範囲内でビルドを実行できます。(クレジットはExecutorのリソースクラスや実行時間に応じて消費されます)
    • 同時実行できるジョブ数に制限があります。
    • 基本的な機能はほぼ利用可能です。
  • Performanceプラン:
    • より多くのクレジット、高い同時実行数、高速なマシンタイプが利用できます。
    • チームでの開発や、ビルド頻度が高いプロジェクトに適しています。
    • SSHデバッグなどの高度な機能も利用しやすくなります。
  • Scaleプラン:
    • 大規模な組織向けのカスタムプランです。
    • さらに多くのリソース、専任サポートなどが提供されます。

多くのプロジェクトでは、まずFreeプランから始めて、必要に応じて有料プランに移行するのが良いでしょう。最新の料金体系や各プランの詳細は、公式サイトで確認してください。

CircleCI 料金プラン詳細

まとめ ✅

この記事では、CI/CDの基本からCircleCIの主要な概念、設定ファイルの書き方、具体的な使用例、そして便利な機能について解説しました。

CircleCIの主なメリット:
  • 簡単な導入: GitHub/Bitbucket連携と.circleci/config.ymlの作成で始められる。
  • 柔軟な設定: ワークフローによる複雑なパイプライン構築、多様なExecutorの選択が可能。
  • 豊富な機能: キャッシュ、成果物、テスト結果、SSHデバッグ、環境変数管理など。
  • Orbsによる拡張性: 再利用可能な設定パッケージで記述量を削減。
  • Freeプランの存在: 無料から始められるため、導入のハードルが低い。

CircleCIを導入することで、コード変更後のビルドやテスト、さらにはデプロイまでのプロセスを自動化し、開発チームはより価値の高い作業に集中できるようになります。信頼性の高いソフトウェアを迅速にリリースするために、CI/CDは現代の開発に不可欠なプラクティスであり、CircleCIはその強力なツールの一つです。

まずは簡単なプロジェクトでCircleCIを試してみて、その便利さを体験してみてください。慣れてきたら、Orbsの活用、より複雑なワークフローの構築、様々な環境へのデプロイ戦略など、さらに深く学んでいくことをお勧めします。Happy building! 🥳

コメント

タイトルとURLをコピーしました