GitHub Copilotによって遂にPythonコードのドキュメントの完全自動生成を成し遂げた話

## Summary

- GitHub Copilot $\times$ Sphinx $\times$ GitHub Pages で遂にPythonプログラムのドキュメント完全自動生成を成し遂げた
- GitHub Copilot で `/doc` コマンドを実行してdocstringを生成してあげるだけで本格的なHTMLドキュメントが勝手に生成される
- これからはドキュメント作成に悩まされることはなくなった！

## これまで何に困っていたか

プログラムのドキュメント作成といえば，プログラミングに何かとついてまわってくる作業です．

![Figure1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154356/b5fc23b8-3085-637e-43f0-8df7158f6ac1.png)

他人が書いたコードを正確に読み取るというのはそこそこ研鑽が必要な技術なので，それを補うためにドキュメントが存在します．実際，今のプログラミングスタイルでは必要な機能を自分でゼロから実装することはほぼなく，複数のライブラリを複雑に組み合わせてやりたいことを実現するスタイルが主流です．

したがって，自分が実装したライブラリなどを使ってもらう場合でも最低限のドキュメント整備は必須と言ってよいと思われます．

下図は[Python3.12.0のドキュメント](https://docs.python.org/ja/3/library/string.html)の一部ですが，これくらい品質の良いドキュメントを整備するのはコードを書くことと同等かそれ以上に労力がかかるのではないかと思います．  
**ドキュメントを作成するのは非常に手間がかかるのです．**  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154356/14d435a5-5bf8-2055-7dbe-fc276db37850.png)

### ドキュメント自動生成における偉大な先人たちの足跡
Quick Startなどどうしても人が書かなければいけないドキュメントもありますが，APIリファレンスやプログラムの構造的なドキュメントなどはこれまでも自動生成する仕組みがあれこれ考えられてきました．

#### Sphinx
Pythonのドキュメント自動生成で最も有名なのは，おそらく[Sphinx](https://www.sphinx-doc.org/ja/master/)ではないかと思います．  
多少ややこしい設定はありますが，Pythonのdocstringから半自動的にHTMLのドキュメントを生成してくれるライブラリです．

ここまでは，かなり前からできるようになっていました．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154356/73b8d3f6-0aa0-925f-04a5-5d2e83658c11.png)


しかし，~~筆者は~~プログラマというものは思った以上に面倒くさがりな人々のようで，  
**Pythonプログラムを書く → docstringを書く → SphinxコマンドでHTML化 → Webサーバにデプロイ**  
という短いサイクルすら回すことができませんでした．．．

#### GitHub Pages
そこで，最近はGitHub Pagesというものが出てきて，リポジトリごとにHTMLのドキュメントを自動でホストしてくれるようになりました．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154356/e1881b66-6543-e8b8-ffd3-9dbc84d080d0.png)

これで，  
**SphinxコマンドでHTML化 → Webサーバにデプロイ**  
という後工程をほぼ完全に自動化することができるようになりました．

なので，現在のところプログラムドキュメントを作成作業は，  
**Pythonプログラムを書く → docstringを書く → GitHubにPushする**  
という3工程にまで圧縮されています．

## 最後のパーツ GitHub Copilot

**Pythonプログラムを書く → docstringを書く → GitHubにPushする**

さて，この3工程を見ていただければわかるように，**GitHub Copilotが遂に最後の最も面倒な部分を埋めてくれました！**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154356/22a9a004-c34f-205c-d677-e9934396c208.png)


コードを書き終わったら，`/doc` とするだけで全てのモジュールに大体のdocstringをつけてくれます！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154356/dbc5e8ab-dbe6-48a8-c844-dcb349058d06.png)


**これによってプログラムドキュメントを作成する作業は  
Pythonプログラムを書く (ついでに`/doc`する) → GitHubにPushする  
という，普通にコードを書くだけの作業に収束しました！**

**遂にドキュメント生成が完全自動化する時代がやってきた！**

## 具体的にどうやったか

では実際にどうやってドキュメント作成を完全自動化したか，具体的な手順の説明です．

まずは今回のプログラムのディレクトリ構造

```
my_code
├── README.md
├── docs
├── src
├── requirements.txt
├── setup.py
└── tests
```

### 1. Sphinxの導入

#### ライブラリのインストール

