はじめに
Sreake事業部でインターンをしている村山です。私は以前に、DORAチームの提案したFour Keysという指標の計測システムの調査・検証を行いました。
以前の検証では、GitHubとGitLab、及びモックデータによる検証を行っていました。以前はGitHub、GitLabそれぞれについての単体での検証を行いましたが、複数サービスを組み合わせたFour Keys計測に興味があり、今回はGitHubとCircleCIとを組み合わせたプロジェクトの場合、Four Keysはどのように計測されるのかを調査しました。
導入方法
Four Keys計測システムの基本的な導入手順については、以前の記事を参照してください。
以前の記事の、「5. webhookの追加」でGitHubもしくはGitLabに対してFour Keysプロジェクトへのwebhookが追加出来ていれば問題ありません。CircleCIへ対応させるための手順は以下のとおりです。
- CircleCIのwebhookの追加
- CircleCI用のパーサーのビルド
- Terraform variablesの設定
- CircleCIのworkflowの設定
0.Four Keys計測のSQL
始めに今回使用するdora-team/fourkeysのFour Keys計測システムについて概要を説明します。
Four Keys計測システムは、GitHub、GitLab、CircleCIといったサービスからコミットやデプロイなどのイベントを取得し、BigQueryのevents_rawテーブルに蓄積、そのevents_rawテーブルからFour Keysの各指標に必要なパラメータを取得・算出しています。以下の画像は、Four Keys計測システムの概要図です。

続いて、CircleCIでのデプロイをFour Keysの計測システムで取得するための条件を確認します。デプロイに関するテーブルのSQLは計測システムのリポジトリdora-team/fourkeysのqueries/deployments.sqlとなります。deployments.sqlの54~63行ではCircleCIのデプロイについて以下のように書かれています。
deploys_circleci AS (# CircleCI pipelines
      SELECT
      source,
      id AS deploy_id,
      time_created,
      JSON_EXTRACT_SCALAR(metadata, '$.pipeline.vcs.revision') AS main_commit,
      ARRAY<string>[] AS additional_commits
      FROM four_keys.events_raw
      WHERE (source = "circleci" AND event_type = "workflow-completed" AND JSON_EXTRACT_SCALAR(metadata, '$.workflow.name') LIKE "%deploy%" AND JSON_EXTRACT_SCALAR(metadata, '$.workflow.status') = "success")
    ),特に、WHERE句の部分からどのような条件であるかを確認することができます。
WHERE (source = "circleci" AND event_type = "workflow-completed" AND JSON_EXTRACT_SCALAR(metadata, '$.workflow.name') LIKE "%deploy%" AND JSON_EXTRACT_SCALAR(metadata, '$.workflow.status') = "success")WHERE句から、deploymentsに分類されるためには以下の4つを全て満たす必要があることがわかります。そのため、これらの条件を満たすことを念頭に置いて以降の設定を行っていく必要があります。
- ソースが”circleci”であること
- イベントのタイプが”workflow-completed”であること
- メタデータ中のワークフローの名前($.workflow.name)に”deploy”が含まれていること
- メタデータ中のワークフローのステータス($.workflow.status)が”success”であること
1.CircleCIのwebhookの追加
計測システムがCircleCIのデプロイイベントを取得できるよう、webhookを追加します。このwebhookの追加によってdeploymentsに分類されるための条件の1と2を満たすことができます。
CircleCIのwebhookの詳細については、CircleCIのドキュメントを参照してください。webhookの追加方法は以下の手順のとおりです。
1-1. Four Keysを計測したいプロジェクトの Project Settings > Webhooks > Add Webhookを選択します。
1-2. 各設定項目については以下のとおりです。
Webhook name
適当な名前を入力してください。今回は「Four Keys」としています
Receiver URL
Google CloudのFour KeysプロジェクトのPayload URLを入力します。以下のコマンドの出力結果を入力してください
$ gcloud run services list --project $PROJECT_ID | grep event-handler | awk '{print $4}'Secret token
Four KeysプロジェクトのSecretを入力します。以下のコマンドの出力結果を入力してください
$ gcloud secrets versions access 1 --secret=event-handler --project $PROJECT_IDCertificate verification
チェックしてください
Events – Workflow Completed
チェックしてください。計測システムがdeployを検知するために必要なEventです
Events – Job Completed
チェックの必要はありません
2.CircleCI用のパーサーのビルド
CircleCIからのwebhookを解析するためにパーサーのビルドを行います。このFour Keysの計測システムでは、webhookからのイベントをパースし、それをBigQueryのテーブルに追加します。また、Four Keysの計測にはデプロイのイベントの他、GitHubなどのプッシュやコミットのイベントが必要なため、GitHubのパーサーのビルドも同様に必要です。GitHubのパーサーをビルドしていない場合は以下のコマンドから、パーサーをビルドしてください。
$ gcloud builds submit bq-workers --config=bq-workers/parsers.cloudbuild.yaml --project $PROJECT_ID --substitutions=_SERVICE=github
CircleCI用のパーサを以下のコマンドからビルドします。
$ gcloud builds submit bq-workers --config=bq-workers/parsers.cloudbuild.yaml --project $PROJECT_ID --substitutions=_SERVICE=circleci
ビルドが成功すると、Cloud RunのサービスにCircleCIのパーサーが追加されます。

