132 lines
4.1 KiB
Python
132 lines
4.1 KiB
Python
#!/usr/bin/python3
|
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
"""Create (or find) the Bugzilla bug for a new Nightly development cycle.
|
|
|
|
If a bug with the expected summary already exists, its ID is reused so
|
|
that retries don't produce duplicates.
|
|
|
|
Usage:
|
|
BUGZILLA_API_KEY=<key> python3 create-nightly-bug.py <VERSION>
|
|
|
|
Set --staging to use bugzilla-dev.allizom.org for testing.
|
|
The bug ID is printed to stdout; status messages go to stderr.
|
|
"""
|
|
|
|
import json
|
|
import os
|
|
import sys
|
|
import urllib.error
|
|
import urllib.parse
|
|
import urllib.request
|
|
|
|
BUGZILLA_PROD_URL = "https://bugzilla.mozilla.org/rest/bug"
|
|
BUGZILLA_STAGING_URL = "https://bugzilla-dev.allizom.org/rest/bug"
|
|
PRODUCT = "Firefox for Android"
|
|
COMPONENT = "General"
|
|
SUMMARY_TEMPLATE = "Start the nightly {} development cycle"
|
|
RELEASE_CHECKLIST_URL = (
|
|
"https://firefox-source-docs.mozilla.org/mobile/android/fenix/"
|
|
"release-checklist.html"
|
|
"#dev-team-starting-the-next-nightly-development-cycle"
|
|
)
|
|
|
|
|
|
def _bugzilla_request(url, data=None, api_key=None):
|
|
if api_key:
|
|
sep = "&" if "?" in url else "?"
|
|
url = f"{url}{sep}api_key={api_key}"
|
|
req = urllib.request.Request(
|
|
url,
|
|
data=data,
|
|
headers={"Content-Type": "application/json"} if data else {},
|
|
)
|
|
try:
|
|
with urllib.request.urlopen(req) as resp:
|
|
return json.loads(resp.read())
|
|
except urllib.error.HTTPError as e:
|
|
body = e.read().decode("utf-8", errors="replace")
|
|
print(f"ERROR: Bugzilla API returned {e.code}: {body}", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
|
|
def find_existing_bug(base_url, version, api_key):
|
|
params = urllib.parse.urlencode({
|
|
"product": PRODUCT,
|
|
"component": COMPONENT,
|
|
"summary": SUMMARY_TEMPLATE.format(version),
|
|
})
|
|
result = _bugzilla_request(f"{base_url}?{params}", api_key=api_key)
|
|
expected = SUMMARY_TEMPLATE.format(version)
|
|
for bug in result.get("bugs", []):
|
|
if bug["summary"] == expected:
|
|
return bug["id"]
|
|
return None
|
|
|
|
|
|
def create_bug(base_url, version, api_key):
|
|
summary = SUMMARY_TEMPLATE.format(version)
|
|
description = (
|
|
"Follow **[[Dev team] Starting the next Nightly development cycle]"
|
|
f"({RELEASE_CHECKLIST_URL})**"
|
|
)
|
|
payload = json.dumps({
|
|
"product": PRODUCT,
|
|
"component": COMPONENT,
|
|
"summary": summary,
|
|
"description": description,
|
|
"type": "task",
|
|
"version": "unspecified",
|
|
"op_sys": "Android",
|
|
"platform": "All",
|
|
}).encode("utf-8")
|
|
result = _bugzilla_request(base_url, data=payload, api_key=api_key)
|
|
return result["id"]
|
|
|
|
|
|
def main():
|
|
args = sys.argv[1:]
|
|
staging = "--staging" in args
|
|
if staging:
|
|
args.remove("--staging")
|
|
|
|
if len(args) != 1 or not args[0].isdigit():
|
|
print("Usage: create-nightly-bug.py [--staging] VERSION", file=sys.stderr)
|
|
print("Example: create-nightly-bug.py 150", file=sys.stderr)
|
|
print(" create-nightly-bug.py --staging 150", file=sys.stderr)
|
|
print("", file=sys.stderr)
|
|
print("Requires BUGZILLA_API_KEY environment variable.", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
version = args[0]
|
|
base_url = BUGZILLA_STAGING_URL if staging else BUGZILLA_PROD_URL
|
|
api_key = os.environ.get("BUGZILLA_API_KEY")
|
|
if not api_key:
|
|
print(
|
|
"ERROR: BUGZILLA_API_KEY environment variable is not set.",
|
|
file=sys.stderr,
|
|
)
|
|
sys.exit(1)
|
|
|
|
if staging:
|
|
print("Using staging instance (bugzilla-dev.allizom.org).", file=sys.stderr)
|
|
|
|
existing = find_existing_bug(base_url, version, api_key)
|
|
if existing:
|
|
print(
|
|
f"Bug {existing} already exists for nightly {version}.",
|
|
file=sys.stderr,
|
|
)
|
|
print(existing)
|
|
return
|
|
|
|
bug_id = create_bug(base_url, version, api_key)
|
|
print(f"Created bug {bug_id} for nightly {version}.", file=sys.stderr)
|
|
print(bug_id)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|