feature: implements frontend saving PR setting

This commit is contained in:
ievgenii vdovenko 2025-06-24 16:48:31 +02:00
parent b42333562d
commit c0ccce7e10
8 changed files with 92 additions and 0 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -1976,6 +1976,10 @@ BIN_FILENODE = 7
}
}
.pull-request-settings {
margin: 2px 7px;
}
.pull-request-merge ul {
padding: 0px 0px;
}

View file

@ -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
*/

View file

@ -216,6 +216,15 @@
<input id="pr_submit" class="btn" name="save" type="submit" value="${_('Submit Pull Request')}">
</div>
</div>
% if c.rhodecode_edition_id == 'EE':
<div class="pull-request-settings">
${h.checkbox('close_branch_before_merging',
checked=c.repo_close_branch_before_merging, value=True)}
<label for="close_branch_before_merging">
${h.literal(_('Close branch before merging'))}
</label>
</div>
% endif
</div>
</div>
</div>

View file

@ -66,6 +66,17 @@
<input type="submit" id="merge_pull_request" value="${_('Merge and close Pull Request')}" class="btn${merge_disabled}"${merge_disabled}>
${h.end_form()}
% if c.rhodecode_edition_id == 'EE':
<div class="pull-request-settings"
id="close_branch_before_merging_wrapper"
>
${h.checkbox('close_branch_before_merging', checked=c.pull_request.settings.get("close_branch_before_merging", False))}
<label for="close_branch_before_merging">
${h.literal(_('Close branch before merging'))}
</label>
</div>
% endif
<div class="pull-request-merge-refresh">
<a href="#refreshChecks" onclick="refreshMergeChecks(); return false;">${_('refresh checks')}</a>
</div>
@ -80,3 +91,14 @@
</div>
</div>
<script>
$("#close_branch_before_merging").on('change', function () {
const $checkbox = $(this);
updateCloseBranchSetting(
"${c.repo_name}",
${c.pull_request.pull_request_id},
$checkbox.prop('checked'),
);
});
</script>