koudenpaのブログ

趣味のブログです。職業柄IT関連の記事が多いと思います。

Blazor WebAssembly を GitHub Actions で GitHub Pages に発行する

koudenpa 2020 抱負 - koudenpaのブログ に書いた通り、C#でSPAを書ける ASP.NET Core Blazor に少し触れている。

Blazorはホスティングモデルが2種類あり、そのうち Blazor WebAssembly がいわゆるSPAで、サーバーで動作する機能に依存しないホスティングができる。Blazor Server は少々毛色が異なり、サーバーとSignalRで接続して協調動作する。

今回はこの Blazor WebAssemblyGitHub Pages に GitHub Actions で継続的にデリバリーしてみた。GitHubのみでリポジトリ管理からデプロイ、ホスティングが完結して非常にお手軽だ。

尚、2020年1月現在Blazor WebAssemblyはプレビュー版なので今後事情は変わってくると思われる。

Blazor アプリケーションの準備

ASP.NET Core Blazor WebAssembly のホスティングに関しては案内のドキュメントがあり、GitHub Pagesへ配置する場合にどうすればよいのか? も記載がある。

ASP.NET Core Blazor WebAssembly をホストしてデプロイする | Microsoft Docs

GitHub Pagesのような単純なファイルホスティングでは、SPAがルーティングするパスへ直接アクセスするとファイルが見つからず404ページが返却されてしまう。そのため、404ページからindexページにアクセスされたURL+パラメータの情報を引き渡すリダイレクト処理が必要となる。サンプルが提示されているので適宜取り込む。

また、独自ドメインを使わない場合はURLのパスにリポジトリ名が含まれるので、それをベースパスリダイレクト処理に指定する必要がある。

Blazor WebAssembly アプリケーションが配信する index.html404.html は以下のような形になった。

bazor-app-sandbox/BlazorAppSandbox/wwwroot at master · 7474/bazor-app-sandbox · GitHub

Actions での発行の構成

以下のようなワークフローで発行している。

bazor-app-sandbox/publish-pages.yml at master · 7474/bazor-app-sandbox · GitHub

転記してコメントした。

name: Publish Blazor Application

on:
  push:
    branches:
    - master
    # デプロイが無限ループしないようにGitHub Pagesのディレクトリは除外
    paths-ignore:
    - 'docs/**'

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v1

    # .NET Core を使用して Blazor WebAssembly のプロジェクトをリリースビルド
    - name: Setup .NET Core
      uses: actions/setup-dotnet@v1
      with:
        dotnet-version: '3.1.100'
    - name: Build Blazor Application
      run: dotnet publish -c Release ./BlazorAppSandbox/bazor-app-sandbox.csproj

    # GitHub Pages で使うディレクトリを一度削除してリリースビルドした内容をコピー
    - name: Clear dist
      run: rm -rf ./docs
    - name: Copy dist
      run: mv ./BlazorAppSandbox/bin/Release/netstandard2.1/publish/bazor-app-sandbox/dist ./docs

    # GitHub Pages 内容を Push
    # Actions が規定で用意してくれる GITHUB_TOKEN での Push では(無限ループを避けるため) Actions が動作しない
    # Pages の発行処理も Actions の一環であるようなのでやはり動作しない
    # そのため、ここではデプロイ用のSSHキーをリポジトリに追加、Secretsにその秘密鍵を指定してPushしている
    # 参考 
    # - https://github.com/peaceiris/actions-gh-pages
    # - https://github.community/t5/GitHub-Actions/Github-action-not-triggering-gh-pages-upon-push/m-p/26869/highlight/true#M301
    - name: Deploy Pages
      run: |
        if [ -n "$(git status --porcelain)" ]; then
          SSH_DIR="${HOME}/.ssh"
          mkdir "${SSH_DIR}"
          ssh-keyscan -t rsa github.com > "${SSH_DIR}/known_hosts"
          echo "${ACTIONS_DEPLOY_KEY}" > "${SSH_DIR}/id_rsa"
          chmod 400 "${SSH_DIR}/id_rsa"

          git remote set-url origin "git@github.com:${GITHUB_REPOSITORY}.git"
          git config --global user.name "7474"
          git config --global user.email "koudenpa@hotmail.com"

          git add ./docs
          git commit -m 'Pulish pages. [skip azpipelines]'
          git push origin HEAD:master
        else
          echo "No change"
        fi
      env:
        ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}

これで master ブランチの変更でPagesに発行されるようになった。 (内容はテンプレートから生成した内容程度のもの)

7474.github.io

所感

先にも書いたけれど、GitHubのみでリポジトリ管理からデプロイ、ホスティングが完結して非常にお手軽だ。

本気でホスティングするには、CDNやキャッシュの兼ね合いなどいろいろ考えることがあると思うけれど、とりあえずのホスティングなら十分なのではないかと思う。

Blazorは同じリポジトリで他にも幾つかお試しを行っているので適宜記事にまとめたい。