reviewers: changes for new author/commit author logic.

- new rules to exclude include pr author, commit-authors
- allows workflow to always add author of PR to reviewers
This commit is contained in:
Milka Kuzminski 2020-11-11 17:47:49 +01:00
parent b362e18090
commit 30342b6001
6 changed files with 120 additions and 71 deletions

View file

@ -48,7 +48,7 @@ PYRAMID_SETTINGS = {}
EXTENSIONS = {}
__version__ = ('.'.join((str(each) for each in VERSION[:3])))
__dbversion__ = 111 # defines current db version for migrations
__dbversion__ = 112 # defines current db version for migrations
__platform__ = platform.system()
__license__ = 'AGPLv3, and Commercial License'
__author__ = 'RhodeCode GmbH'

View file

@ -24,7 +24,8 @@ from rhodecode.model.pull_request import get_diff_info
from rhodecode.model.db import PullRequestReviewers
# V3 - Reviewers, with default rules data
# v4 - Added observers metadata
REVIEWER_API_VERSION = 'V4'
# v5 - pr_author/commit_author include/exclude logic
REVIEWER_API_VERSION = 'V5'
def reviewer_as_json(user, reasons=None, role=None, mandatory=False, rules=None, user_group=None):
@ -88,6 +89,7 @@ def get_default_reviewers_data(current_user, source_repo, source_ref, target_rep
'reviewers': json_reviewers,
'rules': {},
'rules_data': {},
'rules_humanized': [],
}

View file

@ -428,16 +428,12 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView):
c.allowed_to_close = c.allowed_to_merge and not pr_closed
c.forbid_adding_reviewers = False
c.forbid_author_to_review = False
c.forbid_commit_author_to_review = False
if pull_request_latest.reviewer_data and \
'rules' in pull_request_latest.reviewer_data:
rules = pull_request_latest.reviewer_data['rules'] or {}
try:
c.forbid_adding_reviewers = rules.get('forbid_adding_reviewers')
c.forbid_author_to_review = rules.get('forbid_author_to_review')
c.forbid_commit_author_to_review = rules.get('forbid_commit_author_to_review')
except Exception:
pass

View file

@ -0,0 +1,78 @@
# -*- coding: utf-8 -*-
import logging
from sqlalchemy import *
from alembic.migration import MigrationContext
from alembic.operations import Operations
from rhodecode.lib.dbmigrate.versions import _reset_base
from rhodecode.model import meta, init_model_encryption
log = logging.getLogger(__name__)
def upgrade(migrate_engine):
"""
Upgrade operations go here.
Don't create your own engine; bind migrate_engine to your metadata
"""
_reset_base(migrate_engine)
from rhodecode.lib.dbmigrate.schema import db_4_20_0_0 as db
init_model_encryption(db)
context = MigrationContext.configure(migrate_engine.connect())
op = Operations(context)
table = db.RepoReviewRule.__table__
with op.batch_alter_table(table.name) as batch_op:
new_column = Column('pr_author', UnicodeText().with_variant(UnicodeText(255), 'mysql'), nullable=True)
batch_op.add_column(new_column)
new_column = Column('commit_author', UnicodeText().with_variant(UnicodeText(255), 'mysql'), nullable=True)
batch_op.add_column(new_column)
_migrate_review_flags_to_new_cols(op, meta.Session)
def downgrade(migrate_engine):
meta = MetaData()
meta.bind = migrate_engine
def fixups(models, _SESSION):
pass
def _migrate_review_flags_to_new_cols(op, session):
# set defaults for pr_author
query = text(
'UPDATE repo_review_rules SET pr_author = :val'
).bindparams(val='no_rule')
op.execute(query)
# set defaults for commit_author
query = text(
'UPDATE repo_review_rules SET commit_author = :val'
).bindparams(val='no_rule')
op.execute(query)
session().commit()
# now change the flags to forbid based on
# forbid_author_to_review, forbid_commit_author_to_review
query = text(
'UPDATE repo_review_rules SET pr_author = :val WHERE forbid_author_to_review = TRUE'
).bindparams(val='forbid_pr_author')
op.execute(query)
query = text(
'UPDATE repo_review_rules SET commit_author = :val WHERE forbid_commit_author_to_review = TRUE'
).bindparams(val='forbid_commit_author')
op.execute(query)
session().commit()

View file

