🥳

GitHub ActionsでビルドしてCloudflare Pagesにデプロイする

2022/08/30に公開

やりたいこと

Cloudflareは無料プランでも最高。今までGitHub PagesやNetlifyにデプロイしてCloudflare経由で配信してきた。Cloudflareは速くて安定している。

Cloudflare Pages のリポジトリ連携よりは GitHub Actionsで好きなビルド方式でビルドしたものをCloudflare PagesにデプロイしたいとCloudflare Pagesが発表された時から思っていた。それを可能にするGitHub ActionsをCloudflare公式が開発しているのを発見した。その使い方ともっとプレビューを活かせる方法も+αして書いていきたい。

コミットごとにプレビューのページが作成される。
プレビュー例: https://8ba3e416.cloudflare-pages-with-github-actions-prac.pages.dev/

やりかた

Cloudflare Pagesのプロジェクトの作成

前提としてnpmコマンドが実行できるような環境を作る。npxコマンドも付いてきていると思う。フロントエンド開発者が多いと思うので割愛。

以下を実行して新しいCloudflare Pagesのプロジェクトを作成する。

npx wrangler pages project create

(この wranglerはCloudflare公式が開発している。)

上記のコマンドを実行すると以下の画面がブラウザで開かれる。「Allow」を選択する。ブラウザが開いていない場合はターミナル上に出力されてるURLをブラウザ開くと良いと思う。

ここからはターミナルに戻る。「Successfully logged in.」が表示されていれば良い。

プロジェクト名を入力する。今回は「cloudflare-pages-with-github-actions-prac」というプロジェクト名を入力している。このプロジェクト名は最終的に.pages.devの先頭に着くことになる: https://cloudflare-pages-with-github-actions-prac.pages.dev/

