しばやん雑記

Azure とメイドさんが大好きなプログラマーのブログ

Azure Static Web Apps へのデプロイだけを行う軽量な GitHub Actions を公開しました

最近は静的な Web ページが必要な場合に Astro や Vite を使っているので、デプロイ先には当然ながら Static Web Apps を選んでいます。App Service に比べると大幅にコストダウンが可能で、設定ファイルを使ったカスタマイズが便利なので良いサービスなのですが、デプロイに関してはビルドを同時に行うため若干癖があります。

ソースコードが GitHub にある場合、Static Web Apps をデプロイするタイミングでリポジトリを紐づけておけば GitHub Actions が自動作成されますが、ワークフローでは公式の Actions である Azure/static-web-apps-deploy が使われます。

この Actions は Web Apps や Azure Functions のデプロイを行う Actions とは異なり、内部で Oryx という App Service 全体で使われているビルドエンジンを使ってアプリケーションのビルド自体を行い、Docker ベースで動作するようになっています。Oryx 自体は多くのプラットフォームに対応した高機能なビルドエンジンですが、その分挙動が隠されている部分も多く Docker ベースというのもありイメージのビルドで時間がかかります。

最近ではビルドプロセスをカスタマイズしたいケースも多いので、ビルドは GitHub Actions 側で行いつつデプロイだけを Azure/static-web-apps-deploy で行うようにワークフローを作ることも増えてきました。現状の Actions でも skip_app_build というオプションを指定すれば実現可能ですが、デプロイだけ行うためにイメージのビルドが必要になるのでオーバーヘッドが大きいです。

基本的にはビルド環境含めてコントロール出来た方が良いので、最近は Static Web Apps CLI を使ってデプロイだけを実行させるようにしていました。この方法の場合は SWA CLI のインストールコストが発生しますが、イメージの作成よりは軽くキャッシュも追加できるので概ね満足していました。

キャッシュまでを含めた詳細な方法は以下のエントリで書いているので、興味がある方はこちらを参照してください。npm でグローバルインストールしている場合のキャッシュ方法としても参考になるかもしれません。

とはいえ SWA CLI を使う方法にもデメリットがあります。SWA CLI のインストールはそれなりに時間のかかる処理で、キャッシュを入れないと思ったより時間がかかり、そのキャッシュの処理の方が定義としては多くなります。単純に Static Web Apps へデプロイしたいだけなのに考えることが多いのは避けたいです。

前置きが非常に長くなりましたが、流石に何とかしたくなったのと AI コーディングに最近はかなり慣れてきたので、シンプルに Static Web Apps へのデプロイだけを行う GitHub Actions を作りました。デプロイの処理自体は SWA CLI と同じですし、Marketplace に公開しているので誰でも簡単に利用できます。

SWA CLI は内部的に StaticSitesClient という CLI を使っているので、この Actions はそれの薄いラッパーのようなものです。自動的にキャッシュも行うので効率的にデプロイが行えるようになっています。

デプロイ方法としては Deployment Token を使った方法と azure/login を使う方法の両方に対応しています。Deployment Token を使う場合は以下のようにシンプルにパラメータで渡すだけです。

- name: Deploy to Azure Static Web Apps
  id: deploy
  uses: shibayan/swa-deploy@v1
  with:
    app-location: dist
    deployment-token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN }}

Deployment Token を直接渡すのではなく azure/login を使う場合は app-name を渡すと Resource Manager API を使って該当リソースを探して、Deployment Token を取得してデプロイを行います。

この時 app-name と同時に resource-group-name も指定できますが、Static Web Apps がリソースグループのスコープでのユニークとなっているので、サブスクリプションに同名の SWA が存在する時に指定する必要があります。

- name: Azure login
  uses: azure/login@v2
  with:
    client-id: ${{ secrets.AZURE_CLIENT_ID }}
    tenant-id: ${{ secrets.AZURE_TENANT_ID }}
    subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

- name: Deploy to Azure Static Web Apps
  uses: shibayan/swa-deploy@v1
  with:
    app-location: dist
    app-name: my-static-web-app
    resource-group-name: my-resource-group

SWA CLI を使う方法よりもシンプルに定義を書けて、公式の Actions よりも軽量なので扱いやすいものになっているかと思います。自分が SWA を使っている部分は Actions を使うように全て書き換えましたが、非常に快適に使えています。

公式のテンプレートをベースに GitHub Copilot Chat の GPT-5.4 と Opus 4.6 を使って全て実装しました。