🌤️

Cloudflare WorkersをGitHub Actionsでデプロイする(プレビューURL表示やDeployments登録付き)

に公開

始めに

ホスティングサービスの選択肢の一つにCloudflareがあると思います。サーバーレスとしても使えるCloudflare Workersは静的ファイルのレスポンスは課金対象に含まれず簡単なAPIと組み合わせてデプロイすることもでき、かなり優秀だと思っています。
CloudflareからGitHubと連携してデプロイ設定するのが一番楽ですが、GitHub Actionsからデプロイしたいケースもあると思います。GitHub Actionsからデプロイする方法はいくつか記事がありましたが、プレビューURLをコメントする方法がなかったりあったとしても冗長な設定でもうちょっと良い方法がないか模索しておりました。
普段 NetlifyのGitHub Actions を使っており、それと同じように以下のような機能を有するGitHub Actionsを設定することができたので、その方法についてまとめました。

  • プレビューURLをGitHub PR上にコメントする
  • GitHub Deploymentsに登録

作ったもの

今回検証用でCloudflareのKVを使ったTODOリストアプリを作りました。実装は以下の記事を参考にしました。
https://zenn.dev/azukiazusa/articles/hono-cloudflare-workers-rest-api

クライアントサイドはVue3でTanStack Queryを使って実装しましたが本題から逸れるので実装内容は割愛します。詳細気になる方は以下のリポジトリからご参照ください。

https://github.com/TakanoriOnuma/trial-cloudflare-todo-list

またデプロイ先は以下になります。

https://trial-cloudflare-todo-list.numa-san-1024.workers.dev/

Cloudflare WorkersをGitHub Actionsからデプロイする

デプロイできるようにGitHub Actionsにシークレットキーを登録

GitHub ActionsからデプロイするにはAPIトークンとアカウントIDが必要になります。まずはそれを用意していきます。

APIトークンの作成

Manage Account > Account API Tokensに遷移して、「Create Token」をクリックします。

そこで「Edit Cloudflare Workers」のテンプレートを選択します。

このまま作成でも問題ないですが、Token nameを編集しておくと識別しやすくなると思います。

作成したらトークンが表示されるのでCopyを押してコピーし、CLOUDFLARE_API_TOKENなどの名前でGitHubシークレットキーに登録します。

アカウントIDの取得

アカウントIDの参照は結構簡単で、Workers&Pagesのところにあります。ここからコピーしてCLOUDFLARE_ACCOUNT_IDなどの名前でGitHubシークレットキーに登録します。

GitHub Actionsでproductionデプロイする

まずはプレビューではなくproductionデプロイをGitHub Actionsから行います。以下のようなコードでデプロイできるようになります。インストールやビルドステップは適宜読み替えてください。また今回の検証ではモノレポで実装したのでworkingDirectoryを設定してますが、直下にコードがある場合は設定不要です。なお、Worker名はwrangler.jsoncなどの設定ファイルから参照され、事前に作っていない場合は勝手に新規で作られます。

Cloudflare Workersをproductionデプロイする
name: Deploy to Cloudflare Workers

on:
  push:
    branches:
      - main

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

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version-file: "package.json"
          cache: "npm"

      - name: Install dependencies
        run: npm install

      - name: Build Web App
        run: npm run w:web build

      - name: Deploy to Cloudflare Workers In Production Mode
        if: ${{ github.event_name == 'push' }}
        id: deploy
        uses: cloudflare/wrangler-action@v3
        with:
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
          workingDirectory: server
          command: "deploy"
          gitHubToken: ${{ secrets.GITHUB_TOKEN }}

GitHub Actionsでプレビュー用をデプロイしてPR上にコメントする

プレビュー用をデプロイして、そのURLをPR上にコメントするには以下のような手順が必要です。

  1. エイリアス名の定義と最終的なエイリアス付きURLを保存
    公式のPreview URLs に書かれていますが、プレビューURLは以下のようなフォーマットになっているため、それに合わせてURLを定義します。一度envにそれぞれ定義すると読みやすくなると思います。
    <VERSION_PREFIX OR ALIAS>-<WORKER_NAME>.<SUBDOMAIN>.workers.dev

  2. エイリアス名指定でデプロイ
    versions upload --preview-alias [エイリアス名]でプレビューデプロイができます。エイリアス名はなんでも良いですが、Netlifyに合わせてここではdeploy-preview-[PR番号]にしています。

  3. デプロイした結果をPR上にコメントする
    thollander/actions-comment-pull-requestを使ってPR上にコメントします。デプロイ先のURLはoutputs.deployment-urlで取得できますが、こちらはデプロイごとに異なるURLでエイリアス設定したURLは残念ながら取得できないので1.で保存したURLを使って出力します。

これを具体的にコードに落とすと以下のようになります。

プレビュー用をデプロイしてPR上にコメントする
 name: Deploy to Cloudflare Workers

 on:
   push:
     branches:
       - main
+  pull_request:

+permissions:
+  pull-requests: write

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

     steps:
       - uses: actions/checkout@v4

       - uses: actions/setup-node@v4
         with:
           node-version-file: "package.json"
           cache: "npm"

       - name: Install dependencies
         run: npm install

       - name: Build Web App
         run: npm run w:web build

       - name: Deploy to Cloudflare Workers In Production Mode
         if: ${{ github.event_name == 'push' }}
         id: deploy
         uses: cloudflare/wrangler-action@v3
         with:
           apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
           accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
           workingDirectory: server
           command: "deploy"
           gitHubToken: ${{ secrets.GITHUB_TOKEN }}

