mirror of
https://github.com/ceph/ceph
synced 2025-04-01 23:02:17 +00:00
script/backport-create-issue: add --resolve-parent feature
When --resolve-parent is provided on the command line, the script will check the status of backport issues for those parent issues all of whose backport issues already exist. If all the backport issues are in status "Resolved", the parent issue's status is set to "Resolved" as well. Signed-off-by: Nathan Cutler <ncutler@suse.com>
This commit is contained in:
parent
20bebe242b
commit
e4d6312fa2
@ -53,6 +53,7 @@ status2status_id = {}
|
||||
project_id2project = {}
|
||||
tracker2tracker_id = {}
|
||||
version2version_id = {}
|
||||
resolve_parent = None
|
||||
|
||||
def usage():
|
||||
logging.error("Command-line arguments must include either a Redmine key (--key) "
|
||||
@ -68,6 +69,8 @@ def parse_arguments():
|
||||
parser.add_argument("--key", help="Redmine user key")
|
||||
parser.add_argument("--user", help="Redmine user")
|
||||
parser.add_argument("--password", help="Redmine password")
|
||||
parser.add_argument("--resolve-parent", help="Resolve parent issue if all backports resolved",
|
||||
action="store_true")
|
||||
parser.add_argument("--debug", help="Show debug-level messages",
|
||||
action="store_true")
|
||||
parser.add_argument("--dry-run", help="Do not write anything to Redmine",
|
||||
@ -83,11 +86,17 @@ def set_logging_level(a):
|
||||
|
||||
def report_dry_run(a):
|
||||
if a.dry_run:
|
||||
logging.info("Dry run: nothing will be written to Redmine")
|
||||
logging.info("Dry run: nothing will be written to Redmine")
|
||||
else:
|
||||
logging.warning("Missing issues will be created in Backport tracker "
|
||||
logging.warning("Missing issues will be created in Backport tracker "
|
||||
"of the relevant Redmine project")
|
||||
|
||||
def process_resolve_parent_option(a):
|
||||
global resolve_parent
|
||||
resolve_parent = a.resolve_parent
|
||||
if a.resolve_parent:
|
||||
logging.warning("Parent issues with all backports resolved will be marked Resolved")
|
||||
|
||||
def connect_to_redmine(a):
|
||||
if a.key:
|
||||
logging.info("Redmine key was provided; using it")
|
||||
@ -154,8 +163,10 @@ def get_release(issue):
|
||||
return field['value']
|
||||
|
||||
def update_relations(r, issue, dry_run):
|
||||
global resolve_parent
|
||||
relations = r.issue_relation.filter(issue_id=issue['id'])
|
||||
existing_backports = set()
|
||||
existing_backports_dict = {}
|
||||
for relation in relations:
|
||||
other = r.issue.get(relation['issue_to_id'])
|
||||
if other['tracker']['name'] != 'Backport':
|
||||
@ -173,10 +184,13 @@ def update_relations(r, issue, dry_run):
|
||||
" backport issue detected")
|
||||
continue
|
||||
existing_backports.add(release)
|
||||
existing_backports_dict[release] = relation['issue_to_id']
|
||||
logging.debug(url(issue) + " backport to " + release + " is " +
|
||||
redmine_endpoint + "/issues/" + str(relation['issue_to_id']))
|
||||
if existing_backports == issue['backports']:
|
||||
logging.debug(url(issue) + " has all the required backport issues")
|
||||
if resolve_parent:
|
||||
maybe_resolve(issue, existing_backports_dict, dry_run)
|
||||
return None
|
||||
if existing_backports.issuperset(issue['backports']):
|
||||
logging.error(url(issue) + " has more backport issues (" +
|
||||
@ -211,6 +225,43 @@ def update_relations(r, issue, dry_run):
|
||||
release + " " + url(other))
|
||||
return None
|
||||
|
||||
def maybe_resolve(issue, backports, dry_run):
|
||||
'''
|
||||
issue is a parent issue in Pending Backports status, and backports is a dict
|
||||
like, e.g., { "luminous": 25345, "mimic": 32134 }.
|
||||
If all the backport issues are Resolved, set the parent issue to Resolved, too.
|
||||
'''
|
||||
global delay_seconds
|
||||
global redmine
|
||||
global status2status_id
|
||||
pending_backport_status_id = status2status_id["Pending Backport"]
|
||||
resolved_status_id = status2status_id["Resolved"]
|
||||
logging.debug("entering maybe_resolve with parent issue ->{}<- backports ->{}<-"
|
||||
.format(issue.id, backports))
|
||||
assert issue.status.id == pending_backport_status_id, \
|
||||
"Parent Redmine issue ->{}<- has status ->{}<- (expected Pending Backport)".format(issue.id, issue.status)
|
||||
all_resolved = True
|
||||
for backport in backports.keys():
|
||||
tracker_issue_id = backports[backport]
|
||||
backport_issue = redmine.issue.get(tracker_issue_id)
|
||||
logging.debug("{} backport is in status {}".format(backport, backport_issue.status.name))
|
||||
if backport_issue.status.id != resolved_status_id:
|
||||
all_resolved = False
|
||||
break
|
||||
if all_resolved:
|
||||
logging.debug("Parent ->{}<- all backport issues in status Resolved".format(url(issue)))
|
||||
note = ("While running with --resolve-parent, the script \"backport-create-issue\" "
|
||||
"noticed that all backports of this issue are in status \"Resolved\".")
|
||||
if dry_run:
|
||||
logging.info("Set status of parent ->{}<- to Resolved".format(url(issue)))
|
||||
else:
|
||||
redmine.issue.update(issue.id, status_id=resolved_status_id, notes=note)
|
||||
logging.info("Parent ->{}<- status changed from Pending Backport to Resolved".format(url(issue)))
|
||||
logging.debug("Rate-limiting to avoid seeming like a spammer")
|
||||
time.sleep(delay_seconds)
|
||||
else:
|
||||
logging.debug("Some backport issues are still unresolved: leaving parent issue open")
|
||||
|
||||
def iterate_over_backports(r, issues, dry_run):
|
||||
counter = 0
|
||||
for issue in issues:
|
||||
@ -237,6 +288,7 @@ def iterate_over_backports(r, issues, dry_run):
|
||||
if __name__ == '__main__':
|
||||
args = parse_arguments()
|
||||
set_logging_level(args)
|
||||
process_resolve_parent_option(args)
|
||||
report_dry_run(args)
|
||||
redmine = connect_to_redmine(args)
|
||||
project = redmine.project.get(project_name)
|
||||
|
Loading…
Reference in New Issue
Block a user