VercelでPRごとにDev環境更新しつつ、任意のタイミングで本番リリースする
TL;DR
以下の3つをやる。
- main ブランチが更新されたら、自動で develop ブランチに反映されるようにする
- vercel.json の git.deploymentEnabled で main ブランチは自動デプロイされないようにする
- Deploy Hooks & GitHub Actions (workflow_dispatch) で任意タイミングで本番デプロイ
前提とモチベーション
- vercel
- monorepo
- vercel のプレビュー環境/本番環境は git の branch ごとにしか作れない
- はじめは素直な vercel 運用で「PR レビュー(&動作確認)→マージ→本番リリース」としていたが、即時本番リリースされるリスクと不安感があったので、Dev環境(Staging環境(?))の用意をしたくなった
- Dev環境:PR がマージされる度にどんどん更新したい
- 本番環境:任意のタイミングでリリースしたい
やろうとしたけどやめた:
PR を develop ブランチにマージしていって、develop ブランチのプレビュー環境を Dev環境とし、develop ブランチを main ブランチにマージすることで本番リリース、でも良いかもと思ったが、monorepo 内の複数アプリケーションのリリース順やタイミングをコントロールしたかったので、これはやめた。
1. main ブランチが更新されたら、自動で develop ブランチに反映されるようにする
デフォルトブランチは main のまま。PR は main ブランチにマージしていく。
GitHub Actions で、PR がマージされ main ブランチが更新されると、同内容が develop ブランチに反映されるようにする。
develop ブランチが更新されると、vercel で develop ブランチのプレビュー環境が自動でデプロイされる(vercel デフォルトの挙動)。これを Dev環境としている。
name: Sync to Develop Branch
on:
push:
branches:
- main
jobs:
sync-develop:
runs-on: ubuntu-latest
steps:
- name: Checkout main branch
uses: actions/checkout@v4
- name: Set up Git identity
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
- name: Sync with develop branch
run: |
git fetch origin develop
git checkout develop
git reset --hard main
git push -f
2. vercel.json の git.deploymentEnabled で main ブランチは自動デプロイされないようにする
はじめは Ignore Build Step を設定して main ブランチはスキップすれば..と考えていたけど、ちょうど良い設定項目があった。
Specify the branches that will not trigger an auto-deployment when committing to them. Any non specified branch is true by default.
(コミット時に自動デプロイを行わないブランチを指定します。指定しないブランチは、デフォルトで true になります。)
3. Deploy Hooks & GitHub Actions (workflow_dispatch) で任意タイミングで本番デプロイ
Deploy Hooks で発行した URL エンドポイントに POST リクエストを投げると、指定のブランチでデプロイを開始してくれる。(vercel のプロジェクトの Settings > Git でできる。)
これには特に認証とかもなく、叩けばデプロイされてしまうので、URL はトークンやパスワードと同じ扱いをしてねとドキュメントにある。GitHub Actions からこれを使う想定なので、URL は Secrets に保管している。
また、GitHub Actions を workflow_dispatch イベントで設定すると手動実行できる。ref: ワークフローの手動実行
これで GitHub の Actions ページからポチポチ実行している。(他にも GitHub CLI や REST API で実行できるらしい。)
こんな感じ:
name: Deploy Prod
on:
workflow_dispatch:
inputs:
project:
required: true
type: choice
options:
- digdig-admin
- digdig-seller
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Set up environment for digdig-admin
if: ${{ github.event.inputs.project == 'digdig-admin' }}
run: echo "DEPLOY_ENDPOINT=${{ secrets.DIGDIG_ADMIN_PROD_DEPLOY_HOOK_ENDPOINT }}" >> $GITHUB_ENV
- name: Set up environment for digdig-seller
if: ${{ github.event.inputs.project == 'digdig-seller' }}
run: echo "DEPLOY_ENDPOINT=${{ secrets.DIGDIG_SELLER_PROD_DEPLOY_HOOK_ENDPOINT }}" >> $GITHUB_ENV
- name: Deploy
run: curl --fail -X POST ${{ env.DEPLOY_ENDPOINT }}
おわり
digdig というサービスを作っています。
まだ運用し始めなので何かあったら記事更新するかもです。
Discussion