Nexgen Software Solution Company

株式会社トレンドソリューションズ
TEL:050-3524-3317

shellでのGitLab API呼び出し

詳細

開発チームから以下の要望がありました。

  • 毎日定時起動
  • テスト環境に最新のアプリをデプロイしたい
  • 前回のデプロイから変更があった場合のみデプロイを実施
  • デプロイ完了後、ネーミングルールに従ってtagを打つ

要件を満たすために以下の対応を実施しました。

GitLab CI/CDのスケジュールにdaily処理として登録し、daily処理の中では以下のようなロジックを実装。

  • 直近のcommit idを取得
  • 最新のcommit idと比較し、値が違うなら(前回tagを打ってからcommitがあった)、デプロイを実施し新しいtagを打つ
直近のcommit id取得でpredefined variablesのCI_COMMIT_BEFORE_SHAを使おうとしていましたが、公式サイト記載の通り取得した値がALL0の場合があります。そのため、GitLab APIを利用することにしました。
※参考:https://docs.gitlab.com/ee/ci/variables/predefined_variables.html

また、commit idの取得と比較処理を外だしして、以下のようにshellを作成し、jobのscripから実行するようにしました。

#!bin/bash

rm -f ./commitsid.txt

# 1ページ100件取得する場合の最大ページ数を取得
TOTAL_PAGES=`curl -I "https://gitlab.com/api/v4/projects/<project id>/repository/tags?access_token=<your token>&per_page=100" | grep "x\-total\-pages" | tr -d "x\-total\-pages: " | tr -d "\r"`
echo $TOTAL_PAGES[@]

# 最大ページ数をループし、すべての明細を取得する
# jqで絞り込み条件を指定し、条件に当てはまるコミットIDだけcommitsid.txtに保存(条件の部分は仕様に応じて修正してください)
for i in `seq 1 $TOTAL_PAGES`
  do    curl --request GET "https://gitlab.com/api/v4/projects/<project id>/repository/tags?access_token=<your token>&per_page=100&page=$i" | jq -r '.[] | select(.name | test("^[0-9]{8}_[0-9]{1,}$")) | [.target] ' | tr -d '"' >> ./commitsid.txt
  done

# tags APIのレスポンスの並び順はデフォルトでupdateの降順になっているため、直近のコミットIDは1件目となる
PRE_COMMIT_SHA=`head -n 2 ./commitsid.txt | tail -n 1`
if [ $CI_COMMIT_SHA = $PRE_COMMIT_SHA ]; then
  # 前回のデプロイから変更ない
  echo "match"
else
  # デプロイ実行し、現在のcommitにtagを打つ(略)
  echo "unmatch"
fi 

簡単ではありますが、以上になります。