From e9d0a6e8b7d3a1a0d72eb62783be4fc2b24140cc Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Jun 02 2020 16:35:54 +0000 Subject: Do not allow removing release branches from which builds have been made Bodhi knows branches that go as far as 'f21': ['el5', 'el6', 'eln', 'epel7', 'epel8', 'epel8m', 'f21', 'f22', 'f23', 'f24', 'f25', 'f26', 'f27', 'f27m', 'f28', 'f28', 'f28m', 'f29', 'f29', 'f29', 'f29m', 'f30', 'f30', 'f30', 'f30m', 'f31', 'f31', 'f31', 'f31m', 'f32', 'f32', 'f32', 'f32m', 'f33', 'f33'] So do the following: - look up the branch in bodhi, if found, do the check using any tags declared by bodhi - if bodhi doesn't know the branch, and the branch matches the pattern of 'f\d{1,2}|el\d|epel\d|epel1\d', refuse (this is forward-looking, to allow epel10) - otherwise allow We will refuse the removal of very old branches that look like release branches, but people wouldn't want that too often anyway, so I think that's OK. --- diff --git a/scripts/distgit-branch-unused.py b/scripts/distgit-branch-unused.py index aade0ea..a57b5d6 100755 --- a/scripts/distgit-branch-unused.py +++ b/scripts/distgit-branch-unused.py @@ -24,16 +24,59 @@ commits. import argparse import pathlib +import re import pygit2 +import requests import koji as _koji +BODHI_RELEASES = 'https://bodhi.fedoraproject.org/releases/?rows_per_page=1000' +NORMAL_BRANCHES = r'^(f\d{1,2}|el\d|epel\d|epel1\d)$' + +_KOJI_SESSION = None +def koji_session(opts): + global _KOJI_SESSION + if not _KOJI_SESSION: + koji = _koji.get_profile_module(opts.koji_profile) + session_opts = koji.grab_session_options(koji.config) + session = koji.ClientSession(koji.config.server, session_opts) + _KOJI_SESSION = (session, koji) + return _KOJI_SESSION + +def koji_builds_exist(tag, package, opts): + session, _ = koji_session(opts) + + print(f'Checking for {package} in tag {tag}...', end=' ') + tagged = session.listTagged(tag, latest=True, inherit=False, package=package) + print(tagged[0]['nvr'] if tagged else '(no)') + return bool(tagged) + +def bodhi_builds_exist(branch, package, opts): + releases = requests.get(BODHI_RELEASES).json()['releases'] + + for entry in releases: + if entry['branch'] == branch: + tags = [v for k,v in entry.items() if k.endswith('_tag') and v] + print(f'Found branch {branch} in bodhi with tags:', ', '.join(tags)) + for tag in tags: + if koji_builds_exist(tag, package, opts): + return True + + print(f'No builds found in koji for branch {branch}') + return False + + print(f'Branch {branch} not found in bodhi, checking if branch matches pattern...') + m = re.match(NORMAL_BRANCHES, branch) + if m: + print('...it does, do not delete') + return True + print('...no match, seems OK to remove') + return False + def find_hash(build): return build['source'].rsplit('#', 1)[1] def list_builds(package, opts): - koji = _koji.get_profile_module(opts.koji_profile) - session_opts = koji.grab_session_options(koji.config) - session = koji.ClientSession(koji.config.server, session_opts) + session, koji = koji_session(opts) pkg = session.getPackageID(package, strict=True) builds = session.listBuilds(packageID=pkg, state=koji.BUILD_STATES['COMPLETE']) @@ -98,11 +141,22 @@ def branch_is_reachable(opts): repo = pygit2.Repository(opts.repository) try: branch = repo.branches.local[opts.branch] + branch_name = branch.branch_name local = True except KeyError: branch = repo.branches.remote[opts.branch] + l = len(branch.remote_name) + branch_name = branch.branch_name[l+1:] local = False + if branch_name == 'master': + print("Branch 'master' cannot be deleted.") + return 1 + + if bodhi_builds_exist(branch_name, opts.package, opts): + print('Branch was used to build packages, cannot delete.') + return 1 + other = list(containing_branches(repo, branch.target, local=local, ignore_branch=branch)) if other: names = ', '.join(o.name for o in other)