diff --git a/common b/common index 47b80254952..76244d215e1 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 47b8025495253fb6c6a56c6b259fd07a1e930771 +Subproject commit 76244d215e1640f1b8816794948ae2b033c2b2e6 diff --git a/readthedocs/doc_builder/director.py b/readthedocs/doc_builder/director.py index be45748ee5c..11bfebb65f9 100644 --- a/readthedocs/doc_builder/director.py +++ b/readthedocs/doc_builder/director.py @@ -240,6 +240,12 @@ def checkout(self): self.data.build["config"] = self.data.config.as_dict() self.data.build["readthedocs_yaml_path"] = custom_config_file + # Raise a build error if the project is not using a config file or using v1 + if self.data.project.has_feature( + Feature.NO_CONFIG_FILE_DEPRECATED + ) and self.data.config.version not in ("2", 2): + raise BuildUserError(BuildUserError.NO_CONFIG_FILE_DEPRECATED) + if self.vcs_repository.supports_submodules: self.vcs_repository.update_submodules(self.data.config) diff --git a/readthedocs/doc_builder/exceptions.py b/readthedocs/doc_builder/exceptions.py index 02ac48b3aa0..fb239ce127d 100644 --- a/readthedocs/doc_builder/exceptions.py +++ b/readthedocs/doc_builder/exceptions.py @@ -57,6 +57,11 @@ class BuildUserError(BuildBaseException): "Ensure your project is configured to use the output path " "'$READTHEDOCS_OUTPUT/html' instead." ) + NO_CONFIG_FILE_DEPRECATED = gettext_noop( + "The configuration file required to build documentation is missing from your project. " + "Add a configuration file to your project to make it build successfully. " + "Read more at https://docs.readthedocs.io/en/stable/config-file/v2.html" + ) class BuildUserSkip(BuildUserError): diff --git a/readthedocs/projects/models.py b/readthedocs/projects/models.py index 55d9371cf59..4d74f6b45ec 100644 --- a/readthedocs/projects/models.py +++ b/readthedocs/projects/models.py @@ -107,7 +107,7 @@ class ProjectRelationship(models.Model): def __str__(self): return '{} -> {}'.format(self.parent, self.child) - def save(self, *args, **kwargs): # pylint: disable=arguments-differ + def save(self, *args, **kwargs): if not self.alias: self.alias = self.child.slug super().save(*args, **kwargs) @@ -544,12 +544,14 @@ class Meta: def __str__(self): return self.name - def save(self, *args, **kwargs): # pylint: disable=arguments-differ + def save(self, *args, **kwargs): if not self.slug: # Subdomains can't have underscores in them. self.slug = slugify(self.name) if not self.slug: - raise Exception(_('Model must have slug')) + raise Exception( # pylint: disable=broad-exception-raised + _("Model must have slug") + ) super().save(*args, **kwargs) try: @@ -567,7 +569,7 @@ def save(self, *args, **kwargs): # pylint: disable=arguments-differ ) self.versions.filter(slug=LATEST).update(identifier=self.default_branch) - def delete(self, *args, **kwargs): # pylint: disable=arguments-differ + def delete(self, *args, **kwargs): from readthedocs.projects.tasks.utils import clean_project_resources # Remove extra resources @@ -1747,7 +1749,7 @@ class Domain(TimeStampedModel): canonical = models.BooleanField( default=False, help_text=_( - "This domain is the primary one where the documentation is " "served from", + "This domain is the primary one where the documentation is served from", ), ) https = models.BooleanField( @@ -1830,7 +1832,7 @@ def restart_validation_process(self): self.validation_process_start = timezone.now() self.save() - def save(self, *args, **kwargs): # pylint: disable=arguments-differ + def save(self, *args, **kwargs): parsed = urlparse(self.domain) if parsed.scheme or parsed.netloc: self.domain = parsed.netloc @@ -1949,6 +1951,7 @@ def add_features(sender, **kwargs): DONT_CREATE_INDEX = "dont_create_index" USE_RCLONE = "use_rclone" HOSTING_INTEGRATIONS = "hosting_integrations" + NO_CONFIG_FILE_DEPRECATED = "no_config_file" FEATURES = ( (ALLOW_DEPRECATED_WEBHOOKS, _("Webhook: Allow deprecated webhook views")), @@ -2139,6 +2142,10 @@ def add_features(sender, **kwargs): "Proxito: Inject 'readthedocs-client.js' as