🔗 はじめに
趣味のプロジェクトでホスティングサービスのVercelを使っています。
Vercelにはプルリクエストを立てると、いい感じのプレビュー環境を構築してくれるGitHub連携機能があるんですが、
その周辺の設定がいまいち痒いところに手が届かないというか分かりづらいので、練習がてらGitHub Actionsで管理してみることにしました。
🔗 Vercel側の設定
まず、mainブランチ向けのプルリクエストを作成/更新したときだけプレビュー環境を作り、それ以外何もしないようにしたいので、
Vercel向け設定ファイルのvercel.json
を以下のようにして完全に自動デプロイを止めます。
{
"git": {
"deploymentEnabled": false
}
}
ちょっと注意なのはgit.deploymentEnabled
は完全に止めるかdenylist的な指定しかできないっぽいので、本番環境へのデプロイは生かしたい場合はVercel管理画面のSetting>Git>Ignored Build Step
から設定する必要があります。
(似たような設定をいろんなところでできるのが紛らわしい...)
🔗 作ったワークフロー
これが最終的にできたワークフローです。
普段シェルで小難しいことやらないチンパンなのでそこは勘弁してあげてください。
name: Vercel Preview Deployment
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
on:
pull_request:
types: [opened, synchronize]
branches:
- main
jobs:
deploy_preview:
runs-on: ubuntu-latest
steps:
- name: Create Deployment
id: create_deployment
uses: octokit/request-action@v2.x
with:
route: POST /repos/{owner}/{repo}/deployments
owner: ${{ github.repository_owner }}
repo: ${{ github.event.repository.name }}
ref: ${{ github.head_ref }}
environment: preview
required_contexts: '[]'
auto_merge: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Checkout Code
uses: actions/checkout@v2
with:
ref: ${{ github.head_ref }}
- name: Install Vercel CLI
run: npm install --global vercel@latest
- name: Deploy Project to Vercel
id: deployment_to_vercel
run: |
set +e
preview_url=$(vercel deploy --token=${{ secrets.VERCEL_TOKEN }})
echo "deploy_exit_code=$?" >> $GITHUB_OUTPUT
set -e
echo "preview_url=${preview_url}" >> $GITHUB_OUTPUT
- name: Update Deployment Status
uses: octokit/request-action@v2.x
with:
route: POST /repos/{owner}/{repo}/deployments/{deployment_id}/statuses
owner: ${{ github.repository_owner }}
repo: ${{ github.event.repository.name }}
deployment_id: ${{ fromJson(steps.create_deployment.outputs.data).id }}
state: ${{ steps.deployment_to_vercel.outputs.deploy_exit_code == 0 && 'success' || 'failure' }}
environment_url: ${{ steps.deployment_to_vercel.outputs.preview_url }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Promote Error
run: exit ${{ steps.deployment_to_vercel.outputs.deploy_exit_code }}
※ VERCEL_TOKEN
はVercelアカウント設定画面のTokens
から発行できて、
VERCEL_ORG_ID
, VERCEL_PROJECT_ID
はローカル環境でVercel CLIでリンクした際に出来る.vercel/project.json
に書いてあります(参考)
🔗 困ったりしたところ
🔗 GitHub Deployment
プルリクエストの下の方に出てくるThis branch has not been deployed
等のデプロイ状況の表示はVercelみたいなPaaSに連携すると勝手に変わってくれますが、
実際何を根拠に出力されているか分からなくてモタモタしました。
これはGitHub DeploymentをAPIで更新していけば同期してくれるみたいです。
今回のワークフローだとCreate Deployment
ステップで作成してUpdate Deployment Status
ステップで結果に応じてsuccess
, failure
に遷移させています。
🔗 コマンドの出力と終了コードをDeploymentに反映させたい
Deploy Project to Vercel
ステップで実行しているvercel deploy
コマンドは、
デプロイが成功した場合はプレビュー環境のURL、失敗した場合はビルドログのURLを標準出力するので成否に関わらず保持したかったんですよね。
それで無理やり頑張った結果こんな感じになりました。
- name: Deploy Project to Vercel
id: deployment_to_vercel
run: |
set +e # vercel deployのエラーで止まらないようにする
preview_url=$(vercel deploy --token=${{ secrets.VERCEL_TOKEN }}) # URLを退避
echo "deploy_exit_code=$?" >> $GITHUB_OUTPUT # 終了コードを出力に設定
set -e # 一応エラーで止まるように戻す
echo "preview_url=${preview_url}" >> $GITHUB_OUTPUT # URLを出力に設定
保持した終了コードはDeploymentのステータスに使う他、Promote Error
ステップをそのままのコードで終了させることでワークフローの成否に反映させてます。
🔗 おわりに
私のシェルちからが足りないせいで汚くなった感じがあり大変辛いですが、ワークフローは今日も元気に動いてくれています。
最後までお読みいただきありがとうございました。