新しいサイトの配備先にCloudflare Pagesを使うことに決めたのだが,PureScriptを使用するなど,一般的なGatsbyの構成ではないことに起因して,Cloudflare Pagesが提供してくれるビルドシステムをそのまま使うことができなかった.代替手段として,GitHub Actionsを使用したCI/CD環境を整備した.
新しくサイトを作るにあたって,どこに公開するかを考える必要が あった.
Amazon S3, Google Cloud Storage, Azure Blobでの静的サイトホスティングは正直飽きるほどやってきているので,今回は違うものを使いたい. JAM Stackのホスティングというと,Netlify,Vercel,Cloudflare Pagesあたりが候補になるだろうか.
Netlifyは使ったことがあるので,VercelかCloudflare Pagesあたりが選択肢にあがるのだが,Cloudflare Pagesの評判をよく聞くので,今回はこれを使ってみようとおもった.
Cloudflare Pagesへのアップロード手段は3つある.
もちろん,最初は1.の方式を考えたのだが,私の構成ではうまく動かず,最終的に3.を採用した. PureScriptの存在が問題になったのである.
PureScriptコンパイラであるpurescript
とそのビルドシステムであるspago
はHaskellで書かれており,npmからインストールする場合は,基本的にコンパイル済みのバイナリが提供される.
Cloudflare Pagesはビルド環境としてNodeJSのランタイムが提供されており,npmを使用した依存関係 の解決と,ビルドを単体で実行することができる.
これならば,単にnpmの依存関係にpurescriptとspagoが追加されていればいいように思えるが,私はNixOSを使っている都合から,npmでバイナリが提供されているツールをローカルそのまま活用することができない.
そのため,purescriptとspagoはnix経由で導入している.
nixには,周辺ツールを含めたビルド環境そのものを宣言的に定義し,パッケージに含めることが出来るという大きな利点が有る一方で,ビルドを行う際は常にnixが必要となる.
今回のCloudflare Pagesのように,実行環境のカスタマイズができないプラットフォームでは,そもそもビルドする手段がなくなってしまうのだ.
とはいえ,毎回手動デプロイというのはエンジニアとしてどうなのだろう.GitHubへのPushをトリガーにして継続的デリバリが出来る環境は欲しい.ということで,GitHub Actionsを使うことにした.
GitHub Actionsであれば,カスタムランナーを作ることができるので,大体のケースに対応できる. 幸いにもMarketplaceにInstall NixというActionが存在したので,ビルドの問題はあっさり解決することができた.
最終的なワークフローファイルは以下の通りである.
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: read
deployments: write
name: Deploy to Cloudflare Pages
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install Nix
uses: cachix/install-nix-action@v15
with:
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- name: Build
env:
CONTENTFUL_SPACE_ID: ${{ secrets.CONTENTFUL_SPACE_ID }}
CONTENTFUL_ACCESS_TOKEN: ${{ secrets.CONTENTFUL_ACCESS_TOKEN }}
HASURA_ADMIN_SECRET: ${{ secrets.HASURA_ADMIN_SECRET }}
GOOGLE_TAGMANAGER_ID: ${{ secrets.GOOGLE_TAGMANAGER_ID }}
GOOGLE_TAGMANAGER_AUTH: ${{ secrets.GOOGLE_TAGMANAGER_AUTH }}
GOOGLE_TAGMANAGER_PREVIEW: ${{ secrets.GOOGLE_TAGMANAGER_PREVIEW }}
run: |
nix develop -c npm install
nix develop -c npm run build
- name: Publish
uses: cloudflare/wrangler-[email protected]
with:
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
command: pages publish --project-name=incipe-dev public
npmのビルド自体をnixでやるのは面倒だったので,開発用のシェル環境(devShell)内で依存関係の解決とビルドを行っている.これはnix-shell内部でないと,purescriptとspagoへの参照が存在しないためである.
Cloudflare PagesへのデプロイはWrangler CLIで行っている. これも,MarketplaceにDeploy to Cloudflare Workers with WranglerというCloudflare公式のActionが存在したので,それをそのまま使っただけである.
これでmainリポジトリへのpush毎に自動ビルドとデプロイが動くようになった.