Sphinx製ドキュメントをAzure Static Web Appsにデプロイする

## はじめに

5月に開催されたMicrosoft Build 2020にて静的コンテンツのホスティングサービスStatic Web Appsが発表され、現在はプレビュー版として無料で利用可能です。
勉強もかねてPythonやLinuxカーネルの公式ドキュメントでも使用されているSphinxをデプロイしてみました。

## 前提

SphinxのプロジェクトがGitHubにPushされている必要があります。
なお、当該プロジェクトは```sphinx-quickstart```実行時の以下の質問にて、**成果物のディレクトリを分離する**設定がなされているものとします[^1]。
この設定で```make html```を実行すると```build/html```以下にコンテンツが生成されます。

```console
> Separate source and build directories (y/n) [n]: y
```

[^1]: この質問で```n```を選ばれている場合は```build/html```の部分を適宜読み替えてください。

## Static Web Appsの作成

Azure PortalからStatic Web Apps(Preview)を作成します。
ビルドの設定ページでは以下のような値を指定してください。

![ビルドの設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34611/ca4a34b0-0d05-699e-f735-edbb956a07e9.png)

「アプリの場所」としてSphinxの成果物が出力されるディレクトリを指定します。
「APIの場所」はAzure Functionsを使用する場合にのみ必要となるので、今回は指定不要です。
「アプリの成果物の場所」は自動生成されるワークフロー(後述)に既定で含まれるアクションで使用される値のため指定不要です。
これらの設定は[クイック スタート:静的 Web アプリを初めてビルドする](https://docs.microsoft.com/ja-jp/azure/static-web-apps/getting-started?tabs=vanilla-javascript)を参考にしました。

## ワークフローの修正

Static Web Appsの作成が終わると、紐づけたGitHubのリポジトリの```.github/workflow```直下にGitHub Actions用のワークフローとして```azure-static-web-apps-(ランダム文字列).yml```が自動的に追加されます。
このワークフローは標準でpushやプルリクエストをトリガーとして、[static-web-apps-deploy](https://github.com/Azure/static-web-apps-deploy)がコンテンツをビルドし、成果物をデプロイしてくれるようになっています[^2]。
詳細は[Azure Static Web Apps プレビューの GitHub Actions ワークフロー](https://docs.microsoft.com/ja-jp/azure/static-web-apps/github-actions-workflow)をご覧ください。

ワークフローが追加されると同時にこのワークフローが実行されますが、このままではSphinxはビルドできないためワークフローの実行は失敗します。
Sphinxのビルドができるよう、ワークフローをカスタマイズします。

ありがたいことにSphinxをビルドするアクションとして[Sphinx Build](https://github.com/marketplace/actions/sphinx-build)が公開されているので、それを使用させていただきます。
自動追加された```.github/workflow```直下のワークフローを以下のように修正します。

```yaml:azure-static-web-apps-(ランダム文字列).yml
name: Azure Static Web Apps CI/CD

on:
  push:
    branches:
    - master
  pull_request:
    types: [opened, synchronize, reopened, closed]
    branches:
    - master

jobs:
  build_and_deploy_job:
    if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed')
    runs-on: ubuntu-latest
    name: Build and Deploy Job
    steps:
    - uses: actions/checkout@v1
    - name: Sphinx Build
      uses: ammaraskar/sphinx-action@master
      with:
        docs-folder: "./"
        pre-build-command: "apt-get update -y && apt-get install -y fonts-ipafont"
    - name: Build And Deploy
      id: builddeploy
      uses: Azure/static-web-apps-deploy@v0.0.1-preview
      with:
        azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_MANGO_RIVER_0AFDB141E }}
        repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for GitHub integrations (i.e. PR comments)
        action: 'upload'
        ###### Repository/Build Configurations - These values can be configured to match you app requirements. ######
        app_location: 'build/html' # App source code path
        api_location: '' # Api source code path - optional
        app_artifact_location: '' # Built app content directory - optional
        ###### End of Repository/Build Configurations ######

  close_pull_request_job:
    if: github.event_name == 'pull_request' && github.event.action == 'closed'
    runs-on: ubuntu-latest
    name: Close Pull Request Job
    steps:
    - name: Close Pull Request
      id: closepullrequest
      uses: Azure/static-web-apps-deploy@v0.0.1-preview
      with:
        azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_MANGO_RIVER_0AFDB141E }}
        action: 'close'
```

```Sphinx Build```というステップを追加しています。
このアクションはパラメータとして```docs-folder```(指定必須)、```build-command```(デフォルト値は```make html```)、```pre-build-command```(デフォルト値なし)が定義されています。
```docs-folder```にはリポジトリのルートディレクトリを基準としたSphinxのプロジェクトのルートディレクトリの相対パスを指定します。
```build-command```はドキュメントのビルドコマンドをカスタマイズする場合に指定しますが、今回はデフォルト値のコマンドで差し支えないため指定していません。
```pre-build-command```はビルド前に実行させたいコマンドを指定できます。
今回はblockdiagなどで日本語フォントを使う可能性を考慮して、IPAフォントをインストールするようにしました。

ワークフローの修正は以上です。
これでpushなどをトリガーとしてSphinxのプロジェクトがビルドされ、成果物はstatic-web-apps-deployがプレーンなhtmlと判断してStatic Web Appsへデプロイされるようになります。

[^2]: 内部ではOryxというビルドエンジンがプロジェクトの種類に応じてコンテンツをビルドしてくれているようで、React、Angular、Vue、プレーンなhtmlに標準で対応しているようです。

## Sphinx拡張機能の追加

このアクションは先のパラーメータとは別に、```docs-folder```へ指定したパスに```requrements.txt```を配置しておくことでSphinxのビルドに必要となるPythonパッケージがインストールできます。
必要に応じてドキュメントで使う可能性のあるSphinx拡張を指定してください。
参考までにblockdiagなどの拡張を使用する場合は以下のようになるかと思います。

```text:requrements.txt
sphinxcontrib-blockdiag
sphinxcontrib-seqdiag
sphinxcontrib-actdiag
sphinxcontrib-nwdiag
```

## 最後に

GitHub Actionsの知識ゼロ状態からやってみましたが、初歩的な仕組みが分かれば意外と簡単にできました。
いや、必要なアクションを作ってくださっている先駆者が居たおかげなのですが笑
望むとすれば、事前にワークフローをリポジトリに作成しておいて、それをStatic Web Appsに関連付けられるようになるといいなぁと思います。
あとは、GitHubだけじゃなくてAzure Pipelineからデプロイできてもいいなぁとも。

ところで無料プランは正式版がリリース後も維持されるのでしょか。
無料プランはぜひ維持してもらいたいですね笑

記事に間違い等あればご指摘いただけると助かります!