しばやん雑記

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

GitHub Actions と SWA CLI を使った Azure Static Web Apps へのデプロイを高速化する

最近は Static Web Apps へのデプロイを行うために Static Web Apps CLI を使うことが多いです。理由としては公式の GitHub Action は Docker Image を毎回ビルドするため時間がかかるのと、ビルドが必要ない場合に Oryx が必要ないので軽量な処理で行いたいというのがあります。

特に SWA CLI を使うと Service Principal / OpenID Connect を使ったシークレットレスでのデプロイが簡単に行えるというのが大きいです。詳細については以下のエントリを参照してください。

このように SWA CLI を使ったデプロイが非常に便利なので、今では GitHub Actions からのデプロイでも SWA CLI を使うようにしていたのですが、GitHub Actions で動かすとランダムでエラーが発生するようになってしまいました。既に Issue は複数上がっていたのですが解消出来ていませんでした。

根本的な原因は SWA CLI が実行時にデプロイ用クライアントが存在しない場合にダウンロードすることにあるため、デプロイ用クライアントのダウンロードをスキップすると回避可能です。

デプロイクライアントは ~/.swa 以下に保存されているため、GitHub Actions のワークフロー内でこのディレクトリをキャッシュするように設定を追加します。

name: Deploy to SWA

on:
  push:
    branches: [ master ]
  workflow_dispatch:

env:
  SWA_CLI_DEPLOYMENT_TOKEN: ***

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4

    - name: Cache SWA CLI
      uses: actions/cache@v4
      with:
        key: swa-${{ runner.arch }}-${{ runner.os }}
        path: |
          ~/.swa

    - name: Deploy to Static Web App
      run: swa deploy ./dist/ --env production

このワークフローを使ってデプロイを行ってみると、キャッシュがある場合には該当ディレクトリを復元し、更に SWA CLI を使ったデプロイ時にはクライアントのダウンロードが行われずに再利用されていることがわかります。ダウンロードしないためデプロイ時に謎のエラーは出なくなります。

デプロイ時に謎のエラーは出なくなるのですが、別にデプロイにかかる時間は大きく短縮できないため、SWA CLI 自体もキャッシュしてしまえば時間のかかる npm からのインストールをスキップ出来ます。

ただし単純に npm がインストールされたディレクトリをキャッシュするだけだと、バージョンアップに追従できなくなってしまうので工夫が必要です。具体的には最新のバージョンを取得してキャッシュキーの一部として扱うことが解決しています。

name: Deploy to SWA

on:
  push:
    branches: [ master ]
  workflow_dispatch:

env:
  SWA_CLI_DEPLOYMENT_TOKEN: ***

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4

    - name: Retrieve SWA CLI version
      id: swa-cli-version
      run: echo "version=$(npm view @azure/static-web-apps-cli version)" >> $GITHUB_OUTPUT

    - name: Cache SWA CLI
      id: cache-swa-cli
      uses: actions/cache@v4
      with:
        key: swa-${{ runner.arch }}-${{ runner.os }}-v${{ steps.swa-cli-version.outputs.version }}
        path: |
          ~/.swa
          /usr/local/bin/swa
          /usr/local/lib/node_modules/@azure/static-web-apps-cli

    - name: Install SWA CLI
      if: steps.cache-swa-cli.outputs.cache-hit != 'true'
      run: npm install -g @azure/static-web-apps-cli

    - name: Deploy to Static Web App
      run: swa deploy ./dist/ --env production

キャッシュが存在している場合は npm インストールをスキップしたいので、条件式を使ってキャッシュが存在する場合にはスキップを行うようにしています。キャッシュがあっても npm インストールを実行すると処理時間の短縮には繋がらないので注意です。

このワークフローを実行すると 2 回目以降はキャッシュが存在しているため、SWA CLI の npm インストールがスキップされていることが確認できます。

実行時間についてもキャッシュが使われている場合には大幅にデプロイ時間が短縮されていて、キャッシュが効いていない場合に比べて半分程になっています。

Static Web Apps のデプロイにこれまで絶対に 1 分以上掛かっていたのを 30 秒ほどまで短縮できたので、プレビュー環境など頻繁にデプロイしたい場合に待ち時間も減らし素早く確認できるようになりました。

ちなみにダウンロードの問題は SWA CLI の v2.0.5 で修正されたので、最新版を使っている限り問題は発生しなくなっています。古いバージョンを使っている場合にはアップデートしておくのが無難です。

バージョンのアップデートを行うとエラーは発生しないのですが、都度 npm からのインストールやデプロイクライアントのダウンロードといった処理は発生するため、キャッシュを入れておくと待ち時間のストレス無くデプロイが行えるようになります。