+      - name: Alias Deployment URL
+        if: ${{ github.event_name == 'pull_request' }}
+        id: alias
+        run: |
+          echo "name=${ALIAS_NAME}" >> $GITHUB_OUTPUT
+          echo "url=https://${ALIAS_NAME}-${WORKER_NAME}.${SUBDOMAIN}.workers.dev" >> $GITHUB_OUTPUT
+        env:
+          ALIAS_NAME: deploy-preview-${{ github.event.pull_request.number }}
+          WORKER_NAME: trial-cloudflare-todo-list
+          SUBDOMAIN: numa-san-1024
+
+      - name: Deploy to Cloudflare Workers In Preview Mode
+        if: ${{ github.event_name == 'pull_request' }}
+        id: deploy-preview
+        uses: cloudflare/wrangler-action@v3
+        with:
+          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
+          accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
+          workingDirectory: server
+          command: "versions upload --preview-alias ${{ steps.alias.outputs.name }}"
+          gitHubToken: ${{ secrets.GITHUB_TOKEN }}
+
+      - name: Comment Preview URL
+        if: ${{ github.event_name == 'pull_request' }}
+        uses: thollander/actions-comment-pull-request@v3
+        with:
+          message: |
+            🚀 Deployed to Cloudflare Workers
+            Preview URL: ${{ steps.alias.outputs.url }}
+            <sub>Deployment URL: ${{ steps.deploy-preview.outputs.deployment-url }}</sub>
+          comment-tag: "cloudflare-workers-deployment"

出力されたコメントは以下のようなものになります。基本的にはPreview URLの方を参照すると思いますが、コミットごとのデプロイを参照したい場合は下のリンクにアクセスすると良いです。

設定ファイルに "preview_urls": true があると勝手にプレビュー機能がONにされるらしいのですがタイミングが悪かったのか上手く表示できなかったので、その時は設定画面からEnableを押して有効にしてください。

余談: KVのプレビューについて

CloudflareのKVにはpreview_idという設定がありますが、あれはversions uploadでは参照されず本番のKVの方が使われてしまいました。軽く調べた感じ方法が分からなかったのでChatGPTに聞いたところ、ちゃんとやるにはそもそもenvにpreview用を用意すると良いらしく、preview_idは廃止方向になるとのことでした。公式ドキュメントをちゃんと読んだわけではないので真実は定かではないですが、確かにenvでpreview用を用意した方が他のケースにも対応できるしそっちに寄せた方が良さそうだなぁと感じました。この辺は今回重要なところではないため一旦プレビューURLでも本番にアクセスする状態になっています。

GitHub Deploymentsに登録

最後にGitHub Deploymentsにも登録しておきます。これをするとGitHubリポジトリのトップページからデプロイされたアプリを確認することができます。複数デプロイする場合はここで一覧できるのは便利そうです。

GitHub Actionsを使って登録する場合は chrnorm/deployment-actionchrnorm/deployment-statusを使うと以下のようなコードでできます。少し手間ですが一度デプロイの枠を作成して、そこにsuccessかfailureか更新する必要があります。

GitHub Deploymentsに登録
 name: Deploy to Cloudflare Workers

 on:
   push:
     branches:
       - main
   pull_request:

 permissions:
   pull-requests: write
+  deployments: write

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

     steps:
       - uses: actions/checkout@v4

       - uses: actions/setup-node@v4
         with:
           node-version-file: "package.json"
           cache: "npm"

       - name: Install dependencies
         run: npm install

       - name: Build Web App
         run: npm run w:web build

       - name: Deploy to Cloudflare Workers In Production Mode
         if: ${{ github.event_name == 'push' }}
         id: deploy
         uses: cloudflare/wrangler-action@v3
         with:
           apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
           accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
           workingDirectory: server
           command: "deploy"
           gitHubToken: ${{ secrets.GITHUB_TOKEN }}

+      - name: Create GitHub Deployment
+        if: ${{ github.event_name == 'push' }}
+        id: deployment
+        uses: chrnorm/deployment-action@v2
+        with:
+          token: ${{ secrets.GITHUB_TOKEN }}
+          environment: "Cloudflare Workers Production"
+
+      - name: Set Deployment Status
+        if: ${{ github.event_name == 'push' }}
+        uses: chrnorm/deployment-status@v2
+        with:
+          token: ${{ secrets.GITHUB_TOKEN }}
+          state: "success"
+          deployment-id: ${{ steps.deployment.outputs.deployment_id }}
+          environment-url: ${{ steps.deploy.outputs.deployment-url }}

       # pull_requestのステップは省略

終わりに

以上がCloudflare WorkersをGitHub Actionsでデプロイする方法でした。NetlifyのGitHub Actionsのようにコメントを出したりDeploymentsに登録するところもやろうとすると割と書くことがあって、この辺もマルっとやってくれてかなりありがたかったなぁと感じました。ただ疎結合の観点からすると過剰な気はしてあくまでデプロイする部分だけやるのが普通なんだろうなと感じており、他のデプロイでも今回設定した内容が使えそうだなと思いました。
Cloudflare WorkersをGitHub Actionsでデプロイしたい人や、プレビューURLをPR上にコメントしたりGitHub Deploymentsに登録したい人の参考になれば幸いです。

GitHubで編集を提案

Discussion