Skip to content
Snippets Groups Projects

rebase-scripts: Improve automation and output

Open Walter Lozano requested to merge wip/wlozano/trigger-no-update into main
1 file
+ 49
6
Compare changes
  • Side-by-side
  • Inline
  • fb427ab1
    A possible scenario during a rebase is that a package has no update, in
    which case, usually the automerge-trivial argument allow the MR to be
    merged. However, for this to work the package need also to have
    trivial changes, which means no delta.
    
    In the case of a delta, it should be reviewed to make sure it is still
    valid, however, this can be done later to unblock the rebase.
    
    To support this behavior introduce a new argument to automerge MR
    when the package has no update. Also, add a log to allow to generate a
    list of packages to be reviewed later.
    
    Signed-off-by: default avatarWalter Lozano <walter.lozano@collabora.com>
@@ -11,11 +11,26 @@ import logging
import json
import base64
DEBIAN_RELEASES = ['buster', 'bullseye', 'bookworm', 'trixie', 'forky']
DEBIAN_BRANCHES = ['debian/' + x for x in DEBIAN_RELEASES ]
def old_debian_branch(debian_branch):
if not debian_branch in DEBIAN_BRANCHES:
return None
index = DEBIAN_BRANCHES.index(debian_branch) - 1
if index >= 0 and index < len(DEBIAN_BRANCHES):
return DEBIAN_BRANCHES[index]
return None
class MergeData:
def __init__(self, mr_url, component, trivial_merge, failed_merge, changes_url, pipeline_url, pipeline_status, failed_jobs, project_id, merge_request_iid):
def __init__(self, mr_url, component, trivial_merge, no_update_merge, failed_merge, changes_url, pipeline_url, pipeline_status, failed_jobs, project_id, merge_request_iid):
self.mr_url = mr_url
self.component = component
self.trivial_merge = trivial_merge
self.no_update_merge = no_update_merge
self.failed_merge = failed_merge
self.changes_url = changes_url
self.pipeline_url = pipeline_url
@@ -30,6 +45,11 @@ class MergeData:
prefix = "🚀 Trivial"
else:
prefix = "😿 Trivial but failed"
elif self.no_update_merge:
if self.pipeline_status == "success":
prefix = "🚀 No update"
else:
prefix = "😿 No update but failed"
elif self.failed_merge:
prefix = "⚠️ Automated merge failed:"
else:
@@ -55,6 +75,19 @@ class Analyser:
self.gl = gitlab.Gitlab.from_config(gitlab_instance)
self.gl.auth()
def no_upstream_update(self, project, debian):
old_debian = old_debian_branch(debian)
try:
debian_id = project.branches.get(debian).commit['id']
old_debian_id = project.branches.get(old_debian).commit['id']
except:
return False
if debian_id == old_debian_id:
return True
return False
def merge(self, data):
project = self.gl.projects.get(data.project_id, lazy=True)
pmr = project.mergerequests.get(data.merge_request_iid, access_raw_diffs=False, lazy=False)
@@ -74,7 +107,7 @@ class Analyser:
p = project.pipelines.get(p.id)
p.retry()
def analyse_mr(self, mr, debian, automerge_trivial, retry_obs):
def analyse_mr(self, mr, debian, automerge_trivial, automerge_no_update, retry_obs):
logging.debug(f"Analyzing {mr.web_url}")
project = self.gl.projects.get(mr.project_id, lazy=True)
@@ -91,6 +124,11 @@ class Analyser:
except:
pass
no_update_merge = False
if self.no_upstream_update(project, debian):
logging.debug(f"Found a no update merge: {no_update_merge}")
no_update_merge = True
cmp = project.repository_compare(debian, pmr.source_branch)
logging.debug(f"Changes url: {cmp['web_url']}")
trivial_merge = True
@@ -119,18 +157,21 @@ class Analyser:
logging.debug(f"Pipeline jobs that failed: {failed_jobs}")
logging.debug(f"Found a trivial merge: {trivial_merge}")
m = MergeData(mr.web_url, component, trivial_merge, failed_merge, cmp['web_url'], p.web_url, p.status, failed_jobs, mr.project_id, mr.iid)
m = MergeData(mr.web_url, component, trivial_merge, no_update_merge, failed_merge, cmp['web_url'], p.web_url, p.status, failed_jobs, mr.project_id, mr.iid)
logging.info(m)
if automerge_trivial and m.trivial_merge and m.pipeline_status == 'success':
self.merge(m)
if automerge_no_update and m.no_update_merge and m.pipeline_status == 'success':
self.merge(m)
if retry_obs and m.pipeline_status == 'failed' and len(m.failed_jobs) > 0 and m.failed_jobs[0].startswith(('obs','upload')):
self.retry_pipeline(m)
return m
def process_mr_list(self, target, debian, user, max_merges = None, automerge_trivial = False, retry_obs = False):
def process_mr_list(self, target, debian, user, max_merges = None, automerge_trivial = False, automerge_no_update = False, retry_obs = False):
merges = []
group = self.gl.groups.get(f"{self.group}", lazy=True)
for mr in group.mergerequests.list(state = "opened", iterator=True, lazy = True):
@@ -143,7 +184,7 @@ class Analyser:
break
max_merges -= 1
data = self.analyse_mr(mr, debian, automerge_trivial, retry_obs)
data = self.analyse_mr(mr, debian, automerge_trivial, automerge_no_update, retry_obs)
merges.append(data)
return merges
@@ -172,6 +213,8 @@ if __name__ == "__main__":
default = None)
parser.add_argument('--automerge-trivial',
action='store_true')
parser.add_argument('--automerge-no-update',
action='store_true')
parser.add_argument('--debian-branch',
default = 'debian/trixie',
help = 'Debian upstream branch to use')
@@ -202,7 +245,7 @@ if __name__ == "__main__":
a = Analyser(args.group)
a.connect(args.gitlab_instance, args.gitlab_server_url, args.gitlab_api_token)
merges = a.process_mr_list(args.apertis_target_branch, args.debian_branch, args.filter_user, args.max_merges,
args.automerge_trivial, args.retry_obs)
args.automerge_trivial, args.automerge_no_update, args.retry_obs)
logging.info(f"Total merges analyzed: {len(merges)}")
logging.info(f"Total trivial merges with happy pipelines: {len(list(filter(lambda m: m.trivial_merge and m.pipeline_status == 'success', merges)))}")
Loading