From c45e8c7f993144c7f4ed1ceca429c04f5a97db7e Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Mon, 24 Feb 2020 17:31:30 +0100 Subject: [PATCH 1/4] Skip promoting new stable if current stable is not `machine=True` When the "stable" is managed by the user (because they have a `origin/stable` branch, for example) we do not need to calculate which would be the version to be promoted as stable. So, we return immediately (without doing any computation) if the current stable is not managed by Read the Docs. --- readthedocs/projects/models.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/readthedocs/projects/models.py b/readthedocs/projects/models.py index a6a66ea81bc..ced2b2efcf9 100644 --- a/readthedocs/projects/models.py +++ b/readthedocs/projects/models.py @@ -1022,15 +1022,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 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', { From 8f5ba9caee5be4b50dc7285549b320a76adc0b54 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Tue, 16 Jun 2020 12:24:19 +0200 Subject: [PATCH 2/4] Check the currently stable exists --- readthedocs/projects/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readthedocs/projects/models.py b/readthedocs/projects/models.py index ced2b2efcf9..c69ed0b6baf 100644 --- a/readthedocs/projects/models.py +++ b/readthedocs/projects/models.py @@ -1026,7 +1026,7 @@ def update_stable_version(self): # 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 not current_stable.machine: + if current_stable and not current_stable.machine: return None versions = self.versions(manager=INTERNAL).all() From 7e3dd0432e63767f42cd9026ab93f2c4feaa5f32 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Tue, 16 Jun 2020 12:37:47 +0200 Subject: [PATCH 3/4] Test case promote stable version with machine=False --- readthedocs/rtd_tests/tests/test_project.py | 38 +++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/readthedocs/rtd_tests/tests/test_project.py b/readthedocs/rtd_tests/tests/test_project.py index 98fe04c0702..b24230ddc09 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,43 @@ 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 + self.assertEqual(self.pip.update_stable_version(), None) + def test_has_good_build_excludes_external_versions(self): # Delete all versions excluding External Versions. self.pip.versions.exclude(type=EXTERNAL).delete() From 5dfcd377dc504d2c8cf984d6988735b825c03edf Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Tue, 16 Jun 2020 12:44:18 +0200 Subject: [PATCH 4/4] Double check that we are not calling determine_stable_version --- readthedocs/rtd_tests/tests/test_project.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/readthedocs/rtd_tests/tests/test_project.py b/readthedocs/rtd_tests/tests/test_project.py index b24230ddc09..31294b99e7b 100644 --- a/readthedocs/rtd_tests/tests/test_project.py +++ b/readthedocs/rtd_tests/tests/test_project.py @@ -220,7 +220,9 @@ def test_update_stable_version_machine_false(self): ) # None, since the stable version is marked as machine=False and Read # the Docs does not have control over it - self.assertEqual(self.pip.update_stable_version(), None) + 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.