git worktreeを使ってCDKアプリを並列実行してみた

git worktreeを使ってCDKアプリを並列実行してみた

Clock Icon2025.02.25

こんにちは。たかやまです。

CDKアプリを開発している際に、検証用にCDKアプリを同時に複数作成したい場合はありませんか?

もちろんContextや.tsファイルなどで環境ファイルを用意している場合は、環境ファイルを参照することで環境ごとにCDKアプリを作成することができます。

https://dev.classmethod.jp/articles/aws-cdk-multi-environment-config/

今回は環境ファイルを用意しないケースで、CDKアプリを複数作成したい場合に、git worktreeが活用できそうでしたので、今回はgit worktreeを使ったCDKアプリの並列実行方法をご紹介します。

git worktree とは

git worktreeは、1つのリポジトリから複数の作業ディレクトリ(作業ツリー)を作成できる機能で、異なるブランチを別々のディレクトリで同時に作業することができます。

https://git-scm.com/docs/git-worktree

以下のようなケースで利用され、今回のCDKアプリの並列実行にも利用できます。

  • 機能開発中にプルリクエスト対応をしたい
  • 複数のブランチを同時にビルドしたい
  • ブランチの切り替えが頻繁で、その都度ビルドし直すのが面倒

やってみる

前提

前提として、スタックを複数作成した場合に 物理リソース名が重複しないような設計を想定しています。

作業ツリーの作成

今回はサンプルとして以下のようなブランチを用意します。

git branch
  env1
* main

git worktreeの基本的な使い方としては以下のようになります。

まず、 git worktree add で作業ツリーを作成します。

git worktree add path/to/directory branch-name
env1ブランチのworktreeを作成
git worktree add /Users/your.name/Desktop/work/sample-cdk-env1 env1

こちらのコマンドを実行することで、物理的に workディレクトリ配下に sample-cdk-env1 ディレクトリが作成され、その中に env1 ブランチの内容がコピーされます。

なお、作業ツリーを追加するときのポイントとして、もとのブランチと同じディレクトリに作成しないように注意してください。

同じディレクトリに作成した場合以下のようなディレクトリ構成になりmainブランチにトラッキングされてしまいます。

$ tree -L 1 --dirsfirst
 .
 ├── bin
 ├── lib
 ├── node_modules
+├── sample-cdk-env1 #worktreeで追加されたディレクトリ
 ├── test
 ├── README.md
 ├── cdk.json
 ├── jest.config.js
 ├── package-lock.json
 ├── package.json
 └── tsconfig.json
$
$ git status
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        sample-cdk-env1/

nothing added to commit but untracked files present (use "git add" to track)

作業ツリーが作成されたら、あとは作成されたディレクトリに移動して、通常通りCDKアプリを実行するだけです。

作業ツリーでコミットした内容は、mainブランチでも確認可能です。
検証した設定変更に問題がなければ、通常のブランチと同様にマージできます。

CleanShot 2025-02-24 at 17.20.01@2x-1.png

作業ツリーの削除

作成したworktreeの一覧を表示するには git worktree list を実行します。

git worktree list

今回の環境でworktreeは以下のような作業ツリー構成になります。

$ git worktree list
/Users/your.name/Desktop/work/sample-cdk       a5914f1 [main]
/Users/your.name/Desktop/work/sample-cdk-env1  05da1c9 [env1]

作業ツリーを削除するには git worktree remove を実行します。
先ほど表示された作業ツリーenv1のディレクトリパスを指定することで、作業ツリーを削除することができます。

git worktree remove /Users/your.name/Desktop/work/sample-cdk-env1

こちらを実行することで、物理的なディレクトリとgit上での作業ツリーを削除することができます。

付録 自動化スクリプト

以下のようなシェルスクリプトを使用することで、複数環境の並列デプロイを自動化できます。

#!/bin/bash

# 設定
BASE_DIR="/Users/your.name/Desktop/work"
APP_NAME="sample-cdk"

