マスターブランチのマージと同時にドキュメントをS3に公開する。

# 問題点として
Python のソースコードからドキュメントを生成している場合、Master が更新された後に手動でドキュメントを生成、配置するのは手間がかかり、更新忘れも発生します。

# 解決する手段として
GitHub で管理しているリポジトリにおいて、マスターブランチがマージされた際、GitHubとCircle CIのintegrationにより、自動でドキュメントがビルドされ、AWS S3に配置されるようにします。

## 使用するツール、サービス
次のツール、サービスを使用します。

- Sphinx: ドキュメント自動生成
- GitHub: バージョン管理
- Circle CI: 継続的インテグレーション(デリバリー)サービス
- AWS CLIツール: AWSコマンドラインインターフェイス

## 前提として

- Python3.6を使用します。
- GitHubのレポジトリとCircle CIは関連付けされているものとします。
- 配置先のS3のバケットは既に存在し、適切な権限を持つIAMが設定がされているものとします。


# プロジェクトの構成
ここでは架空のPythonモジュール **"my_tools"** を開発している仮のプロジェクトを使用します。

```tree
.
|____docs
|____my_tools
| |______init__.py
| |_____adder.py
```

docsにはSphinx関連のファイルが入ります。
モジュール **my_tools** には、加算器adder.pyが入っています。

```python:adder.py
# -*- coding: utf-8 -*-
"""加算に関するユーティリティーが入っているモジュールです."""


class Adder:
    """加算器."""

    def __init__(self) -> None:
        """初期化."""
        pass

    def add(self, x: int, y: int) -> int:
        """加算を実行するメソッド.

        :param x: 整数x
        :param y: 整数y
        :return: x と y の演算結果
        """
        return x + y
```

# Sphinx

## Sphinxプロジェクトの作成
docs以下にドキュメントを生成するためのSphinxプロジェクトを作成します。
なお、この記事ではSphinxの詳細には触れません。最小限の構成を扱います。

```bash
$ cd docs
$ sphinx-quickstart
```

いくつか質問が表示されます。最低限の設定をしておきます。

- Project name
- Author name(s)
- Project version
- autodoc

autodoc には **y** を入力してください。

その他は Enter 押下でデフォルト設定とします。

## 設定ファイルの編集と追加
### index.rst
生成された index.rst の toctree に今回のモジュール my_tools を加えます。

```rst:docs/my_tools
.. toctree::
   :maxdepth: 2
   :caption: Contents:

   my_tools
```

### my_tools.rst
今回追加したモジュールのドキュメントをビルドするための .rst を**新規作成**します。

```rst:docs/my_tools
my\_tools パッケージ
====================

..
  Submodules
  ----------

my\_tools\.adder モジュール
-------------------------------------------

.. automodule:: my_tools.adder
    :members:
    :undoc-members:
    :show-inheritance:
```

### conf.py
コードを追加、編集します。

```python:conf.py

import os
import sys

sys.path.insert(0, os.path.abspath('../'))

# 組込み Sphinx 拡張機能
extensions = ['sphinx.ext.autodoc',
              'sphinx_autodoc_typehints',
              'sphinx.ext.todo',
              'sphinx.ext.viewcode']
```

## Sphinxプロジェクトのビルド

プロジェクトのルートディレクトリから

```bash
$ sphinx-build -a ./docs/ ./docs/html/
```

もしくは docs から

```bash
$ make html
```

これにより `docs/html/index.html` にドキュメントのトップページが生成されました。

![shot2_edited.png](https://qiita-image-store.s3.amazonaws.com/0/242203/97c7e7d7-765b-49a4-4af8-fe4d04cf2a87.png)



# Circle CI
Circle CI ver.2 の設定になります。

## 設定ファイル
設定ファイル .circleci/config.yml にドキュメント生成とS3に配置するjobを追加します。

```yml:cofig.yml
version: 2
jobs:
  build:
    docker:
      - image: python:3

    steps:
      - checkout
      - add_ssh_keys:
          fingerprints:
            - "57:f1:**:**:**:**:**:**:**:**:**:**:**:**:**:**"
            - "00:5e:**:**:**:**:**:**:**:**:**:**:**:**:**:**"
      - run:
          name: Build documents
          command: |
            sphinx-build -a ./docs/ ./docs/html/;
            tar cfvz html.tar.gz docs/html/

      - persist_to_workspace:
          root: .
          paths:
            - docs/html/*

  deploy_doc:
    machine:
      enabled: true

    steps:
      - attach_workspace:
          at: html
      - run:
          name: Upload documents
          command: |
            pip install -U awscli;
            aws s3 sync ./html/* s3://<my-bucket>/<my-key>/

workflows:
  version: 2

  build_deploy:
    jobs:
      - build
      - deploy_doc:
          requires:
            - build
          filters:
            branches:
              only: master
```

## workflows
Circle CI 2.0ではworkflowsを起点としてjobが実行されます。
ここでのjobは次の2つになります。

- ドキュメントの生成 (build)
- ドキュメントの配置 (deploy_doc)

なおドキュメントの配置jobは以下の条件を満たす場合に実行されます。

- ビルドが済んでいること
- マスターブランチであること


## ドキュメントの生成
build job の主要部分を抜粋します。

```yml
      - run:
          name: Build documents
          command: |
            sphinx-build -a ./docs/ ./docs/html/;

      - persist_to_workspace:
          root: .
          paths:
            - docs/html/*
```

sphinx-build でドキュメントを生成しています。
persist_to_workspaceは次のjobに引き継ぐディレクトリを記述しています。
※本来ならコード自体のビルドやテストが行われるところですが、ここでは説明のため省略しています。

## ドキュメントの配置
deploy_doc job の主要部分を抜粋しています。

```yml
  deploy_doc:
    machine:
      enabled: true

    steps:
      - attach_workspace:
          at: html
      - run:
          name: Upload documents
          command: |
            pip install -U awscli;
            aws s3 sync ./html/* s3://<my-bucket>/<my-key>/
```

- machineはデフォルトのVMを起動します。
- attach_workspaceは前jobのpresist_to_workspaceのディレクトリを使用するための特別なステップです。
- run で AWS CLI を使用し、S3 に生成したドキュメントを配置しています。


# 実行
マスターブランチにマージされた際、ドキュメントのビルドと配置が実行されます。


# 結果として
プルリクエストされた作業ブランチのレビューが済み、マスターブランチにマージされた際、自動的にdocstringsからドキュメントが生成され、S3で公開されるようになりました。


# サンプルスクリプト
GitHubの[こちらのリポジトリ](https://github.com/smn-ailab/style-autodoc-qiita)に公開しています。


# 参考元
[論文執筆を支える継続的インテグレーション: Git から Amazon S3 まで](https://blog.ymyzk.com/2017/12/ci-for-writing-papers/?utm_content=buffer285b4&utm_medium=social&utm_source=twitter.com&utm_campaign=buffer)