1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
|
import re
import textwrap
import git
from tlz.itertoolz import last, unique
co_author_re = re.compile(r"Co-authored-by: (?P<name>[^<]+?) <(?P<email>.+)>")
ignored = [
{"name": "dependabot[bot]"},
{"name": "pre-commit-ci[bot]"},
{
"name": "Claude",
"email": [
"noreply@anthropic.com",
"claude@anthropic.com",
"no-reply@anthropic.com",
],
},
]
def is_ignored(name, email):
# linear search, for now
for ignore in ignored:
if ignore["name"] != name:
continue
ignored_email = ignore.get("email")
if ignored_email is None or email in ignored_email:
return True
return False
def main():
repo = git.Repo(".")
most_recent_release = last(list(repo.tags))
# extract information from commits
contributors = {}
for commit in repo.iter_commits(f"{most_recent_release.name}.."):
matches = co_author_re.findall(commit.message)
if matches:
contributors.update({email: name for name, email in matches})
contributors[commit.author.email] = commit.author.name
# deduplicate and ignore
# TODO: extract ignores from .github/release.yml
unique_contributors = unique(
name for email, name in contributors.items() if not is_ignored(name, email)
)
sorted_ = sorted(unique_contributors)
if len(sorted_) > 1:
names = f"{', '.join(sorted_[:-1])} and {sorted_[-1]}"
else:
names = "".join(sorted_)
statement = textwrap.dedent(
f"""\
Thanks to the {len(sorted_)} contributors to this release:
{names}
""".rstrip()
)
print(statement)
if __name__ == "__main__":
main()
|