| |
@@ -1,4 +1,4 @@
|
| |
- #!/bin/python3
|
| |
+ #!/usr/bin/env python3
|
| |
|
| |
# Copyright Red Hat
|
| |
#
|
| |
@@ -19,7 +19,7 @@
|
| |
|
| |
"""Fedora release blocker / freeze exception bug tracker update script."""
|
| |
|
| |
- import getpass
|
| |
+ import argparse
|
| |
import sys
|
| |
|
| |
import bugzilla
|
| |
@@ -29,17 +29,38 @@
|
| |
MILESTONES = ("Beta", "Final")
|
| |
TYPES = (("Blocker", "blocker"), ("FreezeException", "freeze exception"))
|
| |
|
| |
- BLOCKTMP = """Fedora {release} {milestone} blocker tracker bug: http://fedoraproject.org/wiki/BugZappers/HouseKeeping/Trackers
|
| |
+ BLOCKTMP = """Fedora {release} {milestone} blocker tracker bug: \
|
| |
+ https://{fpo}/wiki/BugZappers/HouseKeeping/Trackers
|
| |
|
| |
- To propose a bug as blocking the Fedora {release} {milestone} release, mark it as blocking this bug, or use the webapp: https://qa.fedoraproject.org/blockerbugs/propose_bug . It will be reviewed according to https://fedoraproject.org/wiki/QA:SOP_blocker_bug_process . If you can, please specify the release criterion that the bug violates. See https://fedoraproject.org/wiki/Fedora_Release_Criteria for details on the release criteria.
|
| |
+ To propose a bug as blocking the Fedora {release} {milestone} release, mark it as blocking this \
|
| |
+ bug, or use the webapp: https://qa.{fpo}/blockerbugs/propose_bug . It will be reviewed according \
|
| |
+ to https://{fpo}/wiki/QA:SOP_blocker_bug_process . If you can, please specify the release \
|
| |
+ criterion that the bug violates. See https://{fpo}/wiki/Fedora_Release_Criteria for details on the \
|
| |
+ release criteria.
|
| |
|
| |
- If the bug is not serious enough to block release but you believe it merits being fixed during a milestone freeze (see https://fedoraproject.org/wiki/Milestone_freezes ), you can propose it as a 'freeze exception' instead. To do this, mark it as blocking the bug F{release}{milestone}FreezeException . See https://fedoraproject.org/wiki/QA:SOP_freeze_exception_bug_process for the freeze exception process."""
|
| |
+ If the bug is not serious enough to block release but you believe it merits being fixed during a \
|
| |
+ milestone freeze (see https://{fpo}/wiki/Milestone_freezes ), you can propose it as a 'freeze \
|
| |
+ exception' instead. To do this, mark it as blocking the bug F{release}{milestone}FreezeException . \
|
| |
+ See https://{fpo}/wiki/QA:SOP_freeze_exception_bug_process for the freeze exception process."""
|
| |
|
| |
- FETMP = """Fedora {release} {milestone} freeze exception bug tracker: http://fedoraproject.org/wiki/BugZappers/HouseKeeping/Trackers
|
| |
+ FETMP = """Fedora {release} {milestone} freeze exception bug tracker: \
|
| |
+ https://{fpo}/wiki/BugZappers/HouseKeeping/Trackers
|
| |
|
| |
- To propose a bug as a freeze exception bug for the Fedora {release} {milestone} release, mark it as blocking this bug, or use the webapp: https://qa.fedoraproject.org/blockerbugs/propose_bug . It will be reviewed according to https://fedoraproject.org/wiki/QA:SOP_freeze_exception_bug_process .
|
| |
+ To propose a bug as a freeze exception bug for the Fedora {release} {milestone} release, mark it \
|
| |
+ as blocking this bug, or use the webapp: https://qa.{fpo}/blockerbugs/propose_bug . It will be \
|
| |
+ reviewed according to https://{fpo}/wiki/QA:SOP_freeze_exception_bug_process .
|
| |
|
| |
- If you think the bug is sufficiently serious to block the {milestone} release, instead mark it as blocking the bug F{release}{milestone}Blocker. See https://fedoraproject.org/wiki/QA:SOP_blocker_bug_process for the blocker process."""
|
| |
+ If you think the bug is sufficiently serious to block the {milestone} release, instead mark it as \
|
| |
+ blocking the bug F{release}{milestone}Blocker. See \
|
| |
+ https://{fpo}/wiki/QA:SOP_blocker_bug_process for the blocker process."""
|
| |
+
|
| |
+ def get_argparser():
|
| |
+ parser = argparse.ArgumentParser()
|
| |
+ parser.add_argument('release', metavar='RELEASE', type=int, help='The Fedora release number '
|
| |
+ 'that was finalized, e.g. 36')
|
| |
+ parser.add_argument('--stg', action='store_true', help='Use the staging instance of Bugzilla '
|
| |
+ 'and Wiki')
|
| |
+ return parser
|
| |
|
| |
def get_mile_type(alias):
|
| |
"""Find the milestone and blocker type from an alias, we do this
|
| |
@@ -79,14 +100,13 @@
|
| |
}
|
| |
return bzapi.query(query)
|
| |
|
| |
- def update_current(rel, bzapi):
|
| |
+ def update_current(rel, bzapi, fpohost):
|
| |
"""Close the trackers for the new release and remove the generic
|
| |
aliases from them.
|
| |
"""
|
| |
update = bzapi.build_update(status="CLOSED", resolution="CURRENTRELEASE",
|
| |
- comment="Fedora {0} was released. Bug closed per "
|
| |
- "https://fedoraproject.org/wiki/BugZappers/HouseKeeping/Trackers"
|
| |
- .format(rel))
|
| |
+ comment=f"Fedora {rel} was released. Bug closed per "
|
| |
+ f"https://{fpohost}/wiki/BugZappers/HouseKeeping/Trackers")
|
| |
# build_update can't handle multiple aliases, so we do this manually.
|
| |
update['alias'] = {'remove': get_aliases()}
|
| |
# we have to go one by one, as you can't do alias changes on multiple
|
| |
@@ -113,7 +133,7 @@
|
| |
bzapi.update_bugs([bug.id], update)
|
| |
return bugs
|
| |
|
| |
- def update_nextnext(rel, bzapi):
|
| |
+ def update_nextnext(rel, bzapi, fpohost):
|
| |
"""Create the trackers for the release after next."""
|
| |
# sanity check: don't re-create
|
| |
existing = get_trackers(rel, bzapi)
|
| |
@@ -125,11 +145,11 @@
|
| |
for alias in get_aliases(rel):
|
| |
(mile, typ) = get_mile_type(alias)
|
| |
if typ == "blocker":
|
| |
- desc = BLOCKTMP.format(release=rel, milestone=mile)
|
| |
- url = "https://fedoraproject.org/wiki/QA:SOP_blocker_bug_process"
|
| |
+ desc = BLOCKTMP.format(release=rel, milestone=mile, fpo=fpohost)
|
| |
+ url = f"https://{fpohost}/wiki/QA:SOP_blocker_bug_process"
|
| |
else:
|
| |
- desc = FETMP.format(release=rel, milestone=mile)
|
| |
- url = "https://fedoraproject.org/wiki/QA:SOP_freeze_exception_bug_process"
|
| |
+ desc = FETMP.format(release=rel, milestone=mile, fpo=fpohost)
|
| |
+ url = f"https://{fpohost}/wiki/QA:SOP_freeze_exception_bug_process"
|
| |
|
| |
print("Creating {0} tracker for {1} with alias {2}".format(typ, mile, alias))
|
| |
create = bzapi.build_createbug(
|
| |
@@ -149,13 +169,13 @@
|
| |
# as it makes sure the alias info is included
|
| |
return get_trackers(rel, bzapi)
|
| |
|
| |
- def update_wiki(wiki, rel, currbugs, nxt, nxtbugs, nxnx, nxnxbugs):
|
| |
+ def update_wiki(wiki, rel, currbugs, nxt, nxtbugs, nxnx, nxnxbugs, bzhost):
|
| |
"""Edit the Trackers wiki page with all the changes."""
|
| |
print("Updating wiki page...")
|
| |
page = wiki.pages["BugZappers/HouseKeeping/Trackers"]
|
| |
pgtxt = page.text()
|
| |
|
| |
- def build_table(rel, bugs, gencol=True):
|
| |
+ def build_table(rel, bugs, bzhost, gencol=True):
|
| |
"""Inner function to build the table for a particular release.
|
| |
If gencol is True, the generic aliases will be included in the
|
| |
table. If it's None, there will be no column for a generic
|
| |
@@ -176,15 +196,18 @@
|
| |
name = "Fedora {0} {1}".format(rel, mile)
|
| |
if typ == "freeze exception":
|
| |
name += " Freeze Exception"
|
| |
+ if "stage" in bzhost:
|
| |
+ # the [[rhbug]] interwiki link always points to prod bz
|
| |
+ # there is no stg equivalent
|
| |
+ bugtext = f"[https://{bzhost}/show_bug.cgi?id={bugid} {bugid}]"
|
| |
+ else:
|
| |
+ bugtext = f"[[rhbug:{bugid}|{bugid}]]"
|
| |
if gencol is None:
|
| |
- text += "| {0} || {1} || [[rhbug:{2}|{2}]]\n|-\n".format(
|
| |
- name, alias, bugid)
|
| |
+ text += f"| {name} || {alias} || {bugtext}\n|-\n"
|
| |
elif gencol:
|
| |
- text += "| {0} || {1} || {2} || [[rhbug:{3}|{3}]]\n|-\n".format(
|
| |
- name, generic, alias, bugid)
|
| |
+ text += f"| {name} || {generic} || {alias} || {bugtext}\n|-\n"
|
| |
else:
|
| |
- text += "| {0} || - || {1} || [[rhbug:{2}|{2}]]\n|-\n".format(
|
| |
- name, alias, bugid)
|
| |
+ text += f"| {name} || - || {alias} || {bugtext}\n|-\n"
|
| |
text += "|}\n\n"
|
| |
return text
|
| |
|
| |
@@ -192,13 +215,13 @@
|
| |
sep = "Past Tracker Bugs ==\n\n"
|
| |
pos = pgtxt.index(sep)
|
| |
newtxt = pgtxt[:pos+len(sep)]
|
| |
- newtxt += build_table(rel, currbugs, gencol=None)
|
| |
+ newtxt += build_table(rel, currbugs, bzhost, gencol=None)
|
| |
newtxt += pgtxt[pos+len(sep):]
|
| |
|
| |
# Re-create all the 'current' tracker text
|
| |
currtxt = "== Current Tracker Bugs ==\n\n"
|
| |
- currtxt += build_table(nxt, nxtbugs, gencol=True)
|
| |
- currtxt += build_table(nxnx, nxnxbugs, gencol=False)
|
| |
+ currtxt += build_table(nxt, nxtbugs, bzhost, gencol=True)
|
| |
+ currtxt += build_table(nxnx, nxnxbugs, bzhost, gencol=False)
|
| |
|
| |
# Throw away the top of the page and replace it with currtext
|
| |
pos = newtxt.index("== Policy ==")
|
| |
@@ -207,26 +230,39 @@
|
| |
|
| |
def run():
|
| |
"""Main logic."""
|
| |
- if len(sys.argv) != 2 or not sys.argv[1].isdigit():
|
| |
- sys.exit("Usage: {0} NN, where NN is the release that was finalized".format(sys.argv[0]))
|
| |
+ parser = get_argparser()
|
| |
+ args = parser.parse_args()
|
| |
+ bzhost = "bugzilla.redhat.com"
|
| |
+ fpohost = "fedoraproject.org"
|
| |
+ if args.stg:
|
| |
+ bzhost = "bugzilla.stage.redhat.com"
|
| |
+ fpohost = "stg.fedoraproject.org"
|
| |
+ print("Will use the staging instances.")
|
| |
|
| |
- bzapi = bugzilla.Bugzilla("bugzilla.redhat.com")
|
| |
+ bzapi = bugzilla.Bugzilla(url=bzhost, tokenfile=None)
|
| |
+ if not bzapi.api_key:
|
| |
+ print("ERROR: You must configure a Bugzilla API key. Log in to Bugzilla in a web browser, "
|
| |
+ f"create an API key, and then run `bugzilla --bugzilla {bzhost} login --api-key` to "
|
| |
+ "create a python-bugzilla config file with the API key stored.", file=sys.stderr)
|
| |
+ sys.exit(1)
|
| |
+ if not bzapi.logged_in:
|
| |
+ print("ERROR: Bugzilla login failed for some reason. An invalid API key?", file=sys.stderr)
|
| |
+ sys.exit(1)
|
| |
# this solves a problem with Bug instances returned by build_createbug
|
| |
# not knowing what their aliases are...
|
| |
bzapi.bug_autorefresh = True
|
| |
- if not bzapi.logged_in:
|
| |
- bzapi.interactive_login()
|
| |
- wiki = wikitcms.wiki.Wiki(host='fedoraproject.org')
|
| |
+
|
| |
+ wiki = wikitcms.wiki.Wiki(host=fpohost)
|
| |
wiki.login()
|
| |
|
| |
- rel = int(sys.argv[1])
|
| |
+ rel = args.release
|
| |
nxt = str(rel + 1)
|
| |
nxnx = str(rel + 2)
|
| |
rel = str(rel)
|
| |
- currbugs = update_current(rel, bzapi)
|
| |
+ currbugs = update_current(rel, bzapi, fpohost)
|
| |
nxtbugs = update_next(nxt, bzapi)
|
| |
- nxnxbugs = update_nextnext(nxnx, bzapi)
|
| |
- update_wiki(wiki, rel, currbugs, nxt, nxtbugs, nxnx, nxnxbugs)
|
| |
+ nxnxbugs = update_nextnext(nxnx, bzapi, fpohost)
|
| |
+ update_wiki(wiki, rel, currbugs, nxt, nxtbugs, nxnx, nxnxbugs, bzhost)
|
| |
|
| |
try:
|
| |
run()
|
| |
Allows to update staging bugzilla and staging wiki (and also test it there,
if needed). Bugzilla API key is now required, due to changes in upstream
Bugzilla. Argparse is used instead of manual args handling.
Fixes: https://pagure.io/fedora-qa/qa-misc/issue/7
This was already tested on stg and it worked fine.