Edited at

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

More than 1 year has passed since last update.


問題点として

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" を開発している仮のプロジェクトを使用します。

.

|____docs
|____my_tools
| |______init__.py
| |_____adder.py

docsにはSphinx関連のファイルが入ります。

モジュール my_tools には、加算器adder.pyが入っています。


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の詳細には触れません。最小限の構成を扱います。

$ cd docs

$ sphinx-quickstart

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


  • Project name

  • Author name(s)

  • Project version

  • autodoc

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

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


設定ファイルの編集と追加


index.rst

生成された index.rst の toctree に今回のモジュール my_tools を加えます。


docs/my_tools

.. toctree::

:maxdepth: 2
:caption: Contents:

my_tools



my_tools.rst

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


docs/my_tools

my\_tools パッケージ

====================

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

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

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



conf.py

コードを追加、編集します。


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プロジェクトのビルド

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

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

もしくは docs から

$ make html

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

shot2_edited.png


Circle CI

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


設定ファイル

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


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 の主要部分を抜粋します。

      - 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 の主要部分を抜粋しています。

  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のこちらのリポジトリに公開しています。


参考元

論文執筆を支える継続的インテグレーション: Git から Amazon S3 まで