ゼロから始めるDocs as Code

# ドキュメント書いてますか？

突然ですが、技術ドキュメント書いてますか？
ドキュメントの内容が実際のコードと乖離してないですか？
ExcelやWrod、あるいはWikiで書かれたドキュメントが扱いにくいと思ったことはないですか？
xxxxx_20231201.xlsのような日付入りのファイルが大量にできてないですか？
必要な時にすぐに情報に辿り着くことができてますか？迷子になってないですか？

# 問題点

このようなことは現場ではよく聞く話です。「あるある」と思った人も多いのではないでしょうか。

特にウォーターフォール型の受託開発の現場では大量のドキュメントがWordやExcelで作られることも多いでしょう。それはドキュメントが正式な中間成果物として扱われるためであり、そういった成果物の検収を受ける際にWordやExcelだと「納品物として都合がいい」と、（特に非エンジニアによって）判断される傾向があることと無関係ではないと思います。場合によってはアジャイルであってもドキュメントの管理については似たような状態になっていることもあるでしょう。

しかしあくまでExcelは「表計算ソフト」です。「技術ドキュメント作成ソフト」ではありません。Wordも、一般的なWikiも然りです。**テクニカルライティングにはそれに相応しい手法とツール、もっと言えば哲学が別にあるはずです。**

:::note info
先に断っておくと、すべての場合でWordやExcelで技術ドキュメントを書くことが悪いことではありません。何事も適材適所です。
:::

# 2つのメンタルモデル

これらの問題は、ドキュメントを書く人・スキル・文化・タイミングなどが、コードを書く時のそれらと別々である場合に、特に顕著に現れます。

これは「ドキュメントを書く」という行為と「コードを書く」という行為がそれぞれ全く別のメンタルモデルであると解釈されているからと考えられます。ですがそうではありません。

システムの仕様をプログラミング言語で表現するか、ドキュメント用の言語（日本人なら日本語）で表現するか、その違いに過ぎません。どちらも表現のための道具に過ぎないのです。例えば、テストコードを普段から書いているような人であれば「テストコードがドキュメントのように振る舞う」というのはイメージしやすいのではないでしょうか。

コードとドキュメントは一つのメンタルモデルで考える方が自然な気がしてきませんか？
コードを書く時と同じような開発者体験をドキュメントでも実現できると思いませんか？

# Docs as Code

https://www.writethedocs.org/guide/docs-as-code/

> Documentation as Code (Docs as Code) refers to a philosophy that you should be writing documentation with the same tools as code


**Documentation as Code（Docs as Code）** とはコードを書く時と同じツールを使ってドキュメントを書くという手法、またはその考え方・哲学を指します。
ドキュメントをコードのように扱う、つまりWordやExcelなどではなくMarkdownのようなプレーンテキストでドキュメントを書き、Gitでバージョン管理し、レビューと自動テストを回しながら継続的にドキュメントを育てていくという、まさに現代ソフトウェア開発で培われた手法そのものに倣ったやり方です。

伝統的なドキュメントライティングにおいてはドキュメントとコードは基本的に分離された存在でした。しかしDocs as Codeの考えに倣えば、ドキュメントをコードと同じように扱い、コードに近い場所に置いておくことで、コードとドキュメントを（理想的には）統一的に扱うことができるようになります。

では、ここから先は実際にどのようにDocs as Codeを始めていけばよいか、その一例を考えてみましょう。前提となる環境として、IDEにVSCode、バージョン管理にGithubを利用して普段コードを書いているものとします。

# Markdown環境

Docs as Codeではできるだけコードを書く時と同じツールを使っていくことが大事です。
まずはVSCodeでMarkdownドキュメントを書ける環境を整えていきましょう。
といってもVSCodeはデフォルトでMarkdownに対応していてプレビュー機能も付いているので特に何かする必要はありません。デフォルトでは物足りないということであれば[Markdown All in One](https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one)などの拡張機能を入れるといいでしょう。

https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one

ただし、Mermaid（マーメイド）記法などのダイアグラムの描画には対応していないので別途[Markdown Preview Mermaid Support](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-mermaid)などは入れておく必要があります。

https://marketplace.visualstudio.com/items?itemName=bierner.markdown-mermaid

Mermaid記法を使うとテキストのみで様々な図を描画できます。
代表的なところでいうとフローチャートやシーケンス図などです。

**※フローチャートの例**

```
flowchart LR
    A[Start] --> B{Is it?}
    B -->|Yes| C[OK]
    C --> D[Rethink]
    D --> B
    B ---->|No| E[End]
```

```mermaid
flowchart LR
    A[Start] --> B{Is it?}
    B -->|Yes| C[OK]
    C --> D[Rethink]
    D --> B
    B ---->|No| E[End]
```

効果的で質の高いドキュメントを書くには適切な図解が必須です。
簡単な図であればMarkdownとMermaid記法の組み合わせで何とかなりますが、複雑で巨大な図や独自のダイアグラムなどを柔軟に作りたい場合は後述するdraw.ioを併用します。

# ダイアグラムの描画環境

