📘

GitHub ActionsでNetlifyにデプロイする

2023/03/12に公開

始めに

NetlifyはGitHubリポジトリと連携するだけで簡単にデプロイ設定できると思います。しかしデプロイの条件が複雑になったり、Git submoduleなど認証周りが絡んでくるとやりづらさが出てくると思います。
実はNetlifyはGitHub Actionsからでもデプロイすることはできて、これにより認証やCIの実行条件をGitHub Actionsに寄せられて管理が楽になると思ったので、試した内容についてまとめました。

検証内容

実行するアプリケーションはなんでも良いですが、今回はViteでVue3を選択しました。このアプリケーションをdev用、prd用の2環境のサイトを用意し、GitHub Actionsで以下のタイミングでデプロイするようにします。

  • dev環境
    • devブランチpush時に本番デプロイ
    • mainブランチ以外の全てのブランチに向けたPRに対してDeploy Preview
  • prd環境
    • mainブランチpush時に本番デプロイ
    • mainブランチへのPRにのみDeploy Preview

なお、今回検証で使ったリポジトリは以下となりますので、詳細が気になる方はご参照ください。
https://github.com/wintyo/trial-netlify-using-github-actions

GitHub ActionsでNetlifyにデプロイする

Netlifyへデプロイするために必要な値を登録

まずはNetlifyへデプロイするために必要な環境変数を取得していきます。

デプロイに必要な値がある場所

次からコピーする必要のある場所を説明していきます。カッコ書きになっている変数名はGitHub Secretsに登録する名前になります。

Netlifyアクセス用のPAT(NETLIFY_AUTH_TOKEN)

以下のページにアクセスして、NetlifyのPersonal Access Tokensを取得します。

https://app.netlify.com/user/applications

Netlify Site ID(NETLIFY_SITE_ID_DEV, NETLIFY_SITE_ID_PRD)

デプロイ先の「Site settings」タブのSite detailsからSite IDを取得します。dev環境とprd環境の2サイトなのでそれぞれコピーします。

GitHub secretsに上記項目を登録

先ほどコピーしてきた値をGitHub RepositoryのSecretに登録します。
「Settings > Secrets and variables > Actions」から、「New repository secret」ボタンを押して登録します。

登録が終わったらスクショにある「Repository secrets」の項目のように、以下3つが登録されていると思います。

  • NETLIFY_AUTH_TOKEN
  • NETLIFY_SITE_ID_DEV
  • NETLIFY_SITE_ID_PRD

(任意) devとprdで判別できるようにビルドコマンドを分ける

これはデプロイ設定とは関係ありませんが、devとprdで成果物が変わるようにします。
Viteではmodeオプションによって参照する環境変数ファイルを切り替えることができるため、それに対応したnpm taskを用意しました。実際に設定した環境変数ファイルなどは本筋とはそれるので、詳細が気になる方はリポジトリの方をご参照ください。

package.json
   "scripts": {
     "dev": "vite --mode dev",
-    "build": "vue-tsc && vite build",
+    "build:dev": "vue-tsc && vite build --mode dev",
+    "build:prd": "vue-tsc && vite build --mode prd",
     "preview": "vite preview"
   },

dev環境へデプロイするGitHub Actionsの設定

先に結論を書くと、以下のyamlファイルで動きました。この後各項目について説明します。

.github/workflows/deploy-netlify-dev.yml
name: Deploy Netlify Dev

on:
  push:
    branches:
      - dev
  pull_request:
    branches-ignore:
      - main

permissions:
  contents: write
  pull-requests: write
  statuses: write
  deployments: write