```bash
pip install sphinx sphinx sphinx-rtd-theme myst-parser
```

- sphinx-rtd-theme → ドキュメントの見た目をいい感じにする
- myst-parser → Sphinxはrstが標準なので，mdファイルでもドキュメントをかけるようにする

requirements.txtにも追記しておきます．

#### Sphinxの設定もろもろ

```bash
cd docs
sphinx-quickstart
> Separate source and build directories (y/n) [n]: y
> Project name: hoge
> Author name(s): fuga
> Project version []: 1.0.0
```

↓
docs配下にドキュメントの雛形が生成されます．

```
my_code
├── README.md
├── docs
│   ├── Makefile
│   ├── build
│   ├── make.bat
│   └── source
│       ├── _templates
│       ├── conf.py
│       └── index.md
├── src
├── requirements.txt
├── setup.py
└── tests

```

conf.pyを編集

```python
+ import sys
+ from pathlib import Path
+ 
+ root_path = Path(__file__).parent.parent.parent
+ sys.path.insert(0, str(root_path.absolute()))     # Sphinxがライブラリを探索できるようにパスを追加

# Configuration file for the Sphinx documentation builder.
#
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html

# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information

# extensionsを追加
+ extensions = [
+     "sphinx.ext.autodoc",
+     "sphinx.ext.viewcode",
+     "sphinx.ext.todo",
+     "sphinx.ext.napoleon",
+     "sphinx_rtd_theme",
+     "myst_parser",
+ ]


# テーマを変更
- html_theme = "alabaster"
+ html_theme = "sphinx_rtd_theme"


# Sphinxで扱うファイル形式を定義
+ source_suffix = {
+     ".rst": "restructuredtext",
+     ".txt": "markdown",
+     ".md": "markdown",
+ }
```

以上でSphinxの設定完了 $\ldots$！
ローカルでドキュメントを生成したい場合は，以下のようにすればOK．

```bash
sphinx-apidoc -f -o docs/source/ src
sphinx-build docs/source/ docs/build/ -a
```

### 2. GitHub Pagesの準備

基本的に公式に従っていけばOK → [GitHub Pages](https://docs.github.com/ja/pages/getting-started-with-github-pages/creating-a-github-pages-site)

この後の手順でGitHub Actionsのワークフローを設定しますが，そこではGitHub Pages用のブランチをgh-pagesとしています．  
なので，事前にブランチを作ってプッシュしておきます．

```bash
git branch gh-pages
git push origin gh-pages
```

これでGitHub Pagesでgh-pagesブランチを使ってドキュメントを公開できるので，GitHubから設定します．


### 3. GitHub Actionsの設定

GitHubにPushしたら，自動的にSphinxのビルドとGitHub Pagesへのドキュメント公開が実行されるようにワークフローを定義します．

まずはファイル作成

```
mkdir -p .github/workflows
touch .github/workflows/sphinx.yml
```

sphinx.ymlの中身です．コピペでOK

```yaml
name: Sphinx

on:
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    env:
      ACTIONS_ALLOW_UNSECURE_COMMANDS: true
    steps:
      - uses: actions/checkout@v1
      - run: pip install -r requirements.txt
      - name: Sphinx build
        run: sphinx-apidoc -f -o docs/source/ src/
      - name: Make HTML
        run: sphinx-build docs/source/ docs/build/ -a
      - name: Deploy
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: docs/build/
```

編集が終わったらGitHubにPushします．

これで，コードをGitHubにPushしたら，docstringに基づいてSphinxが自動でドキュメントを作成→GitHub Pagesで公開までしてくれるようになりました．

### 4. Waiting for GitHub Copilot!

ここまででほぼ終わったようなものですが，**あとはコードを書いてひと段落するたびに `/doc` でdocstringを自動生成するだけです！**  
あとは何もせずともGitHubのリポジトリにPushした時点で自動的にプログラムのドキュメントが生成されます！  
もちろん，Get Startedのような独自のドキュメントを含めることも可能！

GitHub Copilotが最後のピースを埋めてくれることによって，コードを書く作業とドキュメントを書く作業が完全に一体化しました．  
これでもうドキュメントに悩まずに済む．．．
イノベーションというものの有難みを改めて実感した瞬間でした．．．

参考までに．こんなドキュメントができます.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154356/77dc3bc5-a1ad-450b-bf11-e8be0702ed0f.png)