次にプロダクションブランチを入力する。今回は「main」を入力している。このプロダクションブランチ以外はプレビューのURL(例えば https://60797843.cloudflare-pages-with-github-actions-prac.pages.dev/)になる。

すべて入力し終えた時の画面が以下。メトリクスを送るかなどを聞いてきている。

ここまで終わるとダッシュボード画面(https://dash.cloudflare.com/)に行くと、以下のようにPagesが一つ出来ていることが確認できる。

Cloudflareのトークンの作成

以下のAPIトークンの画面に行く。
https://dash.cloudflare.com/profile/api-tokens

以下の「Create Token」をクリック。

「Create Custom Token」の「Get started」をクリック。

「Token name」を好きに埋めて、
「Permissions」の「Account」のSelect item...になっているプルダウンを「Cloudflare Pages」に変更して、「Edit」を選択する。
最終的に以下の画像のようにする。

それ以外は変更しなくて問題なし。
あとは下にある「Continue to summary」をクリックする。

あとはCreate tokenして、一度しかトークンは表示されないので忘れずにメモする。

GitHub Actionsの作成

以下のように GitHub Actions を作る。埋めるべき項目に関して説明していく。

.github/workflows/cloudflare-pages.yml
name: Cloudflare Pages

on: [push]

jobs:
  publish:
    runs-on: ubuntu-20.04
    permissions:
      contents: read
      deployments: write
    steps:
      - name: Checkout
        uses: actions/checkout@v3
     
     # ここで好きなビルド処理をする
     
      - name: Publish to Cloudflare Pages
        uses: cloudflare/pages-action@1
        with:
          accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          projectName: <ここにプロジェクト名(今回は "cloudflare-pages-with-github-actions-prac" )>
          directory: < ここは ./dist など >
          gitHubToken: ${{ secrets.GITHUB_TOKEN }}

secrets.CLOUDFLARE_API_TOKEN は 先ほど生成した API Token のこと。

GitHubのsecretsの設定方法は、まずリポジトリの画面に行き、以下のSettingsを選択する。

左のメニューからSecretsを開き、Actionsを選択する。

以下の「New Repository Secret」ボタンを選択する。

以下の画面になるので、「Name」には「CLOUDFLARE_API_TOKEN」と入力する。「Value」にはメモしておいたAPI tokenを入力する。スペースなどがtokenの前後に入ってしまっていないか確認するといいと思う。

次にsecrets.CLOUDFLARE_ACCOUNT_IDに関して。
まず https://dash.cloudflare.com/ をブラウザで開く。するとリダイレクトして以下の赤枠のように .com/ の後ろに文字列がつく。この .com/ 以降の文字列が CLOUDFLARE_ACCOUNT_ID

tokenと同様にCLOUDFLARE_ACCOUNT_IDをsecretsに登録する。

公式であるcloudflare/pages-actionのREADME.mdにはCLOUDFLARE_ACCOUNT_IDはsecretsに登録せずに.ymlに直接書いているのでsecretsにわざわざ入れなくて大丈夫だと思うが念のためにsecretsに入れておいている。

secrets.GITHUB_TOKENは何もしなくてもGitHub Actionsから提供されるので特に設定はいらない。

ここまで設定して .github/workflows/cloudflare-pages.yml を GitHub に pushすれば 、次からpushするごとにCloudflareへのデプロイが実行されプレビューが生成される。

以下はその実行例で「Take a peek over at ...」の後にプレビューのURLが表示されていることが分かる。

もっと手軽にプレビューにアクセス

これで公式のcloudflare/pages-actionに書かれていた内容は完了!十分 Cloudflare Pages + GitHub Actions が出来ている。

だがもっとプレビューのURLに手軽にアクセスしたい。

以下のようにコミットごとの✅からプレビューに飛べるようにする。

これを実現するGitHub Actions全体は以下になる。

.github/workflows/cloudflare-pages.yml
name: Cloudflare Pages

on: [push]

jobs:
  publish:
    runs-on: ubuntu-20.04
    permissions:
      contents: read
      deployments: write
      # これを追記
      statuses: write

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Publish to Cloudflare Pages
        # これを追記
        id: cloudflare_pages_deploy
        uses: cloudflare/pages-action@1
        with:
	  accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          projectName: <プロジェクト名>
          directory: < ./distなど >
          gitHubToken: ${{ secrets.GITHUB_TOKEN }}

      # これを追記
      - name: Add publish URL as commit status
        uses: actions/github-script@v6
        with:
          script: |
            const sha = context.payload.pull_request?.head.sha ?? context.sha;
            await github.rest.repos.createCommitStatus({
              owner: context.repo.owner,
              repo: context.repo.repo,
              context: 'Cloudflare Pages',
              description: 'Cloudflare Pages deployment',
              state: 'success',
              sha,
              target_url: "${{ steps.cloudflare_pages_deploy.outputs.url }}",
            });

差分はhttps://github.com/nwtgck/cloudflare-pages-with-github-actions-prac/commit/1f0ebf2a72580bea6392c5dc02d76daca699f6bc

通常のコミットのpushに限らず、プルリクエストであってもpushごと✅にプレビューURLへのアクセスが付く。

プルリクエストであれば最終的なコミットのプレビューは以下のUIからもアクセスできる。

これは GitHubのcommit status と呼ばれる機能。commit status用の GitHub Actionsもあるが透明性を高めるためにGitHub公式のactions/github-scriptを使って実現してGitHub Actionsの信頼性を高めている。

実際のGitHub Actions

Cloudflareのダッシュボードの様子

maincommit-statusはブランチ名であり、これは cloudflare/pages-action が自動で認識してくれている。

おまけ: API tokenの使い回し

同じAPI tokenを使い回すと以下のようにエラーした。新しくtokenを生成するとデプロイは成功した。

✘ [ERROR] A request to the Cloudflare API (/accounts/***/pages/projects/<プロジェクト名>/upload-token) failed.

  Authentication error [code: 10000]
  
  If you think this is a bug, please open an issue at: https://github.com/cloudflare/wrangler2/issues/new/choose

Discussion