From 096a2d94655ee349c78abd7afe9b6d09d4c58d43 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Mon, 29 Jul 2024 15:03:42 +0200 Subject: [PATCH 1/3] script to generate the release string --- ci/release_contributors.py | 49 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 ci/release_contributors.py diff --git a/ci/release_contributors.py b/ci/release_contributors.py new file mode 100644 index 00000000000..dab95c651c5 --- /dev/null +++ b/ci/release_contributors.py @@ -0,0 +1,49 @@ +import re +import textwrap + +import git +from tlz.itertoolz import last, unique + +co_author_re = re.compile(r"Co-authored-by: (?P[^<]+?) <(?P.+)>") + + +def main(): + repo = git.Repo(".") + + most_recent_release = last(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 + ignored = ["dependabot", "pre-commit-ci"] + unique_contributors = unique( + contributor + for contributor in contributors.values() + if contributor.removesuffix("[bot]") not in ignored + ) + + 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() From b5b34fe6fc965d1386c112d99458ca48c7f39d98 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Mon, 29 Jul 2024 15:05:35 +0200 Subject: [PATCH 2/3] use the new script in the release guide --- HOW_TO_RELEASE.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/HOW_TO_RELEASE.md b/HOW_TO_RELEASE.md index 9d1164547b9..629c444d63f 100644 --- a/HOW_TO_RELEASE.md +++ b/HOW_TO_RELEASE.md @@ -23,14 +23,13 @@ upstream https://github.com/pydata/xarray (push) ```sh git fetch upstream --tags ``` - This will return a list of all the contributors since the last release: + Then run ```sh - git log "$(git tag --sort=v:refname | tail -1).." --format=%aN | sort -u | perl -pe 's/\n/$1, /' - ``` - This will return the total number of contributors: - ```sh - git log "$(git tag --sort=v:refname | tail -1).." --format=%aN | sort -u | wc -l + python ci/release_contributors.py ``` + (needs `gitpython`) + + and copy the output. 3. Write a release summary: ~50 words describing the high level features. This will be used in the release emails, tweets, GitHub release notes, etc. 4. Look over whats-new.rst and the docs. Make sure "What's New" is complete From 04fd9c2502ba5e387cd0429a8914bb9afbb4b615 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Mon, 29 Jul 2024 15:18:14 +0200 Subject: [PATCH 3/3] include `toolz` in the deps --- HOW_TO_RELEASE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HOW_TO_RELEASE.md b/HOW_TO_RELEASE.md index 629c444d63f..28f7b8e8775 100644 --- a/HOW_TO_RELEASE.md +++ b/HOW_TO_RELEASE.md @@ -27,7 +27,7 @@ upstream https://github.com/pydata/xarray (push) ```sh python ci/release_contributors.py ``` - (needs `gitpython`) + (needs `gitpython` and `toolz` / `cytoolz`) and copy the output. 3. Write a release summary: ~50 words describing the high level features. This