😎

Cloudflare Workers + Github Actionsで一つのリポジトリから環境毎のWorkersにデプロイする

2024/10/27に公開

はじめに

Cloudflare Workers で Github Actions を使用して環境毎にデプロイする方法で少し詰まったのでその際のメモです。

API トークンの取得・設定

この辺りは他の方の記事があるので紹介されている手順通りに取得します。
https://zenn.dev/monicle/articles/4613eb4064dc40
https://zenn.dev/camomile_cafe/articles/ec3df91c4e7a58

環境変数を設定(セキュアな情報の場合)

wrangler.toml はリポジトリに含めて運用することが想定されているので、環境変数を設定する場合は Github の Secrets を使用します。
API トークンの取得・設定の記事で設定した方法と同じ手順で、SettingsSecrets an variables から設定します。

環境変数を設定(セキュアではない情報の場合)

特に見られても問題のない情報の場合は wrangler.toml に記載しておきます。

wrangler.toml
name = "sample-worker"
compatibility_date = "2024-10-18"

[env.dev.vars]
API_URL = "http://localhost:8080/rest/v1"
SERVICE_X_DATA = { URL = "service-x-api.dev.example", MY_ID = 123 }

######## STAGING environment config ########

[env.staging]
name = "sample-worker-staging"
route = { pattern = "staging.sample.com/*", zone_name = "sample.com" }

[env.staging.vars]
API_URL = "http://stg.example.com/rest/v1"
SERVICE_X_DATA = { URL = "service-x-api.dev.example", MY_ID = 123 }

######## PRODUCTION environment config ########

[env.production]
name = "sample-worker-production"
route = { pattern = "sample.com/*", zone_name = "sample.com" }

[env.production.vars]
API_URL = "http://example.com/rest/v1"
SERVICE_X_DATA = { URL = "service-x-api.prod.example", MY_ID = 456 }

Github Actions の設定

.github/workflows/deploy.ymlをプロジェクト直下に作成し、main または develop ブランチに push(main にマージされた場合でも)された際にデプロイするように設定します。

deploy.yml
name: Production & Staging Deploy

on:
  push:
    branches:
      - main
      - develop

jobs:
  publish:
    runs-on: ubuntu-20.04
    permissions:
      contents: read
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Install
        run: npm install
        working-directory: ./

      - name: Build
        run: npm run build
        working-directory: ./

      - name: Set environment
        id: set-env
        run: |
          echo "ENV_NAME=${{ github.ref_name == 'main' && '--env production' || '--env staging' }}" >> $GITHUB_ENV

      - name: Deploy
        id: cloudflare-wrangler
        uses: cloudflare/wrangler-action@v3
        with:
          apiToken: ${{ secrets.CF_API_TOKEN }}
          accountId: ${{ secrets.CF_ACCOUNT_ID }}
          command: deploy --env ${{ env.ENV_NAME }}
          secrets: |
            SAMPLE_URL
            SAPLE_KEY
          ENVIRONMENT: ${{ env.ENV_NAME }}
        env:
          SAMPLE_URL: ${{ secrets.SAMPLE_URL }}
          SAPLE_KEY: ${{ secrets.SAPLE_KEY }}

Workflow のポイントは以下です。

deploy コマンドのオプションに--env を追加

deploy.yml
      - name: Set environment
        id: set-env
        # mainブランチの場合はproduction、それ以外はstagingを指定
        run: |
          echo "ENV_NAME=${{ github.ref_name == 'main' && '--env production' || '--env staging' }}" >> $GITHUB_ENV

      - name: Deploy
        id: cloudflare-wrangler
        uses: cloudflare/wrangler-action@v3
        with:
          command: deploy --env ${{ env.ENV_NAME }}

環境毎に deploy 先の Workers を変更する場合、deploy コマンドのオプションに--env を追加します。
ここで wrangler.toml に設定したproductionまたはstagingを指定することで wrangler.toml の環境変数等の設定情報が反映されます。

secrets のアップロード

deploy.yml
      - name: Deploy
        id: cloudflare-wrangler
        uses: cloudflare/wrangler-action@v3
        with:
          secrets: |
            SAMPLE_URL
            SAPLE_KEY
          ENVIRONMENT: ${{ env.ENV_NAME }}
        env:
          SAMPLE_URL: ${{ secrets.SAMPLE_URL }}
          SAPLE_KEY: ${{ secrets.SAPLE_KEY }}

Github の settings から設定した secrets をアップロードする場合はsecrets: に指定します。
ENVIRONMENTでアップロード先の環境を指定します。ここは Wrangler GitHub Action のドキュメントに記載されていなかったので独自で追加しています。
最適な方法かはわかりませんが、secrets についても環境毎に分けたい場合は別名の secrets を作成して env.ENV_NAME で切り替える方法もあるかと思います。

deploy.yml
      - name: Deploy
        id: cloudflare-wrangler
        uses: cloudflare/wrangler-action@v3
        with:
          secrets: |
            SAMPLE_URL
            SAPLE_KEY
          ENVIRONMENT: ${{ env.ENV_NAME }}
        env:
          SAMPLE_URL: ${{ github.ref_name == 'main' && secrets.PROD_SAMPLE_URL || secrets.STG_SAMPLE_URL }}
          SAPLE_KEY: ${{ github.ref_name == 'main' && secrets.PROD_SAPLE_KEY || secrets.STG_SAPLE_KEY }}

ENVIRONMENTを追加した際の調査メモ

最初は Wrangler GitHub Action のドキュメントに記載されているサンプルを参考に Workflow を作成したのですが、secrets がアップロードされない問題が発生しました。

アップロードに失敗した Workflow

deploy.yml
      - name: Deploy
        id: cloudflare-wrangler
        uses: cloudflare/wrangler-action@v3
        with:
          apiToken: ${{ secrets.CF_API_TOKEN }}
          accountId: ${{ secrets.CF_ACCOUNT_ID }}
          command: deploy --env ${{ env.ENV_NAME }}
          secrets: |
            SAMPLE_URL
            SAPLE_KEY
        env:
          SAMPLE_URL: ${{ secrets.SAMPLE_URL }}
          SAPLE_KEY: ${{ secrets.SAPLE_KEY }}

原因を探るべく Github Actions の実行結果を確認したところ、secret:bulk コマンドに--env オプションがついていないことがわかりました。

🔑 Uploading secrets...
  /usr/local/bin/npx wrangler secret:bulk

   ⛅️ wrangler 3.80.1 (update available 3.83.0)
  ---------------------------------------------

  ▲ [WARNING] `wrangler secret:bulk` is deprecated and will be removed in a future major version.

    Please use `wrangler secret bulk` instead, which accepts exactly the same arguments.


  🌀 Creating the secrets for the Worker "sample-worker-staging"
  ✨ Successfully created secret for key: SAMPLE_URL
  ✨ Successfully created secret for key: SAPLE_KEY

  Finished processing secrets JSON file:
  ✨ 2 secrets successfully uploaded

Wrangler GitHub Action のソースコードを確認したところENVIRONMENTを指定することで secret:bulk コマンドに--env オプションが追加される様になっています。
https://github.com/cloudflare/wrangler-action/blob/b2be7abbfc024e06516af00e22260d4b6edcce53/src/index.ts#L235-L255

ということでENVIRONMENTを指定してあげて無事環境毎に secrets をアップロードできるようになりました。

参考

https://developers.cloudflare.com/workers/wrangler/commands/#secretbulk

Discussion