Repository: readthedocs/readthedocs.org

Issue:
Warn or Fail build if there is no `index.html` generated
Docs look broken when there isn't an index file to serve. We should probably be validating that an `index.html` or a `README.html` exists, which we will serve at the root of their docs. 



Discussion:
I think this is already implemented since when there is no `index.html` generated RTD generates one for us with a message which also points to the "Getting Started Guide" at #3447 

@ericholscher If that's the issue, can we close this one?
Believe this should still be the case. People can still have no `index.[md|rst]` and have a build pass. We're only generating them if there is no sphinx/mkdocs config found. 
Related issue #2483
  
For the record:
- The builds already fails if there is no index file (sphinx or empty project).
- If the user change the `master_doc` (other name than index), the build pass, but the docs at `/` gives 404.
This is also very easy to hit with mkdocs.
I don't think we have a way to indicate a `waning` in the build process. Also, mkdocs already handle the case where users have a README file, so, we can't just check for a missing index file, we could do the check in the generated docs.
Also, now sphinx-quickstart suggest an index file by default, which can help to have fewer users without an index file.
Checking for `index.html` after build instead of at build time (checking for `.md` or `.rst`) is good. I just found an example where the `index.html` comes from an static `.html` file and we were creating an `index.md` that overrides the static file the user wanted. See https://github.com/readthedocs/readthedocs.org/pull/7305
Yea -- we should be able to figure this out via ImportedFile objects, and wouldn't be a hard feature to build I think 👍 
FYI, I was just bitten by this in https://github.com/executablebooks/sphinx-external-toc/issues/1#issuecomment-817374457
We did some work to start logging what are the projects where we are creating the `index.html` file automatically at https://github.com/readthedocs/readthedocs.org/pull/10471. After some weeks we will contact them telling we are removing this feature.

I'm assigning this issue to myself so I work on this in the next weeks.
We have some logs already at https://onenr.io/0LwGgpA0Yw6. It seems we have around ~114 projects (.org and .com combined)
We sent the email today 📧 🚀 

Resolving patch:
diff --git a/readthedocs/projects/tasks/builds.py b/readthedocs/projects/tasks/builds.py
--- a/readthedocs/projects/tasks/builds.py
+++ b/readthedocs/projects/tasks/builds.py
@@ -574,24 +574,13 @@ def get_valid_artifact_types(self):
 
             if artifact_type == "html":
                 index_html_filepath = os.path.join(artifact_directory, "index.html")
-                readme_html_filepath = os.path.join(artifact_directory, "README.html")
-                if not os.path.exists(index_html_filepath) and not os.path.exists(
-                    readme_html_filepath
-                ):
-                    log.warning(
+                if not os.path.exists(index_html_filepath):
+                    log.info(
                         "Failing the build. "
                         "HTML output does not contain an 'index.html' at its root directory.",
                         index_html=index_html_filepath,
-                        readme_html=readme_html_filepath,
                     )
-                    # TODO: uncomment this line to fail the build once we have
-                    # communicated with projects without an index.html or
-                    # README.html
-                    #
-                    # NOTE: we want to deprecate serving README.html as an
-                    # index.html file as well.
-                    #
-                    # raise BuildUserError(BuildUserError.BUILD_OUTPUT_HTML_NO_INDEX_FILE)
+                    raise BuildUserError(BuildUserError.BUILD_OUTPUT_HTML_NO_INDEX_FILE)
 
             if not os.path.exists(artifact_directory):
                 # There is no output directory.


Test patch:
diff --git a/readthedocs/projects/tests/test_build_tasks.py b/readthedocs/projects/tests/test_build_tasks.py
--- a/readthedocs/projects/tests/test_build_tasks.py
+++ b/readthedocs/projects/tests/test_build_tasks.py
@@ -294,6 +294,14 @@ def test_build_updates_documentation_type(self, load_yaml_config):
                 )
             ).touch()
 
+        # Create an "index.html" at root to avoid failing the builds
+        pathlib.Path(
+            os.path.join(
+                self.project.artifact_path(version=self.version.slug, type_="html"),
+                "index.html",
+            )
+        ).touch()
+
         self._trigger_update_docs_task()
 
         # Update version state
@@ -438,6 +446,14 @@ def test_successful_build(
                 )
             ).touch()
 
+        # Create an "index.html" at root to avoid failing the builds
+        pathlib.Path(
+            os.path.join(
+                self.project.artifact_path(version=self.version.slug, type_="html"),
+                "index.html",
+            )
+        ).touch()
+
         self._trigger_update_docs_task()
 
         # It has to be called twice, ``before_start`` and ``after_return``