【Unity】DocFX for Unityを使ってGitHubでドキュメントを生成する

DocFX for Unityを使ってGitHubでドキュメントを作成する方法をまとめました。

Unity2019.3.5

はじめに

ドキュメントを作るためのツールの一つにDocFXというものがあります。

dotnet.github.io

DocFX for Unityは、UnityのプロジェクトにおいてDocFXを使ったドキュメントの生成を自動化するためのサンプルプロジェクトです。

github.com

本記事ではDocFX for Unityを使ってGitHub Pagesにドキュメントを公開するまでの手順をまとめます。

1. DocFXをインストールする

まず下記の手順に従ってDocFXをインストールします。

dotnet.github.io

インストールには以下の4つの方法が用意されています。

  • Chocolatey
  • Homebrew
  • GitHubからzipをダウンロード
  • NuGet

2. 初期設定する

次にドキュメントを自動ビルドするための環境を整えていきます。

2-1. GitHub Pagesを設定する

まずドキュメントを配置するためのGitHub Pagesを設定します。
gh-pagesというブランチ作成します。
下記のように親のいないブランチとして作ります。

$ git checkout --orphan gh-pages
$ git reset --hard
$ echo 'Hello World.' > index.html
$ git add index.html
$ git commit -am 'Initial commit of gh-pages.'

次にプロジェクトのリポジトリのSettings > GitHub PagesのSourceをgh-pages branchに設定します。
※ gh-pagesブランチをプッシュされた時点で自動的に設定された場合はそのままでOKです

f:id:halya_11:20200505232834p:plain
GitHub Pagesを設定

これでhttps://[ユーザ名].github.io/[リポジトリ名]/GitHub Pagesが作成されました。

2-2. GitHubのアクセストークンを設定する

次にGitHub上で自動的にドキュメントをビルド・デプロイするために権限の設定をします。
以下のページのGenerate new tokenからアクセストークンを発行します。

github.com

Scopeは以下のようにRepoとして作成します。

f:id:halya_11:20200505192228p:plain
アクセストークンを生成

トークンが生成されたらそれをコピーして、リポジトリのSettings > Secret > Add a new secretからAccessTokenという名前で登録します。

f:id:halya_11:20200505192637p:plain
Secretを登録

2-3. README.mdを作成

README.mdをまだ作成していない場合には作成しておきます。
DocFX for Unityではドキュメントのビルド時にREADMEをコピーしたものがルート(index.html)となるので事前に作成しておく必要があります。

2-4. .gitignoreを設定

次にプロジェクトの.gitignoreファイルを設定します。
まずビルドしたドキュメントに関連するファイルを以下のように無視する対象に指定します。
GitHubでビルドを自動化するためこれらのファイルをコミットする必要がないため)

# Documentation
Documentation/api/
Documentation/index.*
_site/
Assets/**/obj*

次にもし.csproj.slnが無視対象となっている場合には、これらを無視対象から除外するよう修正します。

#*.csproj
#*.sln

これらはAPIドキュメントを自動生成するために必要なファイルになります。
以下のような.gitignoreをそのまま使っていると無視対象になってしまうので気を付けてください。

github.com

2-5. DocFX for Unityからフォルダ・ファイルをコピー

次にDocFX for Unityから必要なフォルダ・ファイルをコピーします。
DocFX for Unityを以下のリポジトリからダウンロードします。

github.com

ダウンロードしたら展開したフォルダの中からDocumentationというフォルダをUnityプロジェクト配下にコピーします。
また.github/workflows/documentation.ymlもコピーしておきます(フォルダ階層は保ったまま)。

2-6. docfx.jsonを編集

次に前節でダウンロードしたDocumentation/docfx.jsonを編集します。
まずglobalMetadataにドキュメントのタイトルなどを入力します。

"globalMetadata": {
    "_appTitle": "Example Documentation",
    "_appFooter": "Example Documentation",
    "_enableSearch": true
},

またsitemapのbaseUrlには以下のようにしてGitHub PagesのURLを設定します。