jobs:
  build-and-deploy:
    runs-on: ubuntu-22.04
    timeout-minutes: 10

    steps:
      - uses: actions/checkout@v3

      - uses: actions/setup-node@v3
        with:
          node-version: 18.12.1

      - run: yarn install

      - run: yarn build:dev

      - name: Set GitHub Deployment Environment
        id: github_deployment_environment
        run: |
          if [ "$GITHUB_EVENT_NAME" = "push" ]; then
            echo "GITHUB_DEPLOYMENT_ENVIRONMENT=Netlify dev" >> "${GITHUB_OUTPUT}"
          else
            echo "GITHUB_DEPLOYMENT_ENVIRONMENT=Netlify Preview" >> "${GITHUB_OUTPUT}"
          fi

      - name: Deploy to Netlify
        uses: nwtgck/actions-netlify@v1.2
        with:
          publish-dir: './dist'
          production-branch: dev
          github-deployment-environment: ${{ steps.github_deployment_environment.outputs.GITHUB_DEPLOYMENT_ENVIRONMENT }}
          github-token: ${{ secrets.GITHUB_TOKEN }}
          deploy-message: ${{ github.event.head_commit.message || github.event.pull_request.title }}
          alias: deploy-preview-${{ github.event.number }}
          fails-without-credentials: true
        env:
          NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
          NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID_DEV }}

CI実行条件を設定する

まずはCI実行条件を設定します。本番デプロイはdevブランチのpush時なのでその通りに設定し、pull_request時は基本的には全ての条件で発動させます。ただし、mainブランチはprd環境のプレビューが走り、dev環境のプレビューは不要だと思うのでbranches-ignoreで除外しています。

dev環境デプロイのCI実行条件の設定
on:
  push:
    branches:
      - dev
  pull_request:
    branches-ignore:
      - main

permissionsの設定

次にGITHUB_TOKENで扱えるパーミッションを定義します。最近デフォルトでは勝手にコメントを追記したりpushしたりできなくなり、そのままActionsを呼んでも権限エラーになることがあります。全体設定で最初からwrite権限も付与するやり方もありますが、ここではファイルから指定する方法を採りました。以下のように必要な権限だけ追記します。(必要そうな項目全てをwrite権限付与しているので、もしかしたらもうちょっと少ない権限でも実行できるかもしれないです)

使用する権限の明記
permissions:
  contents: write
  pull-requests: write
  statuses: write
  deployments: write

他に設定できる権限はこちらをご参照ください。
https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token

基本的なインストールからビルドまで実行

ここからは実際のjobに入っていきます。最初は見慣れたようなコマンドを多く見かけるので説明は割愛させていただきます。

基本的なインストールからビルドまで
jobs:
  build-and-deploy:
    runs-on: ubuntu-22.04
    timeout-minutes: 10

    steps:
      - uses: actions/checkout@v3

      - uses: actions/setup-node@v3
        with:
          node-version: 18.12.1

      - run: yarn install

      - run: yarn build:dev

GitHub Deployment Environment名の設定

次はGitHub Deployment Environment名の設定です。
NetlifyにデプロイするGitHub Actionsを使った際に、「Environment」というセクションにデプロイ情報として表示されるようになります。ここに出す名前を設定することができるので本番ビルド時とDeploy Preview時で名前を切り替えます。

push時とpull_request時でラベルを変えれば良いので、ifで分岐してoutputに流し込みます。

GitHub Deployment Environment名の設定
- name: Set GitHub Deployment Environment
  id: github_deployment_environment
  run: |
    if [ "$GITHUB_EVENT_NAME" = "push" ]; then
      echo "GITHUB_DEPLOYMENT_ENVIRONMENT=Netlify dev" >> "${GITHUB_OUTPUT}"
    else
      echo "GITHUB_DEPLOYMENT_ENVIRONMENT=Netlify Preview" >> "${GITHUB_OUTPUT}"
    fi

NetlifyへデプロイするActionsを使ってデプロイ

最後にNetlifyへデプロイするActionsを使ってデプロイします。

- name: Deploy to Netlify
  uses: nwtgck/actions-netlify@v1.2
  with:
    publish-dir: './dist'
    production-branch: dev
    github-deployment-environment: ${{ steps.github_deployment_environment.outputs.GITHUB_DEPLOYMENT_ENVIRONMENT }}
    github-token: ${{ secrets.GITHUB_TOKEN }}
    deploy-message: ${{ github.event.head_commit.message || github.event.pull_request.title }}
    alias: deploy-preview-${{ github.event.number }}
    fails-without-credentials: true
  env:
    NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
    NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID_DEV }}

