mirror of
https://github.com/scylladb/scylladb.git
synced 2026-04-25 19:10:42 +00:00
./github/scripts/auto-backport.py: don't remove backport label when backport process has an error
Today, when the `Fixes` prefix is missing or the developer is not a collaborator with `scylladbbot` we remove the backport labels to prevent the process from starting and notifying the developers. Developers are worried that removing these backport labels will cause us to forget we need to do these backports. @nyh suggested to add a `scylladbbot/backport_error` label instead Applied those changes, so when a `Fixes` prefix is missing we will add a `scylladbbot/backport_error` label and stop the process When a user doesn't accept the invite we will still open the PR but he will not be assigned and will not be able to edit the branch when we have conflicts Fixes: https://github.com/scylladb/scylla-pkg/issues/4898 Fixes: https://github.com/scylladb/scylla-pkg/issues/4897
This commit is contained in:
50
.github/scripts/auto-backport.py
vendored
50
.github/scripts/auto-backport.py
vendored
@@ -29,10 +29,11 @@ def parse_args():
|
||||
parser.add_argument('--commits', default=None, type=str, help='Range of promoted commits.')
|
||||
parser.add_argument('--pull-request', type=int, help='Pull request number to be backported')
|
||||
parser.add_argument('--head-commit', type=str, required=is_pull_request(), help='The HEAD of target branch after the pull request specified by --pull-request is merged')
|
||||
parser.add_argument('--github-event', type=str, help='Get GitHub event type')
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def create_pull_request(repo, new_branch_name, base_branch_name, pr, backport_pr_title, commits, is_draft=False):
|
||||
def create_pull_request(repo, new_branch_name, base_branch_name, pr, backport_pr_title, commits, is_draft, is_collaborator):
|
||||
pr_body = f'{pr.body}\n\n'
|
||||
for commit in commits:
|
||||
pr_body += f'- (cherry picked from commit {commit})\n\n'
|
||||
@@ -46,7 +47,8 @@ def create_pull_request(repo, new_branch_name, base_branch_name, pr, backport_pr
|
||||
draft=is_draft
|
||||
)
|
||||
logging.info(f"Pull request created: {backport_pr.html_url}")
|
||||
backport_pr.add_to_assignees(pr.user)
|
||||
if is_collaborator:
|
||||
backport_pr.add_to_assignees(pr.user)
|
||||
if is_draft:
|
||||
backport_pr.add_to_labels("conflicts")
|
||||
pr_comment = f"@{pr.user.login} - This PR was marked as draft because it has conflicts\n"
|
||||
@@ -92,18 +94,7 @@ def get_pr_commits(repo, pr, stable_branch, start_commit=None):
|
||||
return commits
|
||||
|
||||
|
||||
def create_pr_comment_and_remove_label(pr, comment_body):
|
||||
labels = pr.get_labels()
|
||||
pattern = re.compile(r"backport/\d+\.\d+$")
|
||||
for label in labels:
|
||||
if pattern.match(label.name):
|
||||
print(f"Removing label: {label.name}")
|
||||
comment_body += f'- {label.name}\n'
|
||||
pr.remove_from_labels(label)
|
||||
pr.create_issue_comment(comment_body)
|
||||
|
||||
|
||||
def backport(repo, pr, version, commits, backport_base_branch):
|
||||
def backport(repo, pr, version, commits, backport_base_branch, is_collaborator):
|
||||
new_branch_name = f'backport/{pr.number}/to-{version}'
|
||||
backport_pr_title = f'[Backport {version}] {pr.title}'
|
||||
repo_url = f'https://scylladbbot:{github_token}@github.com/{repo.full_name}.git'
|
||||
@@ -123,7 +114,7 @@ def backport(repo, pr, version, commits, backport_base_branch):
|
||||
repo_local.git.cherry_pick('--continue')
|
||||
repo_local.git.push(fork_repo, new_branch_name, force=True)
|
||||
create_pull_request(repo, new_branch_name, backport_base_branch, pr, backport_pr_title, commits,
|
||||
is_draft=is_draft)
|
||||
is_draft, is_collaborator)
|
||||
|
||||
except GitCommandError as e:
|
||||
logging.warning(f"GitCommandError: {e}")
|
||||
@@ -140,10 +131,6 @@ def with_github_keyword_prefix(repo, pr):
|
||||
break
|
||||
if not match:
|
||||
print(f'No valid close reference for {pr.number}')
|
||||
comment = f':warning: @{pr.user.login} PR body does not contain a Fixes reference to an issue '
|
||||
comment += ' and can not be backported\n\n'
|
||||
comment += 'The following labels were removed:\n'
|
||||
create_pr_comment_and_remove_label(pr, comment)
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
@@ -168,6 +155,7 @@ def main():
|
||||
scylladbbot_repo = g.get_repo(fork_repo_name)
|
||||
closed_prs = []
|
||||
start_commit = None
|
||||
is_collaborator = True
|
||||
|
||||
if args.commits:
|
||||
start_commit, end_commit = args.commits.split('..')
|
||||
@@ -192,21 +180,33 @@ def main():
|
||||
if not backport_labels:
|
||||
print(f'no backport label: {pr.number}')
|
||||
continue
|
||||
if args.commits and not with_github_keyword_prefix(repo, pr):
|
||||
if not with_github_keyword_prefix(repo, pr) and args.github_event != 'unlabeled':
|
||||
comment = f''':warning: @{pr.user.login} PR body or PR commits do not contain a Fixes reference to an issue and can not be backported
|
||||
please update PR body with a valid ref to an issue. Then remove `scylladbbot/backport_error` label to re-trigger the backport process
|
||||
'''
|
||||
pr.create_issue_comment(comment)
|
||||
pr.add_to_labels("scylladbbot/backport_error")
|
||||
continue
|
||||
if not repo.private and not scylladbbot_repo.has_in_collaborators(pr.user.login):
|
||||
logging.info(f"Sending an invite to {pr.user.login} to become a collaborator to {scylladbbot_repo.full_name} ")
|
||||
scylladbbot_repo.add_to_collaborators(pr.user.login)
|
||||
comment = f':warning: @{pr.user.login} you have been added as collaborator to scylladbbot fork '
|
||||
comment += f'Please check your inbox and approve the invitation, once it is done, please add the backport labels again\n'
|
||||
create_pr_comment_and_remove_label(pr, comment)
|
||||
continue
|
||||
comment = f''':warning: @{pr.user.login} you have been added as collaborator to scylladbbot fork
|
||||
Please check your inbox and approve the invitation, otherwise you will not be able to edit PR branch when needed
|
||||
'''
|
||||
# When a pull request is pending for backport but its author is not yet a collaborator of "scylladbbot",
|
||||
# we attach a "scylladbbot/backport_error" label to the PR.
|
||||
# This prevents the workflow from proceeding with the backport process
|
||||
# until the author has been granted proper permissions
|
||||
# the author should remove the label manually to re-trigger the backport workflow.
|
||||
pr.add_to_labels("scylladbbot/backport_error")
|
||||
pr.create_issue_comment(comment)
|
||||
is_collaborator = False
|
||||
commits = get_pr_commits(repo, pr, stable_branch, start_commit)
|
||||
logging.info(f"Found PR #{pr.number} with commit {commits} and the following labels: {backport_labels}")
|
||||
for backport_label in backport_labels:
|
||||
version = backport_label.replace('backport/', '')
|
||||
backport_base_branch = backport_label.replace('backport/', backport_branch)
|
||||
backport(repo, pr, version, commits, backport_base_branch)
|
||||
backport(repo, pr, version, commits, backport_base_branch, is_collaborator)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user