🐇

VercelでPRごとにDev環境更新しつつ、任意のタイミングで本番リリースする

2023/11/15に公開

TL;DR

以下の3つをやる。

  1. main ブランチが更新されたら、自動で develop ブランチに反映されるようにする
  2. vercel.json の git.deploymentEnabled で main ブランチは自動デプロイされないようにする
  3. 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 ブランチはスキップすれば..と考えていたけど、ちょうど良い設定項目があった。

git.deploymentEnabled より:

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