各オプションについては公式の方をご参照ください。
https://github.com/nwtgck/actions-netlify/tree/v1.2.4

その他

以上でGitHub Actionsからデプロイされるようになりました。実際に動かしてみた際の補足情報も次から記載します。

Netlifyの自動ビルドと併用した場合

Netlify標準機能で、GitHubにpushされたら自動でビルドしてデプロイします。その機能が残ったままGitHub Actionsからもデプロイしたらどうなるか検証してみました。
結果としては特にエラーは起きず、最後にデプロイした方が最新版として反映されるようです。デプロイ時のメッセージは細かいところで差分があり、GitHub Actionsからだとコミットハッシュやブランチ名などは出せないようです。

Netlify標準機能のビルドをOFFにしたい場合

GitHub ActionsでデプロイできるようになってNetlify標準機能のビルドはOFFにしたい場合は、「Build & deploy > Continuous deployment」ページの「Build settings」から「Build status」を「Stopped builds」にしたら止めることができます。

prd環境へデプロイするGitHub Actionsの設定

最後にprd環境へデプロイするGitHub Actionsを設定します。基本的にはdev環境へのデプロイと同じなので、差分が分かるように書くと以下のようになります。

.github/workflows/deploy-netlify-prd.yml
-name: Deploy Netlify Dev
+name: Deploy Netlify Prd

 on:
   push:
     branches:
-      - dev
+      - main
   pull_request:
-    branches-ignore:
+    branches:
       - main

 permissions:
   contents: write
   pull-requests: write
   statuses: write
   deployments: write

 jobs:
   build-and-deploy:
     runs-on: ubuntu-22.04
     timeout-minutes: 10

     steps:
       - uses: actions/checkout@v3

       - uses: actions/setup-node@v3
         with:
           node-version: 18.12.1

       - run: yarn install

-      - run: yarn build:dev
+      - run: yarn build:prd

       - name: Set GitHub Deployment Environment
         id: github_deployment_environment
         run: |
           if [ "$GITHUB_EVENT_NAME" = "push" ]; then
-            echo "GITHUB_DEPLOYMENT_ENVIRONMENT=Netlify dev" >> "${GITHUB_OUTPUT}"
+            echo "GITHUB_DEPLOYMENT_ENVIRONMENT=Netlify prd" >> "${GITHUB_OUTPUT}"
           else
             echo "GITHUB_DEPLOYMENT_ENVIRONMENT=Netlify Preview" >> "${GITHUB_OUTPUT}"
           fi

       - name: Deploy to Netlify
         uses: nwtgck/actions-netlify@v1.2
         with:
           publish-dir: './dist'
-          production-branch: dev
+          production-branch: main
           github-deployment-environment: ${{ steps.github_deployment_environment.outputs.GITHUB_DEPLOYMENT_ENVIRONMENT }}
           github-token: ${{ secrets.GITHUB_TOKEN }}
           deploy-message: ${{ github.event.head_commit.message || github.event.pull_request.title }}
           alias: deploy-preview-${{ github.event.number }}
           fails-without-credentials: true
         env:
           NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
-          NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID_DEV }}
+          NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID_PRD }}

終わりに

以上がGitHub ActionsでNetlifyにデプロイする方法でした。Deploy Previewの条件がNetlifyだと全てのPRか対象のブランチへのPRのみかという選択しかありませんでしたが、GitHub Actionsだと細かく設定することができました。今まで環境変数の設定や実行コマンドが固定だったので環境ごとにサイトを用意していましたが、上手く設定すればブランチデプロイでいけそうだなと感じました。(最近Netlify側も環境変数はブランチごとに設定することができるようになったのでGitHub Actionsじゃなくてもできそうな気はしますが)
Netlifyの仕様で上手くCIの設定ができず悩んでいる方の参考になれれば幸いです。

Discussion