From 124301ca9d1ec4807782e0ad7195288fc492e7c4 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Wed, 27 Apr 2022 12:16:28 +0200 Subject: [PATCH] Build: add a new "Cancelled" final state This is just a POC to show some of the work involved in #9100 --- media/javascript/build_updater.js | 11 +++---- readthedocs/builds/constants.py | 31 ++++++++++++------- readthedocs/core/utils/__init__.py | 3 +- readthedocs/projects/tasks/builds.py | 12 +++++-- .../templates/builds/build_detail.html | 2 +- 5 files changed, 36 insertions(+), 23 deletions(-) diff --git a/media/javascript/build_updater.js b/media/javascript/build_updater.js index 70d3c36bb75..44a5a80b7ad 100644 --- a/media/javascript/build_updater.js +++ b/media/javascript/build_updater.js @@ -30,7 +30,7 @@ var el = $(this.buildDiv + ' span#build-' + prop); if (prop == 'success') { - if (data.hasOwnProperty('state') && data['state'] != 'finished') { + if (data.hasOwnProperty('state') && data['state'] != 'finished') && data['state'] != 'cancelled' { val = "Not yet finished"; } else { @@ -41,7 +41,7 @@ if (prop == 'state') { val = val.charAt(0).toUpperCase() + val.slice(1); - if (val == 'Finished') { + if (val == 'Finished' || val == 'Cancelled') { _this.stopPolling(); } } @@ -55,7 +55,7 @@ BuildUpdater.prototype.getBuild = function() { _this = this; - + $.get(this.buildUrl, function(data) { _this.render(data); }); @@ -74,7 +74,7 @@ // If the build is already finished, or it isn't displayed on the page, // ignore it. - if (stateSpan.text() == 'Finished' || stateSpan.length === 0) { + if (stateSpan.text() == 'Finished' || stateSpan.text() == 'Cancelled' || stateSpan.length === 0) { return; } @@ -117,7 +117,7 @@ if (prop == 'state') { // Show the success value ("Passed" or "Failed") if the build // finished. Otherwise, show the state value. - if (val == 'Finished') { + if (val == 'Finished' || val == 'Cancelled') { val = data['success']; _this.stopPolling(); } else { @@ -134,4 +134,3 @@ }).call(this); - diff --git a/readthedocs/builds/constants.py b/readthedocs/builds/constants.py index a02d5b0d61b..3847289c509 100644 --- a/readthedocs/builds/constants.py +++ b/readthedocs/builds/constants.py @@ -3,20 +3,27 @@ from django.conf import settings from django.utils.translation import gettext_lazy as _ -BUILD_STATE_TRIGGERED = 'triggered' -BUILD_STATE_CLONING = 'cloning' -BUILD_STATE_INSTALLING = 'installing' -BUILD_STATE_BUILDING = 'building' -BUILD_STATE_UPLOADING = 'uploading' -BUILD_STATE_FINISHED = 'finished' +BUILD_STATE_TRIGGERED = "triggered" +BUILD_STATE_CLONING = "cloning" +BUILD_STATE_INSTALLING = "installing" +BUILD_STATE_BUILDING = "building" +BUILD_STATE_UPLOADING = "uploading" +BUILD_STATE_FINISHED = "finished" +BUILD_STATE_CANCELLED = "cancelled" BUILD_STATE = ( - (BUILD_STATE_TRIGGERED, _('Triggered')), - (BUILD_STATE_CLONING, _('Cloning')), - (BUILD_STATE_INSTALLING, _('Installing')), - (BUILD_STATE_BUILDING, _('Building')), - (BUILD_STATE_UPLOADING, _('Uploading')), - (BUILD_STATE_FINISHED, _('Finished')), + (BUILD_STATE_TRIGGERED, _("Triggered")), + (BUILD_STATE_CLONING, _("Cloning")), + (BUILD_STATE_INSTALLING, _("Installing")), + (BUILD_STATE_BUILDING, _("Building")), + (BUILD_STATE_UPLOADING, _("Uploading")), + (BUILD_STATE_FINISHED, _("Finished")), + (BUILD_STATE_CANCELLED, _("Cancelled")), +) + +BUILD_FINAL_STATES = ( + BUILD_STATE_FINISHED, + BUILD_STATE_CANCELLED, ) BUILD_TYPES = ( diff --git a/readthedocs/core/utils/__init__.py b/readthedocs/core/utils/__init__.py index b67295506a3..340665ba8f2 100644 --- a/readthedocs/core/utils/__init__.py +++ b/readthedocs/core/utils/__init__.py @@ -11,6 +11,7 @@ from django.utils.text import slugify as slugify_base from readthedocs.builds.constants import ( + BUILD_STATE_CANCELLED, BUILD_STATE_FINISHED, BUILD_STATE_TRIGGERED, BUILD_STATUS_PENDING, @@ -161,7 +162,7 @@ def prepare_build( build.status = DuplicatedBuildError.status build.exit_code = DuplicatedBuildError.exit_code build.success = False - build.state = BUILD_STATE_FINISHED + build.state = BUILD_STATE_CANCELLED build.save() # Start the build in X minutes and mark it as limited diff --git a/readthedocs/projects/tasks/builds.py b/readthedocs/projects/tasks/builds.py index 0027278f6ca..1db680c3ec2 100644 --- a/readthedocs/projects/tasks/builds.py +++ b/readthedocs/projects/tasks/builds.py @@ -16,6 +16,7 @@ from readthedocs.api.v2.client import api as api_v2 from readthedocs.builds import tasks as build_tasks from readthedocs.builds.constants import ( + BUILD_FINAL_STATES, BUILD_STATE_BUILDING, BUILD_STATE_CLONING, BUILD_STATE_FINISHED, @@ -539,7 +540,11 @@ def after_return(self, status, retval, task_id, args, kwargs, einfo): # Update build object self.data.build['length'] = (timezone.now() - self.data.start_time).seconds - self.update_build(BUILD_STATE_FINISHED) + build_state = None + if self.build["state"] not in BUILD_FINAL_STATES: + build_state = BUILD_STATE_FINISHED + + self.update_build(build_state) build_complete.send(sender=Build, build=self.data.build) @@ -551,8 +556,9 @@ def after_return(self, status, retval, task_id, args, kwargs, einfo): success=self.data.build['success'] ) - def update_build(self, state): - self.data.build['state'] = state + def update_build(self, state=None): + if state: + self.data.build["state"] = state # Attempt to stop unicode errors on build reporting # for key, val in list(self.data.build.items()): diff --git a/readthedocs/templates/builds/build_detail.html b/readthedocs/templates/builds/build_detail.html index b3f4748cc35..fb9cd5f3ddc 100644 --- a/readthedocs/templates/builds/build_detail.html +++ b/readthedocs/templates/builds/build_detail.html @@ -30,7 +30,7 @@ {% block content %}
- {% if build.state != "finished" and request.user|is_admin:project %} + {% if build.state != "finished" and build.state != "cancelled" and request.user|is_admin:project %}
{% csrf_token %}