From d9a411e60c6744a262aeb22d8a738c8b09f4fa8c Mon Sep 17 00:00:00 2001 From: Raphael 'kena' Poss Date: Sat, 9 Nov 2019 18:45:04 +0100 Subject: [PATCH 1/2] scripts/release-notes.py: lint fixes Release note: None --- scripts/release-notes.py | 47 +++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/scripts/release-notes.py b/scripts/release-notes.py index c3ebb40307ce..40c112f0a83b 100755 --- a/scripts/release-notes.py +++ b/scripts/release-notes.py @@ -29,8 +29,9 @@ import sys import itertools import re -import os -import datetime, time +import datetime +import time +from gitdb import exc import subprocess from git import Repo from optparse import OptionParser @@ -256,34 +257,38 @@ repo = Repo('.') heads = repo.heads + def reformat_note(note_lines): sep = '\n' if options.one_line: sep = ' ' return sep.join(note_lines).strip() + # Check that pull_ref_prefix is valid testrefname = "%s/1" % pull_ref_prefix + try: repo.commit(testrefname) -except: +except exc.ODBError: print("Unable to find pull request refs at %s." % pull_ref_prefix, file=sys.stderr) print("Is your repo set up to fetch them? Try adding", file=sys.stderr) print(" fetch = +refs/pull/*/head:%s/*" % pull_ref_prefix, file=sys.stderr) print("to the GitHub remote section of .git/config.", file=sys.stderr) exit(1) + def find_commits(from_commit_ref, until_commit_ref): try: firstCommit = repo.commit(from_commit_ref) - except: + except exc.ODBError: print("Unable to find the first commit of the range.", file=sys.stderr) print("No ref named %s." % from_commit_ref, file=sys.stderr) exit(1) try: commit = repo.commit(until_commit_ref) - except: + except exc.ODBError: print("Unable to find the last commit of the range.", file=sys.stderr) print("No ref named %s." % until_commit_ref, file=sys.stderr) exit(1) @@ -348,6 +353,7 @@ def check_reachability(firstCommit, commit): firstCommit, commit = check_reachability(firstCommit, commit) options.from_commit = firstCommit.hexsha + def extract_release_notes(commit): msglines = commit.message.split('\n') curnote = [] @@ -424,6 +430,7 @@ def extract_release_notes(commit): return foundnote, notes + spinner = itertools.cycle(['/', '-', '\\', '|']) counter = 0 def spin(): @@ -443,6 +450,7 @@ def get_direct_history(firstCommit, lastCommit): history.append(c) return history + excluded_notes = set() if excludedFirst is not None: # @@ -481,6 +489,7 @@ def get_direct_history(firstCommit, lastCommit): release_notes = {} missing_release_notes = [] + def collect_authors(commit): authors = set() author = author_aliases.get(commit.author.name, commit.author.name) @@ -515,6 +524,7 @@ def process_release_notes(pr, title, commit): missing_item = makeitem(pr, title, commit.hexsha[:shamin], authors) return missing_item, authors + def makeitem(pr, prtitle, sha, authors): return {'authors': ', '.join(sorted(authors)), 'sha': sha, @@ -522,6 +532,7 @@ def makeitem(pr, prtitle, sha, authors): 'title': prtitle, 'note': None} + def completenote(commit, cat, notemsg, authors, pr, title): item = makeitem(pr, title, commit.hexsha[:shamin], authors) item['note'] = notemsg @@ -531,10 +542,12 @@ def completenote(commit, cat, notemsg, authors, pr, title): catnotes.append(item) release_notes[cat] = catnotes + per_group_history = {} individual_authors = set() allprs = set() + # This function groups and counts all the commits that belong to a particular PR. # Some description is in order regarding the logic here: it should visit all # commits that are on the PR and only on the PR. If there's some secondary @@ -617,7 +630,6 @@ def analyze_pr(merge, pr): merge_base = merge_base_result[0] - commits_to_analyze = [tip] seen_commits = set() missing_items = [] @@ -650,6 +662,7 @@ def analyze_pr(merge, pr): collect_item(pr, note, merge.hexsha[:shamin], ncommits, authors, stats.total, merge.committed_date) + def collect_item(pr, prtitle, sha, ncommits, authors, stats, prts): individual_authors.update(authors) if len(authors) == 0: @@ -667,6 +680,7 @@ def collect_item(pr, prtitle, sha, ncommits, authors, stats, prts): history.append(item) per_group_history[item['authors']] = history + def analyze_standalone_commit(commit): # Some random out-of-branch commit. Let's not forget them. authors = collect_authors(commit) @@ -790,6 +804,8 @@ def analyze_standalone_commit(commit): seenshas = set() seenprs = set() + + def renderlinks(item): ret = '[%(pr)s][%(pr)s]' % item seenprs.add(item['pr']) @@ -798,6 +814,7 @@ def renderlinks(item): seenshas.add(item['sha']) return ret + for sec in relnote_sec_order: r = release_notes.get(sec, None) if r is None: @@ -858,16 +875,16 @@ def renderlinks(item): notified_authors = sorted(set(ext_contributors) | set(firsttime_contributors)) if len(notified_authors) > 0: - print("We would like to thank the following contributors from the CockroachDB community:") + print("We would like to thank the following contributors from the CockroachDB community:") + print() + for person in notified_authors: + print("-", person, end='') + if person in firsttime_contributors: + annot = "" + if person in crdb_folk: + annot = ", CockroachDB team member" + print(" (first-time contributor%s)" % annot, end='') print() - for person in notified_authors: - print("-", person, end='') - if person in firsttime_contributors: - annot = "" - if person in crdb_folk: - annot = ", CockroachDB team member" - print(" (first-time contributor%s)" % annot, end='') - print() print() ## Print the per-author contribution list. From a242b72b443cb414739de17861cab67dd7c6444e Mon Sep 17 00:00:00 2001 From: Raphael 'kena' Poss Date: Sat, 9 Nov 2019 21:02:49 +0100 Subject: [PATCH 2/2] scripts/release-notes.py: derive author aliases from AUTHORS Previously, the release-notes script contained an explicit list of contributors to the repo with their name aliases, to disambiguate entries in the git log while constructing the release notes report. The explicit list was problematic in numerous ways, foremost because it was often out of date and incomplete, and also because it couldn't distinguish different folk with the same name but different addresses. Luckily, Git has a standard solution for this problem, called a "mailmap" file. The format of this file is standardized and documented in the man page git-check-mailmap(1). To simplify, this file format has one line per _person_, and each line can contain multiple name/mail combinations for that person. Meanwhile, the CockroachDB repository also maintains a file `AUTHORS` at the top of the source tree. This also contains a list of contributors with names and e-mails, although for far this file was not maintained to conform exactly to Git's mailmap format. This commit bridges the two things as follows: - it updates the `AUTHORS` file to conform to the mailmap format. This removes duplicate entries, and spells out Git commit/author aliases alongside the primary name of a person. - it simplifies the release-notes script to use AUTHORS as its input database. Release note: None --- AUTHORS | 144 ++++++------- scripts/release-notes.py | 238 +++++++++++----------- scripts/release-notes/Makefile | 3 +- scripts/release-notes/common.sh | 1 + scripts/release-notes/test1.notes.ref.txt | 2 +- scripts/release-notes/test2.notes.ref.txt | 2 +- scripts/release-notes/test3.notes.ref.txt | 2 +- scripts/release-notes/test5.notes.ref.txt | 2 +- scripts/release-notes/test8.graph.ref.txt | 18 ++ scripts/release-notes/test8.notes.ref.txt | 45 ++++ scripts/release-notes/test8.sh | 37 ++++ 11 files changed, 301 insertions(+), 193 deletions(-) create mode 100644 scripts/release-notes/test8.graph.ref.txt create mode 100644 scripts/release-notes/test8.notes.ref.txt create mode 100644 scripts/release-notes/test8.sh diff --git a/AUTHORS b/AUTHORS index 138468b5460e..9aa659855a04 100644 --- a/AUTHORS +++ b/AUTHORS @@ -3,37 +3,48 @@ # Names should be added to this file as one of # Organization's name # Individual's name -# Individual's name - +# Individual's name [alias] [alias] +# +# If you wish to keep your @cockroachlabs.com address hidden, +# please still list <@cockroachlabs.com> (with no user name) +# in the list of aliases. +# +# (Note: there is no point in hiding it if it is mentioned +# in the git log already.) +# +# For more details about the format, see git-check-mailmap(1) +# # Please keep the list sorted. 1lann -aarondunnington -Abhemailk abhi.madan01@gmail.com -Abhishek Madan +Aaron Dunnington aarondunnington +Aayush Shah <@cockroachlabs.com> +Abhishek Madan Abhemailk abhi.madan01@gmail.com Abhishek Soni -AbhishekSaha +Abhishek Saha AbhishekSaha acoshift Adam Gee Adam Yao +Aditya Maru Aid Idrizović Ajaya Agrawal Alex Gaynor -Alex Robinson -Alfonso Subiotto Marqués +Alex Robinson <@cockroachlabs.com> +Alfonso Subiotto Marqués Alfonso Subiotto Marques Amos Bird -Amruta Ranade +Amruta Ranade Amruta Andrei Matei Andrew Bonventre Andrew Couch -Andrew Kimball <32096062+andy-kimball@users.noreply.github.com> -Andrew Kryczka +Andy Kimball <32096062+andy-kimball@users.noreply.github.com> Andrew Kimball +Andrew Kryczka Andrew Kryczka <@cockroachlabs.com> Andrew NS Yeow Andrew Werner -Andrew Woods +Andy Woods Andrew Woods Andrey Shinkevich +Angela Chang changangela Antoine Grondin -Arjun Ravi Narayan +Arjun Ravi Narayan Arjun Narayan Art Nikpal Arul Ajmani Asit Mahato @@ -42,47 +53,44 @@ Ben Darnell Bilal Akhtar Bob Potter Bob Vawter -Bogdan Batog -bogdanbatog +Bogdan Batog bogdanbatog Brad Seiler Bram Gruneir Brandon Gonzalez Brett Snyder Celia La Céline O'Neil -changangela chengwei <252684445@qq.com> -Chris Seto +Chris Seto <@cockroachlabs.com> Christian Meunier -christopherrouth -CMajeri +Christopher Routh christopherrouth +Chervine Majeri CMajeri Cockroach Labs Inc. coldwater Constantine Peresypkin -ctkou +Adam Kouct ctkou Cuong Do -Dan Kortschak -Daniel Harrison +Dan Kortschak kortschak +Daniel Harrison Daniel Theophanes Daniel Upton -Darin Peshev +Darin Peshev Darin <@cockroachlabs.com> David Eisenstat David López -David Taylor +David Taylor <@cockroachlabs.com> dchenk Dexter Valkyrie -Diana Hsieh -dianasaur323 -DiSiqueira +Diana Hsieh dianasaur323 dianasaur323 +Diego DiSiquera DiSiqueira Dmitry Saveliev Dmitry Vorobev Dominique Luna Dong Liang Dustin Hiatt -EamonZhang +Eamon Zhang EamonZhang Eli Lindsey embark -Emmanuel +Emmanuel Sales Emmanuel <@cockroachlabs.com> Erik Trinh es-chow Evgeniy Vasilev @@ -94,14 +102,13 @@ George Papadrosou George Utsin Georgia Hong Gustav Paul -Haines Chan -hainesc +Haines Chan hainesc Harshit Chopra Hayden A. James Ibrahim AshShohail Igor Kharin il9ue -irfan sharif +Irfan Sharif irfan sharif <@cockroachlabs.com> Isaac Rogers Israel Gilyadov Iuri Sitinschi @@ -113,11 +120,11 @@ Jason E. Aten Jason Young Jay Kominek Jeffrey Dallatezza -Jeffrey Xiao +Jeffrey Xiao <@cockroachlabs.com> Jesse Seldess Jessica Edwards Jiajia Han -jiangmingyang +Jiangming Yang jiangmingyang Jimmy Larsson Jincheng Li Jingguo Yao @@ -142,32 +149,31 @@ Karl Southern Kathy Spradlin Kenji Kaneda Kenjiro Nakayama +Kenneth Liu Kevin Guan kiran -kortschak lanzao <395818758@qq.com> Lasantha Pambagoda -Lauren Hirata +Lauren Hirata Lauren lhirata Lee Reilly Levon Lloyd -liuqi liyanan Lizhong -louishust +Louis Hust louishust Lu Guanqun -Lucy Zhang +Lucy Zhang M-srivatsa MaBo -madhavsuresh +Madhav Suresh madhavsuresh Mahmoud Al-Qudsi Maitri Morarji Manik Surtani -Marc Berhault +Marc Berhault marc MBerhault Marcus Westin Marko Bonaći Martin Bertschler Masha Schneider -Matt Jibson +Matt Jibson <@cockroachlabs.com> Matt Tracy Matthew O'Connor Max Lang @@ -175,22 +181,22 @@ Mayank Oli mbonaci Mo Firouz Mohamed Elqdusy -Nate +Nate Stewart Nate Nathan Johnson -Nathan VanBenschoten -Nathaniel Stewart +Nathan VanBenschoten <@cockroachlabs.com> +Nathan Stilwell neeral -nexdrew -ngaut +Andrew B. Goode nexdrew +ngaut liuqi goroutine Nick Nick Gottlieb -Nikhil Benesch +Nikhil Benesch <@cockroachlabs.com> Nishant Gupta noonan Oliver Tan Panos Mamatsis Paul Banks -Paul Bardea +Paul Bardea <@cockroachlabs.com> Peng Gao Pete Vilter <7341+vilterp@users.noreply.github.com> Peter Mattis @@ -199,16 +205,15 @@ Philippe Laflamme phynalle Piotr Zurek pocockn -Poornima -Radu Berinde +Poornima Malepati Poornima +Radu Berinde RaduBerinde Rafi Shamim -Raphael 'kena' Poss +Raphael 'kena' Poss kena Raphael Poss ReadmeCritic -Rebecca Taft -Rich Loveland +Rebecca Taft rytaft +Rich Loveland Richard Loveland Richard Artoul -Richard Loveland -Richard Wu +Richard Wu <@cockroachlabs.com> Ridwan Sharif Rohan Yadav Roland Crosby @@ -221,35 +226,36 @@ Sergei Turukin Seth Bunce shakeelrao Shawn Morel -Solon Gordon -songhao +Solon Gordon solongordon +Song Hao songhao Spas Bojanov -Spencer Kimball +Spencer Kimball +Sumeer Bhola sumeerbhola sum12 Syd <324760805@qq.com> Takuya Kuwahara -Tamir Duberstein -Tamir Duberstein and Kenji Kaneda +Tamir Duberstein <@cockroachlabs.com> +Tamir Duberstein and Kenji Kaneda <@cockroachlabs.com> Tarek Badr Teodor Pripoae Terrell Russell Thanakom Sangnetra Thomas Schroeter thundercw -tim-o <38867162+tim-o@users.noreply.github.com> +Tim O'Brien <38867162+tim-o@users.noreply.github.com> tim-o <38867162+tim-o@users.noreply.github.com> <@cockroachlabs.com> Timothy Chen -Tobias Schottdorf -Tristan Ohlson +Tobias Schottdorf <@cockroachlabs.com> +Tristan Ohlson <@cockroachlabs.com> Tristan Rice Txiaozhe Tyler Neely -Tyler Roberts +Tyler Roberts Tyler314 Umesh Yadav vagrant veteranlu <23907238@qq.com> Victor Chen Vijay Karthik -Vivek Menezes +Vivek Menezes vivekmenezes wenyong-h Will Haack Xiang Li @@ -257,7 +263,7 @@ Xinyu Zhou (Joe) XisiHuang xphoniex Xudong Zheng <7pkvm5aw@slicealias.com> -Yahor Yuzefovich +Yahor Yuzefovich yuzefovich Yan Long yananzhi Yang Yuting @@ -266,8 +272,8 @@ Yevgeniy Miretskiy Yosi Attias yuhit Yulei Xiao <21739034@qq.com> -yznming +Rafael Yim yznming Zach Brock -Zachary.smith +Zachary Smith Zachary.smith 何羿宏 智雅楠 diff --git a/scripts/release-notes.py b/scripts/release-notes.py index 40c112f0a83b..cb3bf6208238 100755 --- a/scripts/release-notes.py +++ b/scripts/release-notes.py @@ -37,112 +37,112 @@ from optparse import OptionParser from git.repo.fun import name_to_object from git.util import Stats +import os.path ### Global behavior constants ### # minimum sha length to disambiguate shamin = 9 -# FIXME(knz): This probably needs to use the .mailmap. -author_aliases = { - 'changangela': "Angela Chang", - 'dianasaur323': "Diana Hsieh", - 'kena': "Raphael 'kena' Poss", - 'vivekmenezes': "Vivek Menezes", - 'Darin':"Darin Peshev", - 'RaduBerinde': "Radu Berinde", - 'Andy Kimball': "Andrew Kimball", - 'marc': "Marc Berhault", - 'Lauren': "Lauren Hirata", - 'lhirata' : "Lauren Hirata", - 'Emmanuel': "Emmanuel Sales", - 'MBerhault': "Marc Berhault", - 'Nate': "Nathaniel Stewart", - 'a6802739': "Song Hao", - 'Abhemailk abhi.madan01@gmail.com': "Abhishek Madan", - 'rytaft': "Rebecca Taft", - 'songhao': "Song Hao", - 'solongordon': "Solon Gordon", - 'tim-o': "Tim O'Brien", - 'Tyler314': "Tyler Roberts", - 'Amruta': "Amruta Ranade", - 'yuzefovich': "Yahor Yuzefovich", - 'madhavsuresh': "Madhav Suresh", - 'Richard Loveland': "Rich Loveland", -} - -# FIXME(knz): This too. -crdb_folk = set([ - "Abhishek Madan", - "Alex Robinson", - "Alfonso Subiotto Marqués", - "Amruta Ranade", - "Andrei Matei", - "Andrew Couch", - "Andrew Kimball", - "Andrew Werner", - "Andrew Kryczka", - "Andy Woods", - "Aditya Maru", - "Angela Chang", - "Arjun Narayan", - "Ben Darnell", - "Bilal Akhtar", - "Bob Vawter", - "Bram Gruneir", - "Celia La", - "Daniel Harrison", - "David Taylor", - "Darin Peshev", - "Diana Hsieh", - "Emmanuel Sales", - "Erik Trinh", - "George Utsin", - "Jesse Seldess", - "Jessica Edwards", - "Joseph Lowinske", - "Joey Pereira", - "Jordan Lewis", - "Justin Jaffray", - "Jeffrey Xiao", - "Ken Liu", - "Kendra Curtis", - "Kuan Luo", - "Lauren Hirata", - "Lucy Zhang", - "Madhav Suresh", - "Marc Berhault", - "Masha Schneider", - "Matt Jibson", - "Matt Tracy", - "Nathan VanBenschoten", - "Nathaniel Stewart", - "Nikhil Benesch", - "Paul Bardea", - "Pete Vilter", - "Peter Mattis", - "Radu Berinde", - "Rafi Shamim", - "Raphael 'kena' Poss", - "Rebecca Taft", - "Rich Loveland", - "Richard Wu", - "Ridwan Sharif", - "Rohan Yadav", - "Roland Crosby", - "Sean Loiselle", - "Solon Gordon", - "Spencer Kimball", - "Tamir Duberstein", - "Tim O'Brien", - "Tobias Schottdorf", - "Tyler Roberts", - "Will Cross", - "Victor Chen", - "Vivek Menezes", - "Yahor Yuzefovich", -]) - +# Basic mailmap functionality using the AUTHORS file. +mmre = re.compile(r'^(?P.*?)\s+<(?P[^>]*)>(?P(?:[^<]*<[^>]*>)*)$') +mmare = re.compile('(?P[^<]*)<(?P[^>]*)>') +crdb_folk = set() +class P: + def __init__(self, name, addr): + self.name = name + self.email = addr + self.aliases = [(name, addr)] + self.crdb = '@cockroachlabs.com' in addr + if self.crdb: + crdb_folk.add(self) + def __repr__(self): + return "%s <%s>" % (self.name, self.email) + def __lt__(self, other): + return self.name < other.name or (self.name == other.name and self.email < other.email) +mmap_bycanon = {} +mmap_byaddr = {} +mmap_byname = {} +def define_person(name, addr): + p = P(name, addr) + canon = (name, addr) + if canon in mmap_bycanon: + print('warning: duplicate person %r, ignoring', canon) + return None + mmap_bycanon[canon] = p + byaddr = mmap_byaddr.get(addr, []) + byaddr.append(p) + mmap_byaddr[addr] = byaddr + byname = mmap_byname.get(name, []) + byname.append(p) + mmap_byname[name] = byname + return p + +if not os.path.exists('AUTHORS'): + print('warning: AUTHORS missing in current directory.', file=sys.stderr) + print('Maybe use "cd" to navigate to the working tree root.', file=sys.stderr) +else: + with open('AUTHORS', 'r') as f: + for line in f.readlines(): + if line.strip().startswith('#'): + continue + m = mmre.match(line) + if m is None: + continue + p = define_person(m.group('name'), m.group('addr')) + if p is None: + continue + p.crdb = '@cockroachlabs.com' in line + if p.crdb: + crdb_folk.add(p) + aliases = m.group('aliases') + aliases = mmare.findall(aliases) + for alias, addr in aliases: + name = alias.strip() + byaddr = mmap_byaddr.get(addr, []) + if p not in byaddr: + byaddr.append(p) + mmap_byaddr[addr] = byaddr + if name == '': + name = p.name + canon = (name, addr) + if canon in mmap_bycanon: + print('warning: duplicate alias %r, ignoring', canon) + continue + mmap_bycanon[canon] = p + p.aliases.append(canon) + byname = mmap_byname.get(name, []) + if p not in byname: + byname.append(p) + mmap_byname[name] = byname + +# lookup_person retrieves the main identity of a person given one of their +# names or email aliases in the mailmap. +def lookup_person(name, email): + key = (name, email) + if key in mmap_bycanon: + # lucky case. + return mmap_bycanon[key] + # Name+email didn't work. + # Let's see email next. + if email in mmap_byaddr: + candidates = mmap_byaddr[email] + if len(candidates) > 1: + print('warning: no direct name match for', (name, email), + 'and addr', email, 'is ambiguous,', + 'keeping as-is', file=sys.stderr) + return define_person(name, email) + return candidates[0] + # Email didn't work either. That's not great. + if name in mmap_byname: + candidates = mmap_byname[name] + if len(candidates) > 1: + print('warning: no direct name match for', (name, email), + 'and name', name, 'is ambiguous,', + 'keeping as-is', file=sys.stderr) + return define_person(name, email) + return candidates[0] + return define_person(name, email) # Section titles for release notes. relnotetitles = { @@ -492,15 +492,16 @@ def get_direct_history(firstCommit, lastCommit): def collect_authors(commit): authors = set() - author = author_aliases.get(commit.author.name, commit.author.name) - if author != 'GitHub': + author = lookup_person(commit.author.name, commit.author.email) + if author.name != 'GitHub': authors.add(author) - author = author_aliases.get(commit.committer.name, commit.committer.name) - if author != 'GitHub': + author = lookup_person(commit.committer.name, commit.committer.email) + if author.name != 'GitHub': authors.add(author) for m in coauthor.finditer(commit.message): aname = m.group('name').strip() - author = author_aliases.get(aname, aname) + amail = m.group('email').strip() + author = lookup_person(aname, amail) authors.add(author) return authors @@ -526,7 +527,7 @@ def process_release_notes(pr, title, commit): def makeitem(pr, prtitle, sha, authors): - return {'authors': ', '.join(sorted(authors)), + return {'authors': authors, 'sha': sha, 'pr': pr, 'title': prtitle, @@ -676,9 +677,11 @@ def collect_item(pr, prtitle, sha, ncommits, authors, stats, prts): 'date': datetime.date.fromtimestamp(prts).isoformat(), }) - history = per_group_history.get(item['authors'], []) - history.append(item) - per_group_history[item['authors']] = history + al = item['authors'] + k = str(sorted(al)) + history = per_group_history.get(k, (al, [])) + history[1].append(item) + per_group_history[k] = history def analyze_standalone_commit(commit): @@ -729,15 +732,12 @@ def analyze_standalone_commit(commit): firsttime_contributors = [] for a in individual_authors: # Find all aliases known for this person - aliases = [a] - for alias, name in author_aliases.items(): - if name == a: - aliases.append(alias) + aliases = a.aliases # Collect the history for every alias hist = b'' for al in aliases: spin() - c = subprocess.run(["git", "log", "--author=%s" % al, options.from_commit, '-n', '1'], stdout=subprocess.PIPE, check=True) + c = subprocess.run(["git", "log", "--author=%s <%s>" % al, options.from_commit, '-n', '1'], stdout=subprocess.PIPE, check=True) hist += c.stdout if len(hist) == 0: # No commit from that author older than the first commit @@ -851,7 +851,7 @@ def renderlinks(item): print("#### Changes without release note annotation") print() for item in missing_release_notes: - authors = item['authors'] + authors = ', '.join(str(x) for x in sorted(item['authors'])) print("- [%(pr)s][%(pr)s] [%(sha)s][%(sha)s] %(title)s" % item, "(%s)" % authors) seenshas.add(item['sha']) seenprs.add(item['pr']) @@ -878,10 +878,10 @@ def renderlinks(item): print("We would like to thank the following contributors from the CockroachDB community:") print() for person in notified_authors: - print("-", person, end='') + print("-", person.name, end='') if person in firsttime_contributors: annot = "" - if person in crdb_folk: + if person.crdb: annot = ", CockroachDB team member" print(" (first-time contributor%s)" % annot, end='') print() @@ -897,9 +897,9 @@ def renderlinks(item): fmt = " - %(date)s [%(pr)-6s][%(pr)-6s] (+%(insertions)4d -%(deletions)4d ~%(lines)4d/%(files)2d) %(title)s" for group in allgroups: - items = per_group_history[group] - print("- %s:" % group) + al, items = per_group_history[group] items.sort(key=lambda x:x[sortkey],reverse=not revsort) + print("- %s:" % ', '.join(a.name for a in sorted(al))) for item in items: print(fmt % item, end='') if not hideshas: diff --git a/scripts/release-notes/Makefile b/scripts/release-notes/Makefile index ac885ecb7ef6..ba20e19d2566 100644 --- a/scripts/release-notes/Makefile +++ b/scripts/release-notes/Makefile @@ -2,6 +2,7 @@ TESTS := $(wildcard test*.sh) BASH ?= /usr/bin/env bash PYTHON ?= python NOTESCRIPT := $(PWD)/../release-notes.py +TDIR := $(shell pwd) all: test @@ -15,7 +16,7 @@ test: $(TESTS:.sh=.test) @echo @echo "**** Testing for $* ****" @echo - $(BASH) $*.sh $(NOTESCRIPT) + $(BASH) $(TDIR)/$*.sh $(NOTESCRIPT) clean: rm -f *.graph.txt *.notes.txt diff --git a/scripts/release-notes/common.sh b/scripts/release-notes/common.sh index 286d5ac01639..b2470a37e80a 100644 --- a/scripts/release-notes/common.sh +++ b/scripts/release-notes/common.sh @@ -23,6 +23,7 @@ function test_init() { function init_repo() { git init touch foo; git add foo; git commit "${flags[@]}" -m "initial"; git tag initial + git tag v000-base } # Perform some arbitrary change. diff --git a/scripts/release-notes/test1.notes.ref.txt b/scripts/release-notes/test1.notes.ref.txt index 7d8a26dc6bec..bd7091ea9cbd 100644 --- a/scripts/release-notes/test1.notes.ref.txt +++ b/scripts/release-notes/test1.notes.ref.txt @@ -6,7 +6,7 @@ #### Changes without release note annotation -- [#unknown][#unknown] [e3a1f2c94][e3a1f2c94] master update (test1) +- [#unknown][#unknown] [e3a1f2c94][e3a1f2c94] master update (test1 ) ### Doc updates diff --git a/scripts/release-notes/test2.notes.ref.txt b/scripts/release-notes/test2.notes.ref.txt index 0b5431a5b67e..b271604a78cb 100644 --- a/scripts/release-notes/test2.notes.ref.txt +++ b/scripts/release-notes/test2.notes.ref.txt @@ -7,7 +7,7 @@ #### Changes without release note annotation -- [#unknown][#unknown] [f872999e8][f872999e8] master update (test2) +- [#unknown][#unknown] [f872999e8][f872999e8] master update (test2 ) ### Doc updates diff --git a/scripts/release-notes/test3.notes.ref.txt b/scripts/release-notes/test3.notes.ref.txt index 6dca361d0fce..3522b079d7e0 100644 --- a/scripts/release-notes/test3.notes.ref.txt +++ b/scripts/release-notes/test3.notes.ref.txt @@ -9,7 +9,7 @@ #### Changes without release note annotation -- [#unknown][#unknown] [4f4329fdc][4f4329fdc] master update (test3) +- [#unknown][#unknown] [4f4329fdc][4f4329fdc] master update (test3 ) ### Doc updates diff --git a/scripts/release-notes/test5.notes.ref.txt b/scripts/release-notes/test5.notes.ref.txt index 0d36c2a097bb..e07945a9cdaf 100644 --- a/scripts/release-notes/test5.notes.ref.txt +++ b/scripts/release-notes/test5.notes.ref.txt @@ -6,7 +6,7 @@ #### Changes without release note annotation -- [#2][#2] [8156afc96][8156afc96] PR title in need of release note (test5) +- [#2][#2] [8156afc96][8156afc96] PR title in need of release note (test5 ) ### Doc updates diff --git a/scripts/release-notes/test8.graph.ref.txt b/scripts/release-notes/test8.graph.ref.txt new file mode 100644 index 000000000000..31ecb4d9d9c1 --- /dev/null +++ b/scripts/release-notes/test8.graph.ref.txt @@ -0,0 +1,18 @@ +* 801acad030ef8c14766f72609287d323075af29b Merge pull request #200 from foo/bar +|\ +| * 4ba203f0af12e361707c20fa4254fe58f9c3a86e merge pr canary +|/ +* 20f736f8b7421f226d15111e2377a8e069972bf0 Merge #2 +|\ +| * fc02f2ab9ac0c1924c479fa601065235579a605e feature A2 +|/ +* ac02f9cf6095d6430c609812730a34fe254f5e77 Merge pull request #100 from foo/bar +|\ +| * 1fa346db29169f9d1c6f229e34e1e0b0af687af7 merge pr canary +|/ +* 931a977579e2e0f0efee763fa289bd2b3162755b Merge #1 +|\ +| * f76e64ed372d84433ac4c5e0a06e3dfe34a80686 feature A1 +|/ +* a1dec56519bfa4d850e2771bd9880d2dcdb715aa update AUTHORS +* 15d3108780a91a71af56bdaeb020dbdf650fd1ef initial diff --git a/scripts/release-notes/test8.notes.ref.txt b/scripts/release-notes/test8.notes.ref.txt new file mode 100644 index 000000000000..0b28b7c3e3c8 --- /dev/null +++ b/scripts/release-notes/test8.notes.ref.txt @@ -0,0 +1,45 @@ +### Miscellaneous + +#### Changes without release note annotation + +- [#2][#2] [fc02f2ab9][fc02f2ab9] PR 2 title (Foo Foo , test8 ) +- [#1][#1] [f76e64ed3][f76e64ed3] PR 1 title (Foo Foo , test8 ) +- [#unknown][#unknown] [a1dec5651][a1dec5651] update AUTHORS (test8 ) + +### Doc updates + +Docs team: Please add these manually. + +### Contributors + +This release includes 4 merged PRs by 2 authors. +We would like to thank the following contributors from the CockroachDB community: + +- Foo Foo (first-time contributor) +- test8 + +### PRs merged by contributors + +- Foo Foo, test8: + - 2018-04-22 [#2 ][#2 ] [20f736f8b][20f736f8b] (+ 0 - 0 ~ 0/ 0) PR 2 title + - 2018-04-22 [#1 ][#1 ] [931a97757][931a97757] (+ 0 - 0 ~ 0/ 0) PR 1 title + +- test8: + - 2018-04-22 [#unknown][#unknown] [a1dec5651][a1dec5651] (+ 1 - 0 ~ 1/ 1) update AUTHORS + - 2018-04-22 [#200 ][#200 ] [801acad03][801acad03] (+ 0 - 0 ~ 0/ 0) PR 2 title alternate format + - 2018-04-22 [#100 ][#100 ] [ac02f9cf6][ac02f9cf6] (+ 0 - 0 ~ 0/ 0) PR 1 title alternate format + + +[#1]: https://github.com/cockroachdb/cockroach/pull/1 +[#100]: https://github.com/cockroachdb/cockroach/pull/100 +[#2]: https://github.com/cockroachdb/cockroach/pull/2 +[#200]: https://github.com/cockroachdb/cockroach/pull/200 +[#unknown]: https://github.com/cockroachdb/cockroach/pull/unknown +[20f736f8b]: https://github.com/cockroachdb/cockroach/commit/20f736f8b +[801acad03]: https://github.com/cockroachdb/cockroach/commit/801acad03 +[931a97757]: https://github.com/cockroachdb/cockroach/commit/931a97757 +[a1dec5651]: https://github.com/cockroachdb/cockroach/commit/a1dec5651 +[ac02f9cf6]: https://github.com/cockroachdb/cockroach/commit/ac02f9cf6 +[f76e64ed3]: https://github.com/cockroachdb/cockroach/commit/f76e64ed3 +[fc02f2ab9]: https://github.com/cockroachdb/cockroach/commit/fc02f2ab9 + diff --git a/scripts/release-notes/test8.sh b/scripts/release-notes/test8.sh new file mode 100644 index 000000000000..d33d3815baad --- /dev/null +++ b/scripts/release-notes/test8.sh @@ -0,0 +1,37 @@ +#!/bin/sh +set -eux + +. common.sh + +t=test8 +relnotescript=${1:?} +rewrite=${2:-} + +test_init + +( + cd $t + init_repo + + cat >AUTHORS < foo +EOF + git add AUTHORS + make_change "update AUTHORS" + + git checkout -b feature + make_change "feature A1" + git commit --allow-empty --amend --author='foo ' --no-edit + tag_pr 1 + git checkout master + merge_pr feature 1 "PR 1 title" + + git checkout -b feature2 + make_change "feature A2" + git commit --allow-empty --amend --author='foo ' --no-edit + tag_pr 2 + git checkout master + merge_pr feature2 2 "PR 2 title" +) + +test_end