はじめに
GitHub Actions でデプロイパイプラインなどを構築する際に複数環境が対象となることは往々にしてあるかと思います。
例ですが、AWSアカウントにおいても環境やコストなど様々な理由でAWSアカウントごと分離して設計を行うように
ここではGitHub Actions でデプロイパイプラインなどを構築する際に1つのワークフローで管理する方法を検討します。
ワークフローの管理
環境毎の管理の方法
方法としては2パターンです。
- 1つのワークフローで複数環境を管理する
- 環境毎にワークフローを分けて管理する
1.
については環境毎に比べて共通の処理が纏められるので管理は楽になりますが、判定条件を加えることによって可読性は著しく低下します。
また書き方を間違えると思わぬ事故(開発にデプロイするつもりが本番に)につながることもあるかもしれません。
2.
については 1.
に比べて環境毎にワークフローが分離されるため、管理する対象は環境毎に増えるものの可読性を著しく低下させたり、書き方を間違えて事故に繋がったとしても影響範囲はその環境に限定されそうです。
それぞれにメリット、デメリットは他にもありますがこの記事では 1.
の方法を検討します。
ワークフローの方針検討
方針
- 1つのワークフローで複数環境を操作する
- ワークフロー実行には
push/tags
を利用する - 想定する環境は以下
- dev 開発環境
- stg ステージング環境
- prod 本番環境
タグの命名規則
{任意の文字列、日付など}.{環境名}.{役割や用途など}.{連番もしくはバージョン番号}
例)
20210813.dev.version.1
ワークフローの定義
早速完成版です
name: Get Version
on:
push:
tags:
- '[0-9]+.dev.version.[0-9]+'
- '[0-9]+.stg.version.[0-9]+'
- '[0-9]+.prod.version.[0-9]+'
jobs:
pre:
name: pre
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Load Environment
id: get_envs
run: |
echo ::set-output name=VERSION::${GITHUB_REF#refs/tags/}
echo ::set-output name=STAGE::$(echo ${GITHUB_REF#refs/tags/} | awk -F. '{print $2}')
- name: print
run: |
echo ${{ steps.get_envs.outputs.VERSION }}
echo ${{ steps.get_envs.outputs.STAGE }}
- name: Setup
id: setup_config
run: |
case "${{ steps.get_envs.outputs.STAGE }}" in
"dev" )
echo ::set-output name=PARAM1::dev
;;
"stg" )
echo ::set-output name=PARAM1::stg
;;
"prod" )
echo ::set-output name=PARAM1::prod
;;
esac
- run: |
echo ${{ steps.setup_config.outputs.PARAM1 }}
タグからステージを取得する
Load Environment
ステップではタグからステージを取得します。
ワークフローをトリガーしたブランチまたはタグ名は GITHUB_REF
から取得します。
refs/tags/{タグ名}
が格納されているため、Shell Parameter Expansion
で refs/tags/
を削除してタグ名のみを取得します。
ステージ名はタグ名から awk
コマンドで2つ目を切り出し、出力パラメータとして後続へ渡します。
ステージ毎の処理の分岐
例ですが、case文で処理分岐します。
ここではステージ毎に処理分岐をして出力パラメータに設定された値がステージ毎に動的に設定されているかを確認しています。
結果
ステージが取得できたので他にもステップに if
キーワードで制御して環境毎に実行するしないも制御しやすくなりました。