diff --git a/rhodecode/apps/home/views.py b/rhodecode/apps/home/views.py index f3386a76..4bcf4e46 100644 --- a/rhodecode/apps/home/views.py +++ b/rhodecode/apps/home/views.py @@ -79,7 +79,8 @@ class HomeView(BaseAppView, DataGridAppView): _users = UserModel().get_users(name_contains=query, only_active=active) def maybe_skip_user(usr): - if skip_default_user and usr["username"] in [UserModel.cls.DEFAULT_USER, UserModel.cls.GHOST_USER]: + if (skip_default_user and usr["username"] == UserModel.cls.DEFAULT_USER + or usr["username"] in [UserModel.cls.GHOST_USER, UserModel.cls.AI_USER]): return False return True diff --git a/rhodecode/apps/repository/__init__.py b/rhodecode/apps/repository/__init__.py index 1a4650df..de1e3d19 100644 --- a/rhodecode/apps/repository/__init__.py +++ b/rhodecode/apps/repository/__init__.py @@ -825,6 +825,20 @@ def includeme(config): renderer="json_ext", ) + config.add_route( + name="pullrequest_start_ai_code_review", + pattern=r"/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}/ai/review", + repo_route=True, + repo_forbid_when_archived=True, + ) + config.add_view( + RepoPullRequestsView, + attr="start_ai_code_review", + route_name="pullrequest_start_ai_code_review", + request_method="POST", + renderer="json_ext", + ) + config.add_route( name="pullrequest_merge", pattern=r"/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}/merge", diff --git a/rhodecode/apps/repository/views/repo_pull_requests.py b/rhodecode/apps/repository/views/repo_pull_requests.py index 7ec27be7..30f923ac 100644 --- a/rhodecode/apps/repository/views/repo_pull_requests.py +++ b/rhodecode/apps/repository/views/repo_pull_requests.py @@ -61,6 +61,7 @@ from rhodecode.model.forms import PullRequestForm from rhodecode.model.meta import Session from rhodecode.model.pull_request import PullRequestModel, MergeCheck from rhodecode.model.scm import ScmModel +from rhodecode.model.settings import SettingsModel log = logging.getLogger(__name__) @@ -360,6 +361,12 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): c.state_progressing = pull_request.is_state_changing() c.pr_broadcast_channel = channelstream.pr_channel(pull_request) + rc_settings = SettingsModel() + ai_setting = rc_settings.get_setting_by_name("ai_features_enabled") + c.ai_enabled = False + if ai_setting: + c.ai_enabled = ai_setting.app_settings_value + _new_state = { "created": PullRequest.STATE_CREATED, }.get(self.request.GET.get("force_state")) @@ -1280,6 +1287,53 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): h.route_path("pullrequest_show", repo_name=target_repo, pull_request_id=pull_request.pull_request_id) ) + @LoginRequired() + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") + def start_ai_code_review(self): + _ = self.request.translate + redirect_url = None + + pull_request = PullRequest.get_or_404(self.request.matchdict["pull_request_id"]) + if pull_request.is_closed(): + log.debug("AI code review: forbidden because pull request is closed") + message = _("Cannot start review for closed pull requests.") + h.flash(message, category="error") + return {"response": True, "redirect_url": redirect_url} + + log.debug("AI code review: started") + + redirect_url = h.route_path( + "pullrequest_show", + repo_name=self.db_repo_name, + pull_request_id=pull_request.pull_request_id, + ) + + admin_permissions = ( + "repository.admin", + "hg.admin", + ) + is_admin = h.HasRepoPermissionAny(*admin_permissions)( + user=self._rhodecode_user, repo_name=pull_request.target_repo.repo_name + ) + + if is_admin: + log.debug("Initiating code review for pull request id: %s", pull_request.pull_request_id) + run_task(tasks.start_ai_code_review, pull_request.pull_request_id) + msg = _("AI code review has started. The review will be ready in about 1–3 minutes.") + h.flash(msg, category="success") + else: + log.debug("AI code review canceled, only admin can initiate AI code review.") + msg = _( + "AI code review is not available. This feature is in BETA and can only be initiated by an admin." + ) + h.flash( + msg, + category="warning", + ) + + return {"response": True, "redirect_url": redirect_url} + + @LoginRequired() @NotAnonymous() @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") @@ -1312,40 +1366,7 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): do_update_branch_close = "close_branch_before_merging" in self.request.POST if "review_members" in controls: - ai_user = User.get_ai_user() - ai_user_id = ai_user.user_id - members_ = controls["review_members"] - for i, member_data in enumerate(members_): - user_id = safe_int(member_data.get("user_id", -1)) - - if ai_user_id == user_id: - admin_permissions = ( - "repository.admin", - "hg.admin", - ) - is_admin = h.HasRepoPermissionAny(*admin_permissions)( - user=self._rhodecode_user, repo_name=pull_request.target_repo.repo_name - ) - - if is_admin: - log.debug("Initiating code review for pull request id: %s", pull_request.pull_request_id) - run_task(tasks.start_ai_code_review, pull_request.pull_request_id) - msg = _("AI code review has started. The review will be ready in about 1–3 minutes.") - h.flash(msg, category="success") - else: - log.debug("AI code review canceled, only admin can initiate AI code review.") - msg = _( - "AI code review is not available. This feature is in BETA and can only be initiated by an admin." - ) - h.flash( - msg, - category="warning", - ) - del members_[i] - - break - self._update_reviewers( c, pull_request, diff --git a/rhodecode/lib/celerylib/tasks.py b/rhodecode/lib/celerylib/tasks.py index a5f5eaef..c3ab950a 100644 --- a/rhodecode/lib/celerylib/tasks.py +++ b/rhodecode/lib/celerylib/tasks.py @@ -495,7 +495,11 @@ def start_ai_code_review(pull_request_id): log = get_logger(start_ai_code_review) log.info("Starting AI code review for pull request id: %s", pull_request_id) rc_settings = SettingsModel() - ai_enabled = rc_settings.get_setting_by_name("ai_features_enabled") + ai_setting = rc_settings.get_setting_by_name("ai_features_enabled") + ai_enabled = False + if ai_setting: + ai_enabled = ai_setting.app_settings_value + if not ai_enabled: log.info("AI code review is disabled.") return diff --git a/rhodecode/public/js/src/rhodecode/pullrequests.js b/rhodecode/public/js/src/rhodecode/pullrequests.js index feceb658..16d53583 100644 --- a/rhodecode/public/js/src/rhodecode/pullrequests.js +++ b/rhodecode/public/js/src/rhodecode/pullrequests.js @@ -417,6 +417,15 @@ window.ReviewersController = function () { }; + this.startAiCodeReview = function (repo_name, pull_request_id) { + const url = `/${repo_name}/pull-request/${pull_request_id}/ai/review` + const postData = {}; + const success = function (o) { + window.location.reload(); + }; + ajaxPOST(url, postData, success); + }; + this.updateReviewers = function (repo_name, pull_request_id, role) { if (role === 'reviewer') { var postData = $('#reviewers input').serialize(); diff --git a/rhodecode/templates/pullrequests/pullrequest_show.mako b/rhodecode/templates/pullrequests/pullrequest_show.mako index 586f5d2a..5a2728a0 100644 --- a/rhodecode/templates/pullrequests/pullrequest_show.mako +++ b/rhodecode/templates/pullrequests/pullrequest_show.mako @@ -615,7 +615,6 @@
+ % endif + ## TODOs