Skip to content

Commit

Permalink
Build: don't run default steps if no sphinx or mkdocs
Browse files Browse the repository at this point in the history
This PR modifies the build to not run default commands when the user doesn't
specify `sphinx` or `mkdocs` configs in the YAML file.

This allows to use the following YAML file to build with Docusaurus, for
example:

```yaml
version: 2

build:
  os: ubuntu-24.04
  tools:
    nodejs: "22"
  jobs:
    install:
      - cd docs/ && npm install
    build:
      html:
        - cd docs/ && npm run build
    post_build:
      - mkdir --parents $READTHEDOCS_OUTPUT/html/
      - cp --recursive docs/build/* $READTHEDOCS_OUTPUT/html/
```

This is the structure I've been wanting to have to allow any type of doctool to
work in our platform following the `build.jobs` pattern.

The code deployed in production doesn't allow this because it runs automatically
`create_environment`, `install_core_dependencies` and `install_requirements`
even if the project is not using Python --which is incorrect. It fails with the
generic error: " Unknown problem. There was a problem with Read the Docs while
building your documentation"

- https://app.readthedocs.org/projects/test-builds/builds/26425680/
- https://read-the-docs.sentry.io/issues/4458662274/

This PR detects if the user is defining `sphinx` or `mkdocs` and if it's not, it
doesn't run those jobs and leave the user to handle the build workflow
completely.

* Related #11216
* Related #11551
  • Loading branch information
humitos committed Nov 28, 2024
1 parent d95c58b commit 9a98a7a
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 8 deletions.
9 changes: 8 additions & 1 deletion readthedocs/config/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -828,7 +828,14 @@ def doctype(self):

if self.mkdocs:
return "mkdocs"
return self.sphinx.builder

# NOTE: we need to use "source config" here because `_config` is
# auto-populated with Sphinx if no `sphinx` and no `mkdocs` keys are
# declared.
if self.source_config.get("sphinx"):
return self.sphinx.builder

return GENERIC

@property
def submodules(self):
Expand Down
25 changes: 18 additions & 7 deletions readthedocs/doc_builder/director.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ def setup_vcs(self):
# self.run_build_job("pre_checkout")
self.checkout()

self.run_default_commands = self.is_type_mkdocs() or self.is_type_sphinx()

self.run_build_job("post_checkout")

commit = self.data.build_commit or self.vcs_repository.commit
Expand Down Expand Up @@ -309,23 +311,28 @@ def create_environment(self):
if self.data.config.build.jobs.create_environment is not None:
self.run_build_job("create_environment")
return
self.language_environment.setup_base()

if self.run_default_commands or self.data.config.source_config.get("python"):
self.language_environment.setup_base()

# Install
def install(self):
if self.data.config.build.jobs.install is not None:
self.run_build_job("install")
return

self.language_environment.install_core_requirements()
self.language_environment.install_requirements()
if self.run_default_commands or self.data.config.source_config.get("python"):
self.language_environment.install_core_requirements()
self.language_environment.install_requirements()

# Build
def build_html(self):
if self.data.config.build.jobs.build.html is not None:
self.run_build_job("build.html")
return
return self.build_docs_class(self.data.config.doctype)

if self.run_default_commands:
return self.build_docs_class(self.data.config.doctype)

def build_pdf(self):
if "pdf" not in self.data.config.formats or self.data.version.type == EXTERNAL:
Expand All @@ -336,7 +343,7 @@ def build_pdf(self):
return

# Mkdocs has no pdf generation currently.
if self.is_type_sphinx():
if self.is_type_sphinx() and self.run_default_commands:
return self.build_docs_class("sphinx_pdf")

return False
Expand All @@ -353,7 +360,7 @@ def build_htmlzip(self):
return

# We don't generate a zip for mkdocs currently.
if self.is_type_sphinx():
if self.is_type_sphinx() and self.run_default_commands:
return self.build_docs_class("sphinx_singlehtmllocalmedia")
return False

Expand All @@ -366,7 +373,7 @@ def build_epub(self):
return

# Mkdocs has no epub generation currently.
if self.is_type_sphinx():
if self.is_type_sphinx() and self.run_default_commands:
return self.build_docs_class("sphinx_epub")
return False

Expand Down Expand Up @@ -744,6 +751,10 @@ def is_type_sphinx(self):
"""Is documentation type Sphinx."""
return "sphinx" in self.data.config.doctype

def is_type_mkdocs(self):
"""Is documentation type MkDocs."""
return "mkdocs" in self.data.config.doctype

def store_readthedocs_build_yaml(self):
# load YAML from user
yaml_path = os.path.join(
Expand Down

0 comments on commit 9a98a7a

Please sign in to comment.