From c0ccce7e10b45f32ebe08b6e5c88cb4d2363805e Mon Sep 17 00:00:00 2001 From: ievgenii vdovenko Date: Tue, 24 Jun 2025 16:48:31 +0200 Subject: [PATCH] feature: implements frontend saving PR setting --- .../repository/views/repo_pull_requests.py | 17 ++++++++++ rhodecode/model/db.py | 1 + rhodecode/model/forms.py | 1 + rhodecode/model/pull_request.py | 31 +++++++++++++++++++ rhodecode/public/css/main.less | 4 +++ .../public/js/src/rhodecode/pullrequests.js | 7 +++++ .../templates/pullrequests/pullrequest.mako | 9 ++++++ .../pullrequest_merge_checks.mako | 22 +++++++++++++ 8 files changed, 92 insertions(+) diff --git a/rhodecode/apps/repository/views/repo_pull_requests.py b/rhodecode/apps/repository/views/repo_pull_requests.py index 9b24e585..69edc3d9 100644 --- a/rhodecode/apps/repository/views/repo_pull_requests.py +++ b/rhodecode/apps/repository/views/repo_pull_requests.py @@ -166,6 +166,7 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): "comments": _render("pullrequest_comments", comments_count), "comments_raw": comments_count, "closed": pr.is_closed(), + "settings": pr.settings, } ) @@ -934,6 +935,9 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): } c.default_source_ref = selected_source_ref + close_branch_before_merging_key = "rhodecode_%s_close_branch_before_merging" % source_repo.repo_type + c.repo_close_branch_before_merging = self._get_repo_setting(source_repo, close_branch_before_merging_key) + return self._get_template_context(c) @LoginRequired() @@ -1220,6 +1224,7 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): description = _form["pullrequest_desc"] description_renderer = _form["description_renderer"] + settings = {"close_branch_before_merging": _form["close_branch_before_merging"]} try: pull_request = PullRequestModel().create( @@ -1237,6 +1242,7 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): description_renderer=description_renderer, reviewer_data=reviewer_rules, auth_user=self._rhodecode_user, + settings=settings, ) Session().commit() @@ -1283,6 +1289,7 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): controls = peppercorn.parse(self.request.POST.items()) force_refresh = str2bool(self.request.POST.get("force_refresh", "false")) do_update_commits = str2bool(self.request.POST.get("update_commits", "false")) + do_update_branch_close = "close_branch_before_merging" in self.request.POST if "review_members" in controls: self._update_reviewers( @@ -1321,6 +1328,8 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): ) elif str2bool(self.request.POST.get("edit_pull_request", "false")): self._edit_pull_request(pull_request) + elif do_update_branch_close: + self._update_settings(pull_request) else: log.error("Unhandled update data.") raise HTTPBadRequest() @@ -1328,6 +1337,14 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): return {"response": True, "redirect_url": redirect_url} raise HTTPForbidden() + def _update_settings(self, pull_request): + try: + close_branch_before_merging = str2bool(self.request.POST.get("close_branch_before_merging", "false")) + PullRequestModel().update_settings(pull_request, close_branch_before_merging) + except ValueError: + msg = self.request.translate("Cannot update closed pull requests.") + h.flash(msg, category="error") + def _edit_pull_request(self, pull_request): """ Edit title and description diff --git a/rhodecode/model/db.py b/rhodecode/model/db.py index 87d2de47..0a25f8dc 100644 --- a/rhodecode/model/db.py +++ b/rhodecode/model/db.py @@ -4720,6 +4720,7 @@ class PullRequest(Base, _PullRequestBase): attrs.target_ref_parts = pull_request_obj.target_ref_parts attrs.revisions = pull_request_obj.revisions attrs.common_ancestor_id = pull_request_obj.common_ancestor_id + attrs.settings = pull_request_obj.settings attrs.shadow_merge_ref = org_pull_request_obj.shadow_merge_ref attrs.reviewer_data = org_pull_request_obj.reviewer_data attrs.reviewer_data_json = org_pull_request_obj.reviewer_data_json diff --git a/rhodecode/model/forms.py b/rhodecode/model/forms.py index 695886b2..5fd7a62f 100644 --- a/rhodecode/model/forms.py +++ b/rhodecode/model/forms.py @@ -647,6 +647,7 @@ def PullRequestForm(localizer, repo_id): pullrequest_title = v.UnicodeString(strip=True, required=True, min=1, max=255) pullrequest_desc = v.UnicodeString(strip=True, required=False) description_renderer = v.UnicodeString(strip=True, required=False) + close_branch_before_merging = v.StringBoolean(if_missing=False) return _PullRequestForm diff --git a/rhodecode/model/pull_request.py b/rhodecode/model/pull_request.py index dedfb409..4876d6f6 100644 --- a/rhodecode/model/pull_request.py +++ b/rhodecode/model/pull_request.py @@ -31,6 +31,8 @@ import urllib.error import collections import dataclasses as dataclasses +from copy import deepcopy + from rhodecode.lib.pyramid_utils import get_current_request from rhodecode.lib.vcs.nodes import FileNode @@ -809,6 +811,7 @@ class PullRequestModel(BaseModel): reviewer_data=None, translator=None, auth_user=None, + settings=None, ): translator = translator or get_current_request().translate @@ -830,6 +833,8 @@ class PullRequestModel(BaseModel): pull_request.reviewer_data = reviewer_data pull_request.pull_request_state = pull_request.STATE_CREATING pull_request.common_ancestor_id = common_ancestor_id + if self._settings_valid(settings): + pull_request.settings = settings Session().add(pull_request) Session().flush() @@ -938,6 +943,19 @@ class PullRequestModel(BaseModel): return pull_request + def _settings_valid(self, settings): + if not settings: + return False + if not isinstance(settings, dict): + return False + if len(settings) > 1: + return False + if "close_branch_before_merging" not in settings: + return False + if not isinstance(settings["close_branch_before_merging"], bool): + return False + return True + def trigger_pull_request_hook(self, pull_request, user, action, data=None): pull_request = self.__get_pull_request(pull_request) target_scm = pull_request.target_repo.scm_instance() @@ -1470,6 +1488,19 @@ class PullRequestModel(BaseModel): renderer = RstTemplateRenderer() return renderer.render("pull_request_update.mako", **params) + def update_settings(self, pull_request: PullRequest, close_branch_before_merging: bool): + pull_request = self.__get_pull_request(pull_request) + if pull_request.is_closed(): + raise ValueError("This pull request is closed") + + if pull_request.settings["close_branch_before_merging"] == close_branch_before_merging: + return + + settings = deepcopy(pull_request.settings) # need to copy, otherwise SQLalchemy not tracking changes + settings["close_branch_before_merging"] = close_branch_before_merging + pull_request.settings = settings + Session().commit() + def edit(self, pull_request, title, description, description_renderer, user): pull_request = self.__get_pull_request(pull_request) old_data = pull_request.get_api_data(with_merge_state=False) diff --git a/rhodecode/public/css/main.less b/rhodecode/public/css/main.less index fe1b3515..fab77fea 100644 --- a/rhodecode/public/css/main.less +++ b/rhodecode/public/css/main.less @@ -1976,6 +1976,10 @@ BIN_FILENODE = 7 } } +.pull-request-settings { + margin: 2px 7px; +} + .pull-request-merge ul { padding: 0px 0px; } diff --git a/rhodecode/public/js/src/rhodecode/pullrequests.js b/rhodecode/public/js/src/rhodecode/pullrequests.js index 550be5ac..feceb658 100644 --- a/rhodecode/public/js/src/rhodecode/pullrequests.js +++ b/rhodecode/public/js/src/rhodecode/pullrequests.js @@ -528,6 +528,13 @@ var autoCompleteHandler = function (inputId, controller, role) { } } +let updateCloseBranchSetting = function(repo_name, pull_request_id, close_branch_before_merging) { + const postData = { + 'close_branch_before_merging': close_branch_before_merging, + }; + _updatePullRequest(repo_name, pull_request_id, postData); +} + /** * Reviewer autocomplete */ diff --git a/rhodecode/templates/pullrequests/pullrequest.mako b/rhodecode/templates/pullrequests/pullrequest.mako index 0942434e..d8145a3b 100644 --- a/rhodecode/templates/pullrequests/pullrequest.mako +++ b/rhodecode/templates/pullrequests/pullrequest.mako @@ -216,6 +216,15 @@ + % if c.rhodecode_edition_id == 'EE': +
+ ${h.checkbox('close_branch_before_merging', + checked=c.repo_close_branch_before_merging, value=True)} + +
+ % endif diff --git a/rhodecode/templates/pullrequests/pullrequest_merge_checks.mako b/rhodecode/templates/pullrequests/pullrequest_merge_checks.mako index 8386d7eb..880326e2 100644 --- a/rhodecode/templates/pullrequests/pullrequest_merge_checks.mako +++ b/rhodecode/templates/pullrequests/pullrequest_merge_checks.mako @@ -66,6 +66,17 @@ ${h.end_form()} + % if c.rhodecode_edition_id == 'EE': +
+ ${h.checkbox('close_branch_before_merging', checked=c.pull_request.settings.get("close_branch_before_merging", False))} + +
+ % endif +
${_('refresh checks')}
@@ -80,3 +91,14 @@ + +