3.Terraform variablesの設定
CircleCIパーサー用のTerraform variablesを設定します。
$ cd terraform/example
terraform/example/terraform.tfvars
project_id = "{project_id}"
region = "us-central1"
bigquery_region = "US"
parsers = ["github", "circleci"]
variablesの設定が完了したら、Terraformを実行します。
$ terraform plan
$ terraform apply
実行すると以下の画像のように、Cloud RunにCircleCI用のパーサーが追加されます。

4.CircleCIのworkflowの設定
webhookを追加したプロジェクトにワークフローを設定します。プロジェクトで使用しているフレームワークやデプロイ先に合わせてワークフローを設定してください。今回は、例としてNode.jsのプロジェクトをGitHub Pagesにデプロイするためのワークフローを設定します。
4-1.tokenの設定
GitHub Pagesのデプロイにあたり、GitHubのアクセストークンの設定を行います。アクセストークンの基本的な生成方法については、GitHubのドキュメントを参考にしてください。
生成にあたり、Repository accessとPermissionsの項目については、以下のように設定してください。
- Repository access- Only select repositories- Four Keys計測対象のリポジトリを選択します
 
 
- Only select repositories
- Permissions- Repository permissions- Contents- Access: Read and writeを選択してください
 
 
- Contents
 
- Repository permissions
4-2. CircleCIの環境変数の設定
CircleCIのワークフローの実行のため、環境変数の設定を行います。設定する環境変数は、GitHubのtokenです。CircleCIのドキュメントを参考に環境変数を設定します。ここでは例として、環境変数のNameをGH_TOKENとし、Valueには先程生成したtokenを設定します。
4-3.configuration fileの設定
CircleCIでProjectの任意のBranchを選択し、Edit Configを選択します。config.ymlを以下のように設定します。デフォルトの状態では、deploymentsに分類されるための条件の3を満たすために、ワークフローの名前にはdeployという文字列を入れる必要があります。
jobではなく、ワークフローの名前にdeployが必要なことに注意してください。(deployments.sqlのWHERE句の部分を変更すれば任意の文字列にすることが可能です。)ここでは、ワークフローの名前をbuild-and-deployとし、Node.jsのプロジェクトのtestとbuild、deployをしています。
config.yml
version: 2.1
orbs:
  node: circleci/node@5
jobs:
  test:
    executor: node/default
    working_directory: ~/project/{project_name}
    steps:
      - checkout:
          path: ~/project
      - node/install-packages:
          pkg-manager: npm
      - run:
          name: Run tests
          command: npm test
  build:
    executor: node/default
    working_directory: ~/project/{project_name}
    steps:
      - checkout:
          path: ~/project
      - node/install-packages:
          pkg-manager: npm
      - run:
          command: npm run build
      - run:
          name: Create the ~/artifacts directory if it doesn't exist
          command: mkdir -p ~/artifacts
      - run:
          name: Copy artifacts
          command: cp -R build dist public .output .next .docusaurus ~/artifacts 2>/dev/null || true
      - store_artifacts:
          path: ~/artifacts
          destination: node-build
      - persist_to_workspace:
          root: ~/artifacts
          paths:
            - .
  deploy:
    docker:
      - image: cimg/base:stable
    steps:
      - attach_workspace:
          at: ~/artifacts
      - run:
          name: Deploy to GitHub Pages
          command: |
            git config --global user.email {user.email}
            git config --global user.name {user.name}
            echo "machine github.com login {github_username} password ${GH_TOKEN}" > ~/.netrc
            cd ~/artifacts
            git init
            git add .
            git commit -m "Automated deployment to GitHub Pages: ${CIRCLE_SHA1}" --allow-empty
            git push --force --quiet "https://${GH_TOKEN}@github.com/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}.git" master:gh-pages
workflows:
	build-and-deploy:
	    jobs:
	      - test
	      - build:
	          requires:
	            - test
	      - deploy:
	          requires:
	            - build5.設定の確認