[draw.io](https://app.diagrams.net/)（diagrams.net）はオンライン上で様々な図を作成できる軽量な描画ツールです。これをそのままオンライン上で利用して作画してもいいのですが、draw.ioには[VSCodeの拡張機能](https://marketplace.visualstudio.com/items?itemName=hediet.vscode-drawio)が用意されているのでそれを使うのがオススメです。

https://marketplace.visualstudio.com/items?itemName=hediet.vscode-drawio

拡張機能をインストールした後、`.drawio.svg`（`.drawio.png`でも可） という拡張子で新しくファイル作ると、オンライン版と同様のGUIを使ってVSCode上で作画できるようになります。

この拡張機能を使うことで、
- VSCode上で完結するので作画のために別のツールにスイッチする必要がない
- VSCode外ではsvgまたはpngという一般的な画像ファイル形式として認識されるので画像ビューアやブラウザでそのまま表示できる
- 作画した画像をわざわざエクスポートする必要がない

といったメリットが得られます。これは非常に大きな利点です。


# ドキュメントのバージョン管理

ここまででテキストと図を組み合わせたMarkdownベースのドキュメントを作る環境が手元に出来たので、次にそのドキュメントをGitで管理することを考えましょう。
できればドキュメント管理用のリポジトリを別で作るのではなく、そのドキュメントの対象となるコードを管理するリポジトリに一緒に含める方がいいでしょう。「コードと同じ場所にある」という距離感は大事です。

書籍「[Googleのソフトウェアエンジニアリング](https://www.oreilly.co.jp/books/9784873119656/)」ではこう述べられています。

> WHEREもまた暗に示されている場合が多いが、そのドキュメントがどこに存在すべきかを決定しなければならない。通常、選ばれる場所はある種のバージョンコントロールシステム下にあるべきで、理想的にはそのドキュメントがドキュメント化している対象のソースコードとともに存在すべきだ。

その理由は簡単です。ドキュメントとコードは密結合なので、**ドキュメントの変更はその対象となるコードとともに変更されてレビューされるべき**だからです。

# 自動テストとCI/CD

ドキュメントにもソフトウェアと同じく継続的インテグレーション、継続的デリバリの考え方が応用できます。

自動テストについては[TextLint](https://textlint.github.io/)といったLinterを使用した自動校正がまず考えられます。GitHubを利用しているのであれば、Pull RequestをトリガーにしてGitHub Actionsでワークフローを組めばドキュメントのレビューおよびCI環境を作ることはそれほど難しくはないでしょう。

では、ドキュメントのCD、つまりデプロイやデリバリとは何を指すのでしょうか。
様々な考え方があると思いますが、こういったドキュメントは最終的にWEBページ（ドキュメントサイト）として閲覧できるようにしておくのが、UI/UX的にも一番優れていると思います。また、情報のアクセス性の面からもドキュメントはそれを必要とする人に対して常にオープンで開かれた場所にあり容易にアクセスできるようになっているべきです。閲覧性の観点においてWEBサイトというのは最適な表現方法でしょう。

そこでMakdownで書かれたドキュメントをhtmlに変換してWEBサーバーにデプロイすることを「ドキュメントの継続的デリバリ」と捉えます。これは[Marked](https://github.com/markedjs/marked)などを利用して自動変換のスクリプトを用意し、同じくGitHub Actionsのワークフローに組み込んでしまえば可能です。また、Markdownのドキュメントとは別に、コード内のDocコメントをhtmlに変換するフローもここで同時に行なってドキュメントサイトとして統合してしまうのもいいでしょう。場合によってはAlgoliaやElasticsearchなどの全文検索エンジンと組み合わせて検索性を高めてみるのも面白いと思います。

これでドキュメント作成からCI/CDまでの一連の流れが出来上がりました。

# Docs as Codeの始め方

1. コードと同じように、IDE（VSCode）を使って
2. コードと同じように、プレーンテキスト（Markdown）で書き
3. コードと同じように、Gitでバージョン管理を行い
4. コードと同じように、自動テストとCIでレビューを回し
5. コードと同じように、CDでWEBページとしてデプロイする

という流れをここまで見てきましたが、Docs as Codeにはそれを謳った専用のツールも存在します。例えばJetBrainsからリリースされた[Writerside](https://www.jetbrains.com/ja-jp/writerside/)は、まさにMarkdownをGitで管理しhtmlにビルドしてサーバーにデプロイする、といった機能を備えたオーサリングツールです。Markdownを基本としながらも独自のマークアップでよりリッチなドキュメントを作成することができます。

https://www.jetbrains.com/ja-jp/writerside/

もちろんこういった専用ツールを使うのも一つの手ですが、今まで見てきたように、それらに頼らずともゼロからDocs as Codeの基盤を整えるのはそれほど難しいことではありません。むしろドキュメントに対するメンタルチェンジを促すことの方がよっぽど難しく時間もかかるでしょう。だからこそDocs as Codeの哲学を実践することでドキュメントライティングのハードルを下げて、コーディングと同じメンタルモデルに近づけていくことが、ドキュメントを巡る開発者体験の向上に繋がるのではないかと思います。

# 最後に

拙作のWebサイト変換コードのサンプルをGitHubに置いておきます。
Markdown・CSV・SVGで構成されたドキュメントをhtmlに変換するだけの単純なものです。
ここで書いたことは一例に過ぎないので、是非それぞれの置かれた環境に合ったやり方でDocs as Codeにチャレンジしてみてください。

https://github.com/tikamoto/doc-publisher