]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
tools: ceph-release-notes handle multiple issues
authorLoic Dachary <ldachary@redhat.com>
Wed, 30 Sep 2015 16:58:40 +0000 (18:58 +0200)
committerLoic Dachary <ldachary@redhat.com>
Fri, 2 Oct 2015 15:47:12 +0000 (17:47 +0200)
* handle the case where a single pull request is associated with
  multiple pull requests
* encapsulate the quest for the original in a function for easier
  maintenance
* add the --verbose flag for debugging

Signed-off-by: Loic Dachary <ldachary@redhat.com>
src/script/ceph-release-notes

index 0075c9d4a33b3e34cef366515c91ee5ac805c0f2..389a1fca96061da543ab08c6013f5e9617cb54b7 100755 (executable)
@@ -40,57 +40,67 @@ tracker_re = re.compile("http://tracker.ceph.com/issues/(\d+)")
 signed_off_re = re.compile("Signed-off-by: (.+) <")
 tracker_uri = "http://tracker.ceph.com/issues/{0}.json"
 
-def make_release_notes(gh, repo, ref, plaintext,original_issue):
+def get_original_issue(issue, verbose):
+    r = requests.get(tracker_uri.format(issue),params={"include":"relations"}).json()
+
+    # looking up for the original issue only makes sense
+    # when dealing with an issue in the Backport tracker
+    if r["issue"]["tracker"]["name"] != "Backport":
+        if verbose:
+            print ("http://tracker.ceph.com/issues/" + issue + " is from the tracker " + r["issue"]["tracker"]["name"] + ", do not look for the original issue")
+        return issue
+
+    # if a Backport issue does not have a relation, keep it
+    if "relations" not in r["issue"]:
+        if verbose:
+            print ("http://tracker.ceph.com/issues/" + issue + " has no relations, do not look for the original issue")
+        return issue
+    
+    copied_to = [str(i['issue_id']) for i in r["issue"]["relations"] if i["relation_type"] == "copied_to"]
+    if copied_to:
+        if len(copied_to) > 1:
+            if verbose:
+                print ("ERROR: http://tracker.ceph.com/issues/" + issue + " has more than one Copied To relation")
+            return issue
+        if verbose:
+            print ("http://tracker.ceph.com/issues/" + issue + " is the backport of http://tracker.ceph.com/issues/" + copied_to[0])
+        return copied_to[0]
+    else:
+        if verbose:
+            print ("http://tracker.ceph.com/issues/" + issue + " has no copied_to relations, do not look for the original issue")
+        return issue
+
+
+def make_release_notes(gh, repo, ref, plaintext, verbose):
 
     issue2prs = {}
 
     for commit in repo.iter_commits(ref):
         merge = merge_re.match(commit.summary)
         if merge:
-            issue = ''
             number = merge.group(1)
             pr = gh.repos("ceph")("ceph").pulls(number).get()
             # We are not handling multiple issues here yet
             if pr['body']:
-                fixes = fixes_re.findall(pr['body'])
-                tracker = tracker_re.findall(pr['body'])
-                if tracker:
-                    issue = ','.join(tracker)
-                elif fixes:
-                    issue = ','.join(fixes)
-
-            if not issue:
+                issues = fixes_re.findall(pr['body']) + tracker_re.findall(pr['body'])
+
+            if not issues:
                 print ("ERROR: http://github.com/ceph/ceph/pull/" + str(number) + " has no associated issue")
                 continue    
+            
+            for issue in issues:
+                issue = get_original_issue(issue, verbose)
+
+                title = pr['title']
 
-            if original_issue:
-                r = requests.get(tracker_uri.format(issue),params={"include":"relations"})
-
-                # Verify that we are indeed looking at a backports issue
-                if r.json()["issue"]["tracker"]["name"] != "Backport":
-                    continue
-
-                # Now we can get an original issue only if the
-                # relations field is populated, otherwise we fallback
-                # to the tracker number
-                try:
-                    relations = r.json()["issue"]["relations"]
-                except KeyError:
-                    continue
-                related_issues = [str(i['issue_id']) for i in relations if i["relation_type"] == "copied_to"]
-                if related_issues:
-                    issue = ','.join(related_issues)
-
-            title = pr['title']
-
-            title_re = '^(cli|common|mon|osd|fs|librbd|rbd|fs|mds|objecter|rgw|build/ops|tests|tools|doc|crush|librados):'
-            if not re.match(title_re, title):
-                print ("ERROR: http://github.com/ceph/ceph/pull/" + str(number) + " title " + title + " does not match " + title_re)
-            # Big assumption, do a sanity check in the end, we are
-            # getting the author of final merge commit
-            author = commit.parents[-1].author.name
-            issue2prs.setdefault(issue, []).append((author, title, number))
-            sys.stdout.write('.')
+                title_re = '^(cli|common|mon|osd|fs|librbd|rbd|fs|mds|objecter|rgw|build/ops|tests|tools|doc|crush|librados):'
+                if not re.match(title_re, title):
+                    print ("ERROR: http://github.com/ceph/ceph/pull/" + str(number) + " title " + title + " does not match " + title_re)
+                # Big assumption, do a sanity check in the end, we are
+                # getting the author of final merge commit
+                author = commit.parents[-1].author.name
+                issue2prs.setdefault(issue, []).append((author, title, number))
+                sys.stdout.write('.')
 
     print (" done collecting merges.")
 
@@ -111,18 +121,16 @@ if __name__ == "__main__":
     parser.add_argument("--text", "-t",
                         action='store_true', default=None,
                         help="output plain text only, no links")
+    parser.add_argument("--verbose", "-v",
+                        action='store_true', default=None,
+                        help="verbose")
     parser.add_argument("repo", metavar="repo",
                         help="path to ceph git repo")
     parser.add_argument("--token", default=os.getenv("GITHUB_ACCESS_TOKEN"),
                         help="Github Access Token ($GITHUB_ACCESS_TOKEN otherwise)")
-    parser.add_argument("--original_issue", dest='original_issue', action='store_true',
-                        help="When the issue id is a backport, use original upstream issue id instead (default)")
-    parser.add_argument("--no_original_issue", dest='original_issue', action='store_false',
-                        help="When the issue id is a backport, don't use original upstream issue id instead")
-    parser.set_defaults(original_issue=True)
 
     args = parser.parse_args()
     gh = github.GitHub(
         access_token=args.token)
 
-    make_release_notes(gh, Repo(args.repo), args.rev, args.text, args.original_issue)
+    make_release_notes(gh, Repo(args.repo), args.rev, args.text, args.verbose)