"sitemap":
{
    "baseUrl": "https://[githubアカウント名].github.io/[リポジトリ名]",
    ...
},

変更したファイルはmasterブランチにプッシュしておきます。

3. ドキュメントを作る

初期設定が完了したらドキュメントを作っていきます。

3-1. ビルド対象APIの名前空間を設定する

APIドキュメントについては、指定した名前空間のものが自動的に生成されます。
名前空間はDocumentation/filterConfig.ymlで正規表現を使って指定します。

例えばExampleから始まる名前空間すべてを対象にしたい場合には以下のように書きます。

apiRules:
- include:
    uidRegex: ^Example\.*
    type: Namespace
- exclude:
    uidRegex: .*
    type: Namespace

ちなみに名前空間を設定していないものは以下のように書けばビルド対象になります。

- include:
    uidRegex: ^Global
    type: Namespace
3-2. マニュアルを書く

マニュアルはDocumentation/manual配下にmdファイルを配置することにより作成します。
また作成したマニュアルはtoc.ymlファイルに記述することで表示されます。

- name: manual1
  href: manual1.md
  items:
   - name: manual1-1
     href: manual1-1.md
   - name: manual1-2
     href: manual1-2.md
- name: manual2
  href: manual2.md

上記のようにtocファイルを記述すると以下のようなマニュアルが生成されます。

f:id:halya_11:20200506132506p:plain
マニュアルの例

ちなみに画像はDocumentation/resourcesフォルダに入れたうえで以下のように相対パスで指定することで表示できます。

![example](../resources/Example.png)

ただしREADME.mdをindex.mdにコピーする関係上、READMEにはURLで書かなければいけません(すべてURLにしちゃったほうがいいかも)。

3-3. ビルドして確認する

ここまで用意出来たら実際にドキュメントをローカルでビルドして確認してみます。
Windowsの場合は以下のようにコマンドを打ちます。

copy README.md Documentation\index.md
docfx Documentation\docfx.json --serve

ビルドが成功したら http://localhost:8080/ にアクセスすることでドキュメントを確認できます。

3-4. プッシュする

内容に問題がなさそうであればmasterブランチに変更をプッシュします。
するとリモートで自動的にドキュメントがビルドされ、GitHub Pagesがデプロイされます。
進捗はリポジトリのActionsから見ることができます。

f:id:halya_11:20200506004319p:plain
Actions

デプロイが終わってからしばらくすると変更内容がGitHub Pagesに反映されます。

f:id:halya_11:20200506004426p:plain
生成されたドキュメント

Rider + Assembly Definition Fileを使う場合の注意点

ライブラリを作る場合など、Assembly Definition Fileを定義してAsembly-CSharp以外のcsprojを作ることがあるかと思います。
このとき、Riderを使っているとcsprojに含まれるcsファイルへの参照が絶対パスで記述されてしまい、
リモートのビルドだけ失敗するという事象に遭遇しました。

この場合以下のようなAssetPostprocessorを使ってcsprojファイルを書き換える必要があったのでRiderをお使いの方は気を付けてください。

using System;
using System.IO;
using System.Xml.Linq;
using UnityEditor;
using UnityEngine;

public class CSProjectPostProcessor : AssetPostprocessor
{
    private static string OnGeneratedCSProject(string path, string content)
    {
        var document = XDocument.Parse(content);
        var folderPath = Application.dataPath
            .Replace("Assets", "")
            .Replace('/', Path.DirectorySeparatorChar);

        foreach (var descendant in document.Root.Descendants())
        {
            if (descendant.Name.LocalName != "Compile")
                continue;

            var attribute = descendant.Attribute("Include");
            if (attribute == null)
                continue;
            if (!attribute.Value.Contains(".cs") || !attribute.Value.Contains(folderPath))
                continue;

            attribute.Value = attribute.Value.Replace(folderPath, "");
        }
        
        return document.Declaration + Environment.NewLine + document.Root;
    }
}

ちなみにRider2019.3.4で確認したのでもっと新しいバージョンでは修正されているかもしれません。

参考

github.com

qiita.com