やりたいこと
- system毎にディレクトリが分かれているterraformがあり(下記イメージ)、パイプラインで更新があったプロジェクトのディレクトリを判別してterraformを実行したい。
- 具体的には、git diffを使って差分があるディレクトリを抽出し、それをJOSNの配列にしたい。
- 差分は、mainブランチとの差分で、1コミット分の差分抽出でOK
- シェルで実現したい
.
├── README.md
├── modules
│ ├── network
│ ├── resource
│ └── security
└── projects
├── system-a
│ ├── backend.tf
│ ├── data.tf
│ ├── local.tf
│ ├── main.tf
│ ├── provider.tf
│ └── terraform.tf
├── system-b
└── system-c
やりかた
mainへのpull requestの場合のmainコミットとの差分抽出
TARGET_BRANCH=main
git fetch --depth 1 origin ${TARGET_BRANCH} > /dev/null 2>&1
git diff ${TARGET_BRANCH} HEAD --name-only -- 'projects/' | \
sed 's:\(^projects/[^/]*\)*.*$:\1:' | \
sort | uniq | \
jq -scR 'split("\n") | .[:-1]';
push時の一つ前のコミットとの差分抽出
TARGET_BRANCH=main
git fetch --depth 2 origin ${TARGET_BRANCH} > /dev/null 2>&1
git diff HEAD^ HEAD --name-only -- 'projects/' | \
sed 's:\(^projects/[^/]*\)*.*$:\1:' | \
sort | uniq | \
jq -scR 'split("\n") | .[:-1]';
実行例
TARGET_BRANCH=main
git fetch --depth 1 origin ${TARGET_BRANCH} > /dev/null 2>&1
git diff ${TARGET_BRANCH} HEAD --name-only -- 'projects/' | \
sed 's:\(^projects/[^/]*\)*.*$:\1:' | \
sort | uniq | \
jq -scR 'split("\n") | .[:-1]';
["projects/system-a","projects/system-b","projects/system-c"]
解説
TARGET_BRANCH=main
git fetch --depth 1 origin ${TARGET_BRANCH} > /dev/null 2>&1
git diff ${TARGET_BRANCH} HEAD --name-only -- 'projects/'
projects/system-a/backend.tf
projects/system-a/data.tf
projects/system-a/local.tf
projects/system-a/main.tf
projects/system-a/provider.tf
projects/system-b/Makefile
projects/system-b/backend.tf
projects/system-c/dummy
sed 's:\(^projects/[^/]*\)*.*$:\1:' |
sed
でprojects直下のフォルダまでのパスまでだけ抽出しています。
sed
の書き方は、こちらを参照ください
/projects/xxxxx
のパスまで絞り込めますが、この段階では同じディレクトリが重複した状態になります。
projects/system-a
projects/system-a
projects/system-a
projects/system-a
projects/system-a
projects/system-b
projects/system-b
projects/system-c
/sort | uniq
/
uniq
コマンドで重複している行を削除します。uniq
の前提としてソートされている必要があるため、あらかじめsort
コマンドで行をソートします。
- ここまでの実行結果
projects/system-a
projects/system-b
projects/system-c
jq -scR 'split("\n") | .[:-1]'