Repository: readthedocs/readthedocs.org
Issue: Trigger build on default branch when saving a project

Currently when we save a project form (admin panel),
it triggers a build to latest

https://github.com/rtfd/readthedocs.org/blob/9874b866fea9696fa8495d7b3699f1bf1a3f923d/readthedocs/projects/forms.py#L69-L74

https://github.com/rtfd/readthedocs.org/blob/9874b866fea9696fa8495d7b3699f1bf1a3f923d/readthedocs/core/utils/__init__.py#L97-L98

Even if latest is deactivated, we should trigger a build to the default branch instead.

Changed files:
readthedocs/rtd_tests/tests/test_core_utils.py, readthedocs/core/utils/__init__.py

diff --git a/readthedocs/core/utils/__init__.py b/readthedocs/core/utils/__init__.py
index a52c4d1b9..817435869 100644
--- a/readthedocs/core/utils/__init__.py
+++ b/readthedocs/core/utils/__init__.py
@@ -16,7 +16,7 @@ from django.utils.safestring import SafeText, mark_safe
 from django.utils.text import slugify as slugify_base
 from celery import group, chord
 
-from readthedocs.builds.constants import LATEST, BUILD_STATE_TRIGGERED
+from readthedocs.builds.constants import BUILD_STATE_TRIGGERED
 from readthedocs.doc_builder.constants import DOCKER_LIMITS
 
 log = logging.getLogger(__name__)
@@ -73,7 +73,7 @@ def prepare_build(
     project has ``skip=True``, the build is not triggered.
 
     :param project: project's documentation to be built
-    :param version: version of the project to be built. Default: ``latest``
+    :param version: version of the project to be built. Default: ``project.get_default_version()``
     :param record: whether or not record the build in a new Build object
     :param force: build the HTML documentation even if the files haven't changed
     :param immutable: whether or not create an immutable Celery signature
@@ -95,7 +95,8 @@ def prepare_build(
         return (None, None)
 
     if not version:
-        version = project.versions.get(slug=LATEST)
+        default_version = project.get_default_version()
+        version = project.versions.get(slug=default_version)
 
     kwargs = {
         'version_pk': version.pk,
diff --git a/readthedocs/rtd_tests/tests/test_core_utils.py b/readthedocs/rtd_tests/tests/test_core_utils.py
index 4c7adfb23..d69dad3b2 100644
--- a/readthedocs/rtd_tests/tests/test_core_utils.py
+++ b/readthedocs/rtd_tests/tests/test_core_utils.py
@@ -14,6 +14,7 @@ from readthedocs.core.utils.general import wipe_version_via_slugs
 from readthedocs.projects.tasks import remove_dirs
 from readthedocs.core.utils import slugify, trigger_build
 from readthedocs.projects.models import Project
+from readthedocs.builds.constants import LATEST
 
 
 class CoreUtilTests(TestCase):
@@ -34,6 +35,61 @@ class CoreUtilTests(TestCase):
         self.assertFalse(update_docs_task.signature.called)
         self.assertFalse(update_docs_task.signature().apply_async.called)
 
+    @mock.patch('readthedocs.projects.tasks.update_docs_task')
+    def test_trigger_build_when_version_not_provided_default_version_exist(self, update_docs_task):
+        self.assertFalse(Version.objects.filter(slug='test-default-version').exists())
+
+        project_1 = get(Project)
+        version_1 = get(Version, project=project_1, slug='test-default-version', active=True)
+
+        project_1.default_version = 'test-default-version'
+        project_1.save()
+
+        default_version = project_1.get_default_version()
+        self.assertEqual(default_version, 'test-default-version')
+
+        trigger_build(project=project_1)
+        kwargs = {
+            'version_pk': version_1.pk,
+            'record': True,
+            'force': False,
+            'build_pk': mock.ANY,
+        }
+
+        update_docs_task.signature.assert_has_calls([
+            mock.call(
+                args=(project_1.pk,),
+                kwargs=kwargs,
+                options=mock.ANY,
+                immutable=True,
+            ),
+        ])
+    
+    @mock.patch('readthedocs.projects.tasks.update_docs_task')
+    def test_trigger_build_when_version_not_provided_default_version_doesnt_exist(self, update_docs_task):
+
+        trigger_build(project=self.project)
+        default_version = self.project.get_default_version()
+        version_ = self.project.versions.get(slug=default_version)
+
+        self.assertEqual(version_.slug, LATEST)
+
+        kwargs = {
+            'version_pk': version_.pk,
+            'record': True,
+            'force': False,
+            'build_pk': mock.ANY,
+        }
+
+        update_docs_task.signature.assert_has_calls([
+            mock.call(
+                args=(self.project.pk,),
+                kwargs=kwargs,
+                options=mock.ANY,
+                immutable=True,
+            ),
+        ])
+
     @mock.patch('readthedocs.projects.tasks.update_docs_task')
     def test_trigger_custom_queue(self, update_docs):
         """Use a custom queue when routing the task."""