# 引数解析用の変数
BRANCH_NAMES=()
CREATE_WORKTREE=false
DEPLOY=false
DELETE_WORKTREE=false

# 引数解析
usage() {
  echo "使用方法: $0 [オプション]"
  echo "オプション:"
  echo "  -b, --branch <branch>    ブランチ名(複数指定可)"
  echo "  --create-worktree       ワークツリーを作成"
  echo "  --cdk-deploy            CDKデプロイを実行"
  echo "  --delete-worktree       ワークツリーを削除"
  echo ""
  echo "例: $0 -b feature/branch1 -b feature/branch2 --create-worktree --cdk-deploy"
  exit 1
}

while [[ $# -gt 0 ]]; do
  case $1 in
    -b|--branch)
      BRANCH_NAMES+=("$2")
      shift
      ;;
    --create-worktree)
      CREATE_WORKTREE=true
      ;;
    --cdk-deploy)
      DEPLOY=true
      ;;
    --delete-worktree)
      DELETE_WORKTREE=true
      ;;
    -h|--help)
      usage
      ;;
    *)
      echo "Unknown parameter: $1"
      usage
      ;;
  esac
  shift
done

# ワークツリーの作成またはデプロイの場合、ブランチ名が必要
if [ ${#BRANCH_NAMES[@]} -eq 0 ] && ( $CREATE_WORKTREE || $DEPLOY ); then
  echo "Error: ブランチ名が指定されていません。-bまたは--branchでブランチ名を指定してください。"
  exit 1
fi

# ワークツリー作成
if $CREATE_WORKTREE; then
  for branch in "${BRANCH_NAMES[@]}"; do
    WORK_DIR="${BASE_DIR}/${APP_NAME}-${branch}"
    if [ ! -d "$WORK_DIR" ]; then
      echo "Creating worktree from branch $branch..."
      git worktree add "$WORK_DIR" "$branch"
    else
      echo "Worktree already exists: $WORK_DIR"
    fi
  done
fi

# CDKデプロイ
if $DEPLOY; then
  for branch in "${BRANCH_NAMES[@]}"; do
    (
      WORK_DIR="${BASE_DIR}/${APP_NAME}-${branch}"
      if [ -d "$WORK_DIR" ]; then
        echo "Deploying branch $branch..."
        cd "$WORK_DIR" || exit 1
        npm ci
        npx cdk deploy --require-approval never
      else
        echo "Worktree does not exist: $WORK_DIR. Skipping deployment."
      fi
    ) &
  done

  wait
  echo "All deployments have finished."
fi

# ワークツリー削除
if $DELETE_WORKTREE; then
  for branch in "${BRANCH_NAMES[@]}"; do
    WORK_DIR="${BASE_DIR}/${APP_NAME}-${branch}"
    if [ -d "$WORK_DIR" ]; then
      echo "Removing worktree for branch $branch..."
      git worktree remove "$WORK_DIR" --force
    else
      echo "Worktree not found: $WORK_DIR"
    fi
  done
fi

使い方は以下の通りです。

事前に作業ツリーを作成する先となる BASE_DIR と、CDKアプリのプロジェクト名 APP_NAME を設定します。

# 設定
BASE_DIR="/Users/your.name/Desktop/work"
APP_NAME="sample-cdk"

あとは以下のようにオプションを指定して実行します。

  • 作業ツリーを作成する場合
./script.sh -b env1 -b env2 --create-worktree
  • CDKデプロイを実行する場合
./script.sh -b env1 -b env2 --cdk-deploy
  • 作業ツリーを削除する場合
./script.sh -b env1 -b env2 --delete-worktree

最後に

今回はgit worktreeを使ってCDKアプリを並列実行を紹介しました。

ご紹介したworktreeの手法を使うことで、ブランチごとにCDKアプリを並列実行することができます。

複数のブランチでCDKアプリを並列実行したい場合にはぜひworktreeをご活用してみてください。

この記事が誰かのお役に立てれば幸いです。

以上、たかやま(@nyan_kotaroo)でした。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.