homebrew-file などのドキュメントを Read the Docs というサービスを使って公開しているのですが、 そこでドキュメントのビルドが1週間ほど前から失敗するようになっていたので それを直した話。
Read the Docs
Read the Docs はSphinxというPython製のドキュメントビルダーを使って ドキュメントを作成してWebに公開してくれるサービスです。
GitHubと連携して、GitHubと連携して、GitHubのレポジトリにドキュメントのソースファイルを入れておくと、 push時に自動的にレポジトリを取得してドキュメントをビルドして公開してくれます。
もともとSphinxはPythonのドキュメンテーション用に作られたもので また、Read the Docsも サービスがDjangoで作られたりしていて、 PythonのモジュールのドキュメントとかがよくSphinxでビルドしたものがあって、 Read the Docsで公開されているものも多くあります。
SphixはreStructuredTextというマークアップを利用しますが、 Markdownのビルドにも一応対応しています。
GitHubで公開したツールとかに対して、GitHubのReadmeとは一味違った 形でドキュメントを付けるにはお手軽で良い感じに出来るかと思います。
基本的には無料で、表示される広告を消したい場合などは有料で消すこともできます。
起こった問題
んな感じのエラーを出していました:
Running Sphinx v1.8.5
loading translations [en]... done
making output directory...
building [mo]: targets for 0 po files that are out of date
building [html]: targets for 10 source files that are out of date
updating environment: 10 added, 0 changed, 0 removed
reading sources... [ 10%] brew-wrap
reading sources... [ 20%] completion
Traceback (most recent call last):
File "/home/docs/checkouts/readthedocs.org/user_builds/homebrew-file/envs/stable/lib/python3.7/site-packages/sphinx/cmd/build.py", line 304, in build_main
app.build(args.force_all, filenames)
File "/home/docs/checkouts/readthedocs.org/user_builds/homebrew-file/envs/stable/lib/python3.7/site-packages/sphinx/application.py", line 341, in build
self.builder.build_update()
File "/home/docs/checkouts/readthedocs.org/user_builds/homebrew-file/envs/stable/lib/python3.7/site-packages/sphinx/builders/__init__.py", line 347, in build_update
len(to_build))
File "/home/docs/checkouts/readthedocs.org/user_builds/homebrew-file/envs/stable/lib/python3.7/site-packages/sphinx/builders/__init__.py", line 360, in build
updated_docnames = set(self.read())
File "/home/docs/checkouts/readthedocs.org/user_builds/homebrew-file/envs/stable/lib/python3.7/site-packages/sphinx/builders/__init__.py", line 468, in read
self._read_serial(docnames)
File "/home/docs/checkouts/readthedocs.org/user_builds/homebrew-file/envs/stable/lib/python3.7/site-packages/sphinx/builders/__init__.py", line 490, in _read_serial
self.read_doc(docname)
File "/home/docs/checkouts/readthedocs.org/user_builds/homebrew-file/envs/stable/lib/python3.7/site-packages/sphinx/builders/__init__.py", line 534, in read_doc
doctree = read_doc(self.app, self.env, self.env.doc2path(docname))
File "/home/docs/checkouts/readthedocs.org/user_builds/homebrew-file/envs/stable/lib/python3.7/site-packages/sphinx/io.py", line 318, in read_doc
pub.publish()
File "/home/docs/checkouts/readthedocs.org/user_builds/homebrew-file/envs/stable/lib/python3.7/site-packages/docutils/core.py", line 219, in publish
self.apply_transforms()
File "/home/docs/checkouts/readthedocs.org/user_builds/homebrew-file/envs/stable/lib/python3.7/site-packages/docutils/core.py", line 200, in apply_transforms
self.document.transformer.apply_transforms()
File "/home/docs/checkouts/readthedocs.org/user_builds/homebrew-file/envs/stable/lib/python3.7/site-packages/sphinx/transforms/__init__.py", line 90, in apply_transforms
Transformer.apply_transforms(self)
File "/home/docs/checkouts/readthedocs.org/user_builds/homebrew-file/envs/stable/lib/python3.7/site-packages/docutils/transforms/__init__.py", line 171, in apply_transforms
transform.apply(**kwargs)
File "/home/docs/checkouts/readthedocs.org/user_builds/homebrew-file/envs/stable/lib/python3.7/site-packages/sphinx/transforms/__init__.py", line 245, in apply
apply_source_workaround(n)
File "/home/docs/checkouts/readthedocs.org/user_builds/homebrew-file/envs/stable/lib/python3.7/site-packages/sphinx/util/nodes.py", line 94, in apply_source_workaround
for classifier in reversed(node.parent.traverse(nodes.classifier)):
TypeError: 'generator' object is not reversible
Exception occurred:
File "/home/docs/checkouts/readthedocs.org/user_builds/homebrew-file/envs/stable/lib/python3.7/site-packages/sphinx/util/nodes.py", line 94, in apply_source_workaround
for classifier in reversed(node.parent.traverse(nodes.classifier)):
TypeError: 'generator' object is not reversible
The full traceback has been saved in /tmp/sphinx-err-fwowl5pk.log, if you want to report the issue to the developers.
Please also report this if it was a user error, so that a better error message can be provided next time.
A bug report can be filed in the tracker at <https://github.com/sphinx-doc/sphinx/issues>. Thanks!
ドキュメントのソースがおかしいのかな、と思って手元でビルドしてみると特に問題は出ず。
で、ちょっと調べて見ると、どうやら docutils というモジュールの0.18というバージョンが出て、 Sphinxがその変更に対応できていない、とのこと。
“TypeError: ‘generator’ object is not reversible” during RTD builds · Issue #973 · ivadomed/ivadomed
2021年10月26日にdocutilsの0.18がリリースされてるのでそのあたりから問題が出ていたようです。
一方でSphinx最新の4.2ではdocutilsへの依存性を<0.18以下というrequirementsにすることで 一旦回避しています。
Update Sphinx to work with docutils-0.18.x · Issue #9777 · sphinx-doc/sphinx
なので手元でSphinxを(pip install sphinx
で)入れて試したときは問題なかったようです。
ただ、Read the Docsではsphinxのバージョンを<2で要求していて、 これだとdocutils>=0.11で要求しているので最新の物が入り問題が起きていた模様。
したがってとりあえずはビルド環境でdocutils-0.18より前のバージョンを使う かsphinxの新しいバージョンを入れるようにすれば問題が解決できそうです。
Read the Docsの設定もsphinx-4.2.0を入れる様に変更された(される?)みたいですが、 現状ではまだ実際に実行するとsphinx<2のバージョンで実行されています。
readthedocs.org/pip.txt at master · readthedocs/readthedocs.org
Read the Docsの環境設定
Read the Docsに関してはレポジトリを連携するだけで特に細かい設定をしてませんでしたが、 GitHubのレポジトリに設定ファイルを置くことでビルド環境を設定することができます。
まずは以下の様な.readthedocs.yamlというファイルをレポジトリのトップディレクトリに用意します。
1 2 3 4 5 6 7 8 9 10 11 |
|
Pythonのバージョンは現状では3.9はまだ使えないようです。 3.7にしてあるのはドキュメントとかでそうなっていたから、というだけで 3.8は使おうと思えば使えます。
docs/conf.pyはsphinxでsphinx-quickstart
とかで初期化していれば
最初にできているかと思います。
この指定はデフォルトでこの値なので書かなくても同じです。
一方でPythonの設定は、Pythonのバージョンはデフォルトで3.7ですが、 インストールに関しては指定しないとRead the Docsのデフォルトのパッケージを取得するだけで、 docs/requirements.txtがあったとしてもその中身は読まれません。
上のドキュメントにもありますが、requirements.txtを使って モジュールのバージョン指定などをきちんといておきなさい、と。
というわけで、以下を用意します。
1
|
|
これでsphinx-4以上のものが入ります。
もしくは、
1
|
|
でもOK。せっかくだからSphinxの新しいものを使おうかと、上の方を使います。
これらをadd
してcommit
してpush
すればOK。
requirements.txtを使うようにすると、ビルドのところで、 下の絵の様に7番目のタスクとしてrequirements.txtを使ったインストールが追加されます。
その上の部分でRead the Docsデフォルトのパッケージが追加されていますが、そこを見ると
Collecting sphinx<2
Downloading Sphinx-1.8.5-py2.py3-none-any.whl (3.1 MB)
...
Collecting docutils>=0.11
Downloading docutils-0.18-py2.py3-none-any.whl (569 kB)
みたいな感じでsphinxのバージョン2未満と、docutilsの最新の0.18が入れられてる事がわかります。
これらを上書きする形で次のタスクで必要なものが入っていればビルドが成功します。
Read the Docsの対応などを見る感じ、何もしなくてもそのうち ビルドがうまく行くようにもなるとは思いますが、 もし現在ビルドの失敗が気になるようならこれで直すことができます。