From ee22bfc458fbc77890be4db71cf6174f986571e5 Mon Sep 17 00:00:00 2001 From: Marnik Bercx Date: Thu, 21 Nov 2024 11:49:56 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A7=20Add=20`update=5Fchangelog.py`=20?= =?UTF-8?q?script?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/update_changelog.py | 94 +++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 .github/workflows/update_changelog.py diff --git a/.github/workflows/update_changelog.py b/.github/workflows/update_changelog.py new file mode 100644 index 0000000..1ffa753 --- /dev/null +++ b/.github/workflows/update_changelog.py @@ -0,0 +1,94 @@ +#!/bin/bash +# -*- coding: utf-8 -*- +"""Script for automatically updating the `CHANGELOG.md` based on the commits since the latest release tag.""" + +from pathlib import Path +import re +import subprocess +from datetime import date + +from qe_tools import __version__ + +DEFAULT_CHANGELOG_SECTIONS = """ +### โ€ผ๏ธ Breaking changes + + +### โœจ New features + + +### ๐Ÿ—‘๏ธ Deprecations + + +### ๐Ÿ‘Œ Improvements + + +### ๐Ÿ› Bug fixes + + +### ๐Ÿ“š Documentation + + +### ๐Ÿ”ง Maintenance + + +### โฌ†๏ธ Update dependencies + + +### ๐Ÿงช Tests + + +### โ™ป๏ธ Refactor + +""" + + +def update_changelog(): + """Update the `CHANGELOG.md` for a first draft of the release.""" + + print('๐Ÿ” Checking the current version number') + current_changelog = Path('CHANGELOG.md').read_text(encoding='utf-8') + + print(__version__) + + if str(__version__) in current_changelog: + print('๐Ÿ›‘ Current version already in `CHANGELOG.md`. Skipping...') + return + + print('โฌ†๏ธ Found updated version number, adapting `CHANGELOG.md`.') + tags = subprocess.run(['git', 'tag', '--sort=v:refname'], capture_output=True, check=True, encoding='utf-8').stdout + latest_tag = re.findall(r'(v\d\.\d\.\d)\n', tags)[-1] + + print(f'๐Ÿ”„ Comparing with latest tag `{latest_tag}`.') + commits = subprocess.run( + ['git', 'log', "--pretty=format:'%h|%H|%s'", f'{latest_tag}..origin/main'], + capture_output=True, + check=True, + encoding='utf-8', + ).stdout + + pr_pattern = re.compile(r'\(\S(?P\d+)\)') + + changelog_message = f'## `v{__version__}` - {date.today()}\n' + DEFAULT_CHANGELOG_SECTIONS + + for commit in commits.splitlines(): + # Remove the PR number from the commit message + pr_match = pr_pattern.search(commit) + + if pr_match is not None: + pr_number = pr_match.groupdict()['pr_number'] + commit = commit.replace(rf'(#{pr_number})', '') + + # Add the commit hash (short) to link to the changelog + commit = commit.strip("'") + hash_short, hash_long, message = commit.split('|', maxsplit=2) + message += f' [[{hash_short}](https://github.com/aiidateam/qe-tools/commit/{hash_long})]' + changelog_message += f'\n* {message}' + + with Path('CHANGELOG.md').open('w', encoding='utf8') as handle: + handle.write(changelog_message + '\n\n' + current_changelog) + + print("๐Ÿš€ Success! Finalise the `CHANGELOG.md` and let's get this baby released.") + + +if __name__ == '__main__': + update_changelog()