🐙
GitHub Actionsでワークフローは使いまわしたいけど環境別に変数切り替えしたい場合
要するに、staging環境とproduction環境でやることは一緒だけど環境変数だけ切り替えて利用したい ということを実現したい。
変数受け渡し周りで意外とハマったのでメモしておく。
ブランチ・デプロイ戦略
Gitlab Flow がわかりやすいのでこれベースで説明していく。
以下のデプロイフローを想定。
- 環境毎のブランチにpushされると、GitHub Actionsでその環境にデプロイする
- developブランチにpushすると、develop環境にデプロイ
- stagingブランチにpushすると、staging環境にデプロイ
- productionブランチにpushすると、production環境にデプロイ
ファイル構成設計
以下のような感じで置くイメージ
.github/
workflows/
deploy.yaml > 共通で利用できる実際に実行するワークフローyaml
deploy_develop.yaml > develop環境の変数を定義し、共通ワークフローを実行するyaml
deploy_staging.yaml > staging環境の変数を定義し、共通ワークフローを実行するyaml
deploy_production.yaml > production環境の変数を定義し、共通ワークフローを実行するyaml
共通利用したいワークフローyamlをincludeする
利用側でuses
に以下のフォーマットで指定すればOK。
deploy_develop.yaml
name: Deploy to develop
on:
push:
branches:
- develop
jobs:
deploy:
# format: [organization]/[repo_name]/.github/workflows/[common workflow file]@[branch]
uses: toritsuyo/iikanji-app/.github/workflows/deploy.yaml@develop
共通利用したいワークフローに変数を渡す
ここで若干ハマった。
env / secrets / with などでinclude先に渡そうにもスコープの関係で
Unrecognized named-value: xxxs
的なエラーが発生してしまい四苦八苦…
今回、結果的には secrets
に直接渡すことで要件を満たすことが出来た 🎉
環境別のyamlでこんな定義をしておいて…
deploy_develop.yaml
name: Deploy to develop
on:
push:
branches:
- develop
jobs:
deploy:
uses: toritsuyo/iikanji-app/.github/workflows/deploy.yaml@develop
secrets:
himitsu: ${{ secrets.himitsu_dev }}
project_id: 'iikanji-app-dev'
共通ワークフロー側ではこんな感じでsecrets経由で変数を受け渡し出来る。
deploy.yaml
name: Deploy workflow
on:
workflow_call:
secrets:
himitsu:
description: 秘密のトークン
required: true
project_id:
description: プロジェクトID
required: true
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Setup Cloud SDK
uses: google-github-actions/setup-gcloud@v0.2.0
with:
project_id: ${{ secrets.project_id }}
...
補足: 共通利用したいワークフローで条件分岐したい場合
ifを使えば簡単に条件分岐できる。
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: checkout repo
uses: actions/checkout@v1
- name: step 1
if: github.ref == 'refs/heads/develop' || github.event.pull_request.base.ref == 'develop'
run: echo "Hello develop"
...
余談
Github Actions Environments を利用するともう少し良い感じに環境変数を管理することができそうです。
ちなみにGithub Actions Environmentsをざっくり説明すると、以下のようなことが出来ます。
- 環境別に保護ルールとシークレットを持つ環境を設定できます
- 必須のレビュー担当者を割り当て
- 環境毎のシークレット設定
- 環境にデプロイ出来るブランチを制限
ただ、プライベートリポジトリだと Github Enterprise Cloud契約でないとEnvironmentsが利用できなかったため、今回は利用しませんでした。
最後に
割とあるあるな要件を実現してみました。もし「こうすればもっと簡単にできるよ!」という方法があればご教示いただけると助かります!
Discussion