diff --git a/readthedocs/projects/models.py b/readthedocs/projects/models.py index dada277f9ed..17e26731ca6 100644 --- a/readthedocs/projects/models.py +++ b/readthedocs/projects/models.py @@ -1068,15 +1068,21 @@ def update_stable_version(self): Return ``None`` if no update was made or if there is no version on the project that can be considered stable. """ + + # return immediately if the current stable is managed by the user and + # not automatically by Read the Docs (``machine=False``) + current_stable = self.get_stable_version() + if current_stable and not current_stable.machine: + return None + versions = self.versions(manager=INTERNAL).all() new_stable = determine_stable_version(versions) if new_stable: - current_stable = self.get_stable_version() if current_stable: identifier_updated = ( new_stable.identifier != current_stable.identifier ) - if identifier_updated and current_stable.machine: + if identifier_updated: log.info( 'Update stable version: %(project)s:%(version)s', { diff --git a/readthedocs/rtd_tests/tests/test_project.py b/readthedocs/rtd_tests/tests/test_project.py index 98fe04c0702..31294b99e7b 100644 --- a/readthedocs/rtd_tests/tests/test_project.py +++ b/readthedocs/rtd_tests/tests/test_project.py @@ -17,6 +17,7 @@ LATEST, EXTERNAL, ) +from readthedocs.builds.constants import TAG from readthedocs.builds.models import Build, Version from readthedocs.oauth.services import GitHubService, GitLabService from readthedocs.projects.constants import GITHUB_BRAND, GITLAB_BRAND @@ -184,6 +185,45 @@ def test_update_stable_version_excludes_external_versions(self): # Test that External Version is not considered for stable. self.assertEqual(self.pip.update_stable_version(), None) + def test_update_stable_version_machine_false(self): + # Initial stable version from fixture + self.assertEqual(self.pip.update_stable_version().slug, '0.8.1') + + # None, when there is no stable to promote + self.assertEqual(self.pip.update_stable_version(), None) + + get( + Version, + identifier='9.0', + verbose_name='9.0', + slug='9.0', + type=TAG, + project=self.pip, + active=True, + ) + # New stable now is the newly created version + self.assertEqual(self.pip.update_stable_version().slug, '9.0') + + # Make stable version machine=False + stable = self.pip.get_stable_version() + stable.machine = False + stable.save() + + get( + Version, + identifier='10.0', + verbose_name='10.0', + slug='10.0', + type=TAG, + project=self.pip, + active=True, + ) + # None, since the stable version is marked as machine=False and Read + # the Docs does not have control over it + with patch('readthedocs.projects.models.determine_stable_version') as m: + self.assertEqual(self.pip.update_stable_version(), None) + m.assert_not_called() + def test_has_good_build_excludes_external_versions(self): # Delete all versions excluding External Versions. self.pip.versions.exclude(type=EXTERNAL).delete()