🕹️
[Github Actions] Release tagでバージョン管理に連動させた環境設定ごとのデプロイ
tldr
-
main
などへのmerge/commit単位では自動デプロイせず、まとまった時に手動でデプロイ処理が走るようにしたい - 個別のリリース用ブランチは作りたくない
- "まとまった時"はリリースタグを利用して、
v1.x.x
などの形式で管理する -
secrets
などはEnterpriseアカウントなので Github Environmentを使って管理したい -
secrets
は各環境ごとに異なる。なので各環境ごとにworkflow runの承認できるメンバーを変えたい - Actionsに出てくるworkflow runsのタイトルは同じだと分かりにくいので動的にReleaseバージョンなどに合わせたい
- 公式以外の出どころが分からないAppsはactionsで使いたくない
手順
- レポジトリのSettings > Tags > Protected tagsでNew rule >
v*
で保存 - レポジトリのSettings > Environments > New environment
a. Nameを使いたいブランチ名にする (main
,staging
)
b. (以下Configure画面で)Deployment protection rules > Required reviewersにチェックしてから承認メンバーを追加
c.Allow administrators to bypass configured protection rules
のチェックを外す
d.Save protection rules
で保存
e. Deployment branchesでAll branches
をSelected branches
に切り替える
f. Add deployment branch ruleでブランチ名をEnvironment Nameと同じブランチ名を入力する
g. 先人に従いEnvironment secrets > Add secretで任意のキーGCLOUD_SERVICE_KEY
などを設定する。 ただの変数で良いものは Environment variables > Add variableでGOOGLE_APPLICATION_CREDENTIALS
などを設定 - レポジトリに以下2ファイルを作って各ブランチに反映
.github/workflows/deploy-trigger.yml
name: AutomatedReleaseTagCheck
run-name: Checking ${{ github.event.release.name }}
on:
release:
types: [prereleased, released]
permissions: write-all
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Fetch all tags
run: git fetch --tags
- name: Get second latest tag
id: get-second-latest-tag
run: echo ::set-output name=tag::$(git describe --abbrev=0 --tags `git rev-list --tags --skip=1 --max-count=1`)
- name: Compare tags
run: |
SECOND_LATEST_TAG=${{ steps.get-second-latest-tag.outputs.tag }}
NEW_TAG=${{ github.event.release.tag_name }}
if [[ "$(printf '%s\n' "$NEW_TAG" "$SECOND_LATEST_TAG" | sort -V | head -n1)" == "$NEW_TAG" ]]; then
echo "New tag ($NEW_TAG) is not newer than the second latest tag ($SECOND_LATEST_TAG)"
exit 1
fi
- name: Validate tag
id: validate
run: |
TAG_NAME=${{ github.event.release.tag_name }}
echo "Tag name is $TAG_NAME"
if [[ $TAG_NAME != v* ]]; then
echo "Tag does not start with 'v'"
exit 1
fi
# https://github.blog/changelog/2022-09-08-github-actions-use-github_token-with-workflow_dispatch-and-repository_dispatch/
- name: Trigger deploy workflow
uses: actions/github-script@v6
with:
script: |
const branch = "${{ github.event.release.target_commitish }}";
const workflow_file = 'deploy.yml';
await github.rest.actions.createWorkflowDispatch({
owner: context.repo.owner,
repo: context.repo.repo,
workflow_id: workflow_file,
ref: branch,
inputs: {
environment: branch,
title: "${{ github.event.release.tag_name }}"
},
});
.github/workflows/deploy.yml
name: DeployAll
run-name: Deploy ${{ github.event.inputs.title }}
on:
workflow_dispatch:
inputs:
title:
description: 'workflow run title to be used'
required: true
default: 'Deploy(default)'
environment:
description: 'Deployment environment'
required: true
default: 'staging'
jobs:
deploy:
runs-on: ubuntu-latest
environment: ${{ github.event.inputs.environment }}
env:
GOOGLE_APPLICATION_CREDENTIALS: ${{ vars.GOOGLE_APPLICATION_CREDENTIALS }}
GCLOUD_SERVICE_KEY: ${{ secrets.GCLOUD_SERVICE_KEY }}
steps:
- name: Checkout
uses: actions/checkout@v2
with:
ref: ${{ github.event.inputs.branch }}
- name: Make GOOGLE_APPLICATION_CREDENTIALS
run: |
echo "$GCLOUD_SERVICE_KEY" | base64 -d > $GOOGLE_APPLICATION_CREDENTIALS
# 以下各自のデプロイプロセス
# - name: Set up Node.js
# uses: actions/setup-node@v2
# with:
# node-version: 16
# ...
- レポジトリトップの右の方にあるReleases > Draft a new releaseで
a. Choose a tagの入力項目にタグバージョンv1.0.1
などを入れて新規に作る
b. Targetでデプロイ処理をしたい上記Environment連動ブランチを選ぶ
c. Release titleに workflow runsに表示したい文字列を入力する
d.Set as a pre-release
かSet as the latest release
を選んでReleaseを公開 - Actions > All workflowsにまず
Checking {Release titleに使った文字列}
のrunができる - 上記5がすぐ通るとタイマーアイコンの付いた
Deploy {release tag version}
が出てくるので、詳細を開いて"github-actions requested your review to deploy to main" > Review deployments から承認 - 環境設定連動したデプロイが回る🚀
調査に時間がかかった点
- workflow runsに出てくるタイトルはyamlの
name:
かon: push:
などに反応するブランチlatestコミットメッセージだが、去年の9月からrun-name
が使えるようになった - API経由で半自動にworkflow runを作る
workflow_dispatch
がGITHUB_TOKEN
での使用も去年の9月から可能になった - workflowでEnvironment Protection Ruleの承認プロセスを使うには
on: push: branch:
か"manually created" workflow runしか現在対応してない - workflowで
on
は複数条件設定できるが、AND
ではなくOR
なのでon: release
やon:push:tags
が Environment Protection Ruleと共存できない - レポや権限設定にもよるがSettings > Actions でwrite権限がない場合は workflowに
permissions: write-all
が必要
Discussion