@ -5058,8 +5058,14 @@ class RepoReviewRule(Base, BaseModel):
_file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default=u'*') # glob
use_authors_for_review = Column("use_authors_for_review", Boolean(), nullable=False, default=False)
forbid_author_to_review = Column("forbid_author_to_review", Boolean(), nullable=False, default=False)
forbid_commit_author_to_review = Column("forbid_commit_author_to_review", Boolean(), nullable=False, default=False)
# Legacy fields, just for backward compat
_forbid_author_to_review = Column("forbid_author_to_review", Boolean(), nullable=False, default=False)
_forbid_commit_author_to_review = Column("forbid_commit_author_to_review", Boolean(), nullable=False, default=False)
pr_author = Column("pr_author", UnicodeText().with_variant(UnicodeText(255), 'mysql'), nullable=True)
commit_author = Column("commit_author", UnicodeText().with_variant(UnicodeText(255), 'mysql'), nullable=True)
forbid_adding_reviewers = Column("forbid_adding_reviewers", Boolean(), nullable=False, default=False)
rule_users = relationship('RepoReviewRuleUser')
@ -5095,6 +5101,22 @@ class RepoReviewRule(Base, BaseModel):
self._validate_pattern(value)
self._file_pattern = value or '*'
@hybrid_property
def forbid_pr_author_to_review(self):
return self.pr_author == 'forbid_pr_author'
@hybrid_property
def include_pr_author_to_review(self):
return self.pr_author == 'include_pr_author'
@hybrid_property
def forbid_commit_author_to_review(self):
return self.commit_author == 'forbid_commit_author'
@hybrid_property
def include_commit_author_to_review(self):
return self.commit_author == 'include_commit_author'
def matches(self, source_branch, target_branch, files_changed):
"""
Check if this review rule matches a branch/files in a pull request

View file

@ -182,83 +182,34 @@ window.ReviewersController = function () {
if (!data || data.rules === undefined || $.isEmptyObject(data.rules)) {
// default rule, case for older repo that don't have any rules stored
self.$rulesList.append(
self.addRule(
_gettext('All reviewers must vote.'))
self.addRule(_gettext('All reviewers must vote.'))
);
return self.forbidUsers
}
if (data.rules.voting !== undefined) {
if (data.rules.voting < 0) {
self.$rulesList.append(
self.addRule(
_gettext('All individual reviewers must vote.'))
)
} else if (data.rules.voting === 1) {
self.$rulesList.append(
self.addRule(
_gettext('At least {0} reviewer must vote.').format(data.rules.voting))
)
} else {
self.$rulesList.append(
self.addRule(
_gettext('At least {0} reviewers must vote.').format(data.rules.voting))
)
}
}
if (data.rules.voting_groups !== undefined) {
$.each(data.rules.voting_groups, function (index, rule_data) {
self.$rulesList.append(
self.addRule(rule_data.text)
)
});
}
if (data.rules.use_code_authors_for_review) {
self.$rulesList.append(
self.addRule(
_gettext('Reviewers picked from source code changes.'))
)
}
if (data.rules.forbid_adding_reviewers) {
$('#add_reviewer_input').remove();
self.$rulesList.append(
self.addRule(
_gettext('Adding new reviewers is forbidden.'))
)
}
if (data.rules.forbid_author_to_review) {
self.forbidUsers.push(data.rules_data.pr_author);
self.$rulesList.append(
self.addRule(
_gettext('Author is not allowed to be a reviewer.'))
)
if (data.rules_data !== undefined && data.rules_data.forbidden_users !== undefined) {
$.each(data.rules_data.forbidden_users, function(idx, val){
self.forbidUsers.push(val)
})
}
if (data.rules.forbid_commit_author_to_review) {
if (data.rules_data.forbidden_users) {
$.each(data.rules_data.forbidden_users, function (index, member_data) {
self.forbidUsers.push(member_data)
});
}
if (data.rules_humanized !== undefined && data.rules_humanized.length > 0) {
$.each(data.rules_humanized, function(idx, val) {
self.$rulesList.append(
self.addRule(val)
)
})
} else {
// we don't have any rules set, so we inform users about it
self.$rulesList.append(
self.addRule(
_gettext('Commit Authors are not allowed to be a reviewer.'))
self.addRule(_gettext('No additional review rules set.'))
)
}
// we don't have any rules set, so we inform users about it
if (self.enabledRules.length === 0) {
self.addRule(
_gettext('No review rules set.'))
}
return self.forbidUsers
};