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:
parent
b362e18090
commit
30342b6001
6 changed files with 120 additions and 71 deletions
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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': [],
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
78
rhodecode/lib/dbmigrate/versions/112_version_4_23_0.py
Normal file
78
rhodecode/lib/dbmigrate/versions/112_version_4_23_0.py
Normal 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()
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue