chamaoskurumi
chamaoskurumi

Reputation: 2503

GitHub sphinx-action can't find target Python modules and builds an empty sphinx doc

Tl;dr

When I create a sphinx doc locally it builds as expected, but the GitHub Sphinx Build Action creates an empty doc. It must have to do with the sphinx-action not finding the target python modules as specified in conf.py.

Any ideas to configure the sphinx-action or conf.py correctly?

Expected Sphinx Doc

When I build the sphinx doc locally on my machine via cd docs/ && make html the resulting html looks as expected

expected_sphinx_doc

Empty Sphinx Doc generated by sphinx-action

My .github/workflows/sphinx_action.yml includes

    steps:
    # Checkout repo
    - uses: actions/checkout@v2
    # Build sphinx doc
    - uses: ammaraskar/sphinx-action@master
      with:
        docs-folder: "docs/"

and generates an empty skeleton of a Sphinx Doc

output_shpinx_doc

Project Setup

Project Structure
.
├── docs
│   ├── conf.py
│   ├── index.rst
│   ├── make.bat
│   ├── Makefile
│   ├── requirements.txt
│   └── sync.log
├── .github
│   └── workflows
│       └── sphinx_action.yml
├── .gitignore
├── mypackage
│   ├── __init__.py
│   ├── subfolder
│   │   ├── __init__.py
│   │   └── subclass.py
│   └── superclass.py
├── Pipfile
├── Pipfile.lock
└── README.md

conf.py Configuration

My docs/conf.py looks as follows. (Mind that I added three entries to the sys.path manually in order to make Sphinx find all python modules.)

# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html


# -- Path setup --------------------------------------------------------------

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import sys
from m2r import MdInclude

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


# -- Project information -----------------------------------------------------

project = 'MyPackage'
copyright = ''
author = 'Testuser'


# -- General configuration ---------------------------------------------------

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = ['sphinx.ext.autodoc',
              'recommonmark'
]

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

#
source_suffix = ['.rst', '.md']

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']

# document the init of a class, too
autoclass_content = 'both'

# -- Options for HTML output -------------------------------------------------

# The theme to use for HTML and HTML Help pages.  See the documentation for
# a list of builtin themes.
#
html_theme = 'nature'

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']

# from m2r to make `mdinclude` work
def setup(app):
    config = {
        # 'url_resolver': lambda url: github_doc_root + url,
        'auto_toc_tree_section': 'Contents',
        'enable_eval_rst': True,
    }

    # from m2r to make `mdinclude` work
    app.add_config_value('no_underscore_emphasis', False, 'env')
    app.add_config_value('m2r_parse_relative_links', False, 'env')
    app.add_config_value('m2r_anonymous_references', False, 'env')
    app.add_config_value('m2r_disable_inline_math', False, 'env')
    app.add_directive('mdinclude', MdInclude)

Pipfile

[[source]]
verify_ssl = true
url = "https://pypi.org/simple"
name = "pypi"

[dev-packages]

[packages]
m2r = {index = "pypi",version = "==0.2.1"}
pandas = {index = "pypi",version = "==1.0.3"}
sphinx = {index = "pypi",version = "==3.1.0"}
recommonmark = {index = "pypi",version = "==0.6.0"}
mypackage = "*"

[requires]
python_version = "3.8"

Note: I posted this question also as an issue in the GitHub repo of the sphinx-action.

Upvotes: 3

Views: 1427

Answers (2)

sytech
sytech

Reputation: 41061

Build your path inserts deterministically. For example, using __file__:

_HERE = os.path.dirname(__file__)
_ROOT_DIR = os.path.abspath(os.path.join(_HERE, '..'))
_PACKAGE_DIR = os.path.abspath(os.path.join(_HERE, '../mypackage'))
_SUBPACKAGE_DIR = os.path.abspath(os.path.join(_HERE, '../mypackage/subfolder'))

sys.path.insert(0, _ROOT_DIR)
sys.path.insert(0, _PACKAGE_DIR)
sys.path.insert(0, _SUBPACKAGE_DIR)

# test the path; not strictly needed
import mypackage

This way, the resolved locations are always the same, regardless of the present working directory.

Upvotes: 0

Ingmar Schoegl
Ingmar Schoegl

Reputation: 21

I had the exact same issue. Simply putting

import mypackage

in conf.py fixed things for me.

Edit: mypackage above refers to the actual package name and will be specific. In order for this to work, you need to make sure that the package is actually installed (e.g. using setuptools). Below are code snippets for GitHub actions

    - uses: ammaraskar/sphinx-action@master
      with:
        #pre-build-command: "apt-get update -y && apt-get install -y pandoc"
        docs-folder: "docs/"

and my requirements.txt file (in docs)

sphinx>=3.3
sphinx-autodoc-typehints
sphinx-argparse
-e .

I left the commented-out pre-build-command as you can use it to pip install -e . also. I don't think the sphinx version matters.

Upvotes: 2

Related Questions