以上の手順を踏んで、CircleCIのワークフローの設定が完了した場合、対象のリポジトリにプッシュなどを行うと、設定したワークフローが実行されcommitとdeployの結果がFour Keysのイベントとして登録されます。
BigQueryに対して、Google Cloud CLIやBigQueryのSQLワークスペースから以下のようなSQLを叩くことでdeploymentsとして登録されているかを確認することができます。
SELECT * FROM `four_keys.deployments` WHERE source="circleci";
以上のコマンドからは以下のようなレスポンスが期待されます。
{
  "source": "circleci",
  "deploy_id": "464ff6c7-18cb-3d4d-9fb3-b32b57917619",
  "time_created": "2023-07-20 06:57:41.586334 UTC",
  "main_commit": "ec548f3274c011ccbf63663323f2392b21c43b76",
  "changes": ["ec548f3274c011ccbf63663323f2392b21c43b76"]
}
ここで出力された結果が期待していた結果と異なる場合や、結果が出力されない場合は、CircleCIの設定したワークフローが失敗していないかを確認してください。
GitHub Actionsでのデプロイ
CircleCIの代替として、GitHub Actionsを用いることもできます。GitHub Actionsを使用する場合は、新たなパーサーのビルドやwebhookの追加は必要ありません。
参考までに、GitHub Actionsを用いてのデプロイとFour Keysの計測方法について紹介します。Four Keys計測対象のリポジトリの.github/workflows以下にワークフローファイルを設定します。
今回の検証と同様にGitHub Pagesにデプロイを行う例として以下のようなワークフローを設定します。この際に、ワークフローの名前にdeployの文字列を入れる必要はありません。
name: Deploy static content to Pages
on:
  push:
    branches: ["main"]
  workflow_dispatch:
permissions:
  contents: read
  pages: write
  id-token: write
concurrency:
  group: "pages"
  cancel-in-progress: false
jobs:
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Setup Pages
        uses: actions/configure-pages@v3
      - name: Upload artifact
        uses: actions/upload-pages-artifact@v1
        with:
          path: '.'
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v2
このようなワークフローがコミットなどで動作し、成功することで、deploymentsテーブルにこのデプロイが登録され、Four Keysの計測を行うことができます。
CircleCIのソフトウェアデリバリーに関する指標について
CircleCIでもDORAチームのFour Keysのようなソフトウェアデリバリーの指標が示されています。CircleCIではそれらの指標を4つのベンチマークとし、これらのベンチマークとチームのパフォーマンスについての調査を行っています。
4つのベンチマークについての詳細は、公式のドキュメントを参照してください。具体的な4つのベンチマークは以下のとおりです。
- 実行時間(Duration)- ワークフローの実行にかかる平均時間
 
- 平均復旧時間(Mean Time To Recovery)- ビルドの失敗から次のワークフロー実行の成功までにかかる平均時間
 
- スループット(Throughput)- 1日あたりのプロジェクトごとのワークフローの平均実行回数
 
- 成功率(Success Rate)- ワークフローの全実行数のうち、実行に成功したワークフローの割合
 
これらの4つのベンチマークは実行時間、平均復旧時間、スループット、成功率の順に重要であるとされています。ワークフローの実行にかかる時間の短縮は、その他の指標に良い影響をもたらし、結果として生産性の向上が見込まれます。
DORAチームのFour Keysとの違いについては、指標の計測対象が主な相違点であり、DORAチームの開発プロセス全体を対象としているのに対し、CircleCIの4 key metricsはワークフローを対象としています。対象は異なるものの、対象そのものにかかる時間や頻度、MTTR、成功率(障害率)など、指標自体はほぼ同様のものであると言えます。
これらの指標についてはCircleCIの Insights から確認することができます。
まとめ
今回はCircleCIを使用しているプロジェクトでのFour Keysの計測方法について調査・検証しました。CircleCIでのデプロイ検出するための手順は、GitHubやGitLabのプロジェクトの導入時と基本的には同様であることがわかりました。
ただ、GitHubとCircleCIという異なるサービスを連携させている都合上、GitHub Actionsを使用してデプロイまでGitHubで完結させた場合と比較して、少し複雑であり、ワークフローの名前など注意する点があることもわかりました。
私感
今回の調査・検証を通して感じたことは以下のとおりです。
- CircleCIを活用したFour Keysの計測は、Four Keysの計測システムの導入が出来ていれば導入時と同じような操作をするだけなので容易
- Four Keys計測システムのドキュメントの不足- GitHubの場合は、特別な設定をせずにGitHub Actionsのデプロイを取得可能
- SQLを確認しないとCircleCIのイベントをFour Keys計測に使用するための条件がわからない
- ワークフローの名前に、deployという文字列は含まれているほうが好ましいとは思うが、jobsの名前にのみ含まれている可能性も
 
- CircleCIの4つの指標- 4つの指標は基本的にはDORAチームのFour Keysと同様で、開発プロセスを軸にするかワークフローを軸にするかの違い
- ワークフローに特化された指標なため、DORAチームのFour Keysのような組織全体のパフォーマンスというよりは、より小さなチームや個人のパフォーマンスを測定するのに適していそう
 
サービスを組み合わせてFour Keysを計測したり、そのサービス内でパフォーマンスの計測をすることができたりと、パフォーマンス計測の基盤は様々なところで整備されて初めているのだと感じました。どの指標をどの程度活用するかは組織やチーム次第であるものの、選択肢が増えていくことは、組織の目的に合った指標を見つけられる可能性も高まるため非常に良いことだと感じました。
