🎉
【GitHub Actions】環境ごとのデプロイ順番を守りたい
はじめに
staging環境->production環境のように、複数の環境に対して、決まった順番でデプロイすることがよくあると思います。
ちなみに、現在私が携わっているプロジェクトだと、3つの環境ごとにブランチを分けていて、それぞれpushされたタイミングでデプロイを走らせています。
deploy.yml
on:
push:
branches:
- deploy/staging
- deploy/demo
- deploy/production
そして、以下のような順番でpushして、環境ごとにデプロイしています。
staging->demo->production
ところが、何も意識しないと、いきなりproductionにpushしてデプロイすることもできてしまいます。怖い。人間の注意力を信じてはいけないのです。そのような事態を防ぐ策はあるのでしょうか。
この記事では、Gitのコミットハッシュを比較することで、デプロイの順番を守らせる方法の一例をして挙げてみます。
どうするのか
以下が大まかなな流れになります。
-
現在のワークフローをトリガーしたブランチの情報を参照
-
前段階でデプロイしている必要がある環境のブランチ情報を参照
- 現在のワークフローがdemoならstaging、prductionならdemoのブランチ情報
-
上記ブランチそれぞれの最新のコミットハッシュを比較
- 等しい場合: 順番通り。以降のデプロイ処理を実行。
- 異なる場合: 順番が違う。ワークフローを中断。
実装
deploy.yml
on:
push:
branches:
- deploy/staging
- deploy/demo
- deploy/production
name: Deploy
jobs:
deploy-sample:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v2
# 現在のワークフローがデプロイ対象としている環境をenvにセット(後続のステップで参照)
- name: Set variables
id: variables
run: |
# github.refで、現在のワークフローの実行をトリガーしたブランチを参照できる
if [ "${{ github.ref }}" == "refs/heads/deploy/production" ]; then
env="prd"
elif [ "${{ github.ref }}" == "refs/heads/deploy/demo" ]; then
env="demo"
else
env="stg"
fi
echo "::set-output name=env::$env"
- name: Check commit hash
# stagingの時はこのステップは無視される
if: "steps.variables.outputs.env != 'stg'"
run: |
# 前段階でデプロイしている必要がある環境のブランチの最新のコミットハッシュをhash変数に
# -> demoの場合はstg、prdの場合はdemoの最新コミットハッシュ
if [ "${{ steps.variables.outputs.env }}" == "demo" ]; then
git fetch origin deploy/staging
hash=$(git rev-parse origin/deploy/staging)
elif [ "${{ steps.variables.outputs.env }}" == "prd" ]; then
git fetch origin deploy/demo
hash=$(git rev-parse origin/deploy/demo)
fi
# github.shaでトリガーしたブランチの最新コミットハッシュを参照
# それぞれの最新のコミットハッシュを比較。異なる場合は中断
if [ "$hash" != "${{ github.sha }}" ]; then
exit 1
fi
# 以降デプロイ処理...
終わりに
秋になってきましたね。金木犀の香りもそろそろ漂ってくるのではないでしょうか。
皆さんも、鼻をぷんぷんさせてみてはいかがでしょうか。
Discussion