From 18af91798d1453708fd2e7bd1c4f37e4acee546c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Klaim=20=28Jo=C3=ABl=20Lamotte=29?= <142265+Klaim@users.noreply.github.com> Date: Tue, 7 Jan 2025 13:53:42 +0100 Subject: [PATCH 1/7] release scripts now only create 1 version tag --- releaser.py | 66 +++++++++++++++++++++++++-------------------- update_changelog.py | 2 +- version_scheme.py | 5 ++++ 3 files changed, 43 insertions(+), 30 deletions(-) diff --git a/releaser.py b/releaser.py index da277ac4c6..a0dc90a7ea 100644 --- a/releaser.py +++ b/releaser.py @@ -15,8 +15,7 @@ } -def apply_changelog(name, version_name, changes): - version = version_info(version_name) +def apply_changelog(name, version, changes): def template_substitute(contents): x = contents.replace("{{ version_major }}", version.major) @@ -24,7 +23,7 @@ def template_substitute(contents): x = x.replace("{{ version_patch }}", version.patch) x = x.replace("{{ version_is_prerelease }}", "1" if version.pre_release else "0") x = x.replace("{{ version_prerelease_name }}", version.pre_release) - x = x.replace("{{ version_name }}", version_name) + x = x.replace("{{ version_name }}", version.name) return x if name in templates: @@ -59,7 +58,7 @@ def template_substitute(contents): fo.write(res + prev_cl) -def commands(changes): +def commands(release_version, changes): commit_msg = ", ".join([f"{x} {changes[x]['version']}" for x in changes]) today = datetime.date.today() @@ -82,9 +81,7 @@ def commands(changes): files_to_commit += " CHANGELOG.md \\\n" print(f"git commit -m 'release {commit_msg}' \\\n{files_to_commit[:-3]}") - print(f"git tag {date_stamp}") - for c in changes: - print(f"git tag {c}-{changes[c]['version']}") + print(f"git tag {release_version}") class Section: @@ -137,58 +134,69 @@ def main(): sections = [] in_section = False + release_version = None contents = contents[release_start:] - for idx, c in enumerate(contents): - if c.startswith("Releases"): - releases = [x.strip() for x in c[len("Releases: ") :].split(",")] - for r in releases: - rsplit = r.split() - changes[rsplit[0].strip()] = copy.deepcopy(template) - changes[rsplit[0].strip()]["version"] = rsplit[1].strip() + for idx, line in enumerate(contents): + if line.startswith("Release"): + release_re = re.compile(r"Release*:\s+(\d\.\d\.\d[\.\w]*)\s+\(([\w,\s]+)\)\s*") + if matches := re.search(release_re, line): + release_version = matches.group(1) + projects = matches.group(2).replace(',', " ").split() + print("projects: {}".format(projects)) + for project in projects: + # because `micromamba` is now the name of the `mamba` project's directory, we ignore it + if project != 'mamba': + changes[project] = copy.deepcopy(template) + changes[project]["version"] = release_version continue if contents[idx + 1].startswith("===="): break - if c.strip() == "" or c[0] == "-": + if line.strip() == "" or line[0] == "-": in_section = False - if c.strip() == "": + if line.strip() == "": continue - if c[0] != "-": + if line[0] != "-": if not in_section: sections.append(Section()) in_section = True - sections[-1].text += c + sections[-1].text += line - if m := re.search(brackets_re, c): + if m := re.search(brackets_re, line): if in_section: sections[-1].applies_to = [x.strip() for x in m.groups(1)[0].split(",")] else: sections[-1].items.append(Item()) - sections[-1].items[-1].text = c[m.end() :].strip() + sections[-1].items[-1].text = line[m.end() :].strip() sections[-1].items[-1].applies_to = [x.strip() for x in m.groups(1)[0].split(",")] else: - if c.startswith(" "): + if line.startswith(" "): if in_section: - sections[-1].text += " " + c.strip() + sections[-1].text += " " + line.strip() else: - sections[-1].items[-1].text += c.strip() + sections[-1].items[-1].text += line.strip() else: if not in_section: sections[-1].items.append(Item()) - sections[-1].items[-1].text = c.strip() + sections[-1].items[-1].text = line.strip() sections[-1].items[-1].applies_to = ["all"] - for c in changes: - populate_changes(c, sections, changes) + if release_version is None: + raise ValueError("Version to release not found - use `update_changelog.py` to specify it") + + release_version = version_info(release_version) + + for project_name in changes: + populate_changes(project_name, sections, changes) - for el in changes: - apply_changelog(el, changes[el]["version"], changes[el]["changes"]) + for project_name in changes: + apply_changelog(project_name, release_version, changes[project_name]["changes"]) - commands(changes) + commands(release_version, changes) if __name__ == "__main__": diff --git a/update_changelog.py b/update_changelog.py index 02b48a0051..9f1cdf805f 100644 --- a/update_changelog.py +++ b/update_changelog.py @@ -168,7 +168,7 @@ def main(): changelog_file.write("{}\n".format(date.today().strftime("%Y.%m.%d"))) changelog_file.write("==========\n") changelog_file.write( - "\nReleases: libmamba {0}, libmambapy {0}, micromamba {0}\n".format(release_version) + "\nRelease: {0} (libmamba, mamba, micromamba, libmambapy)\n".format(release_version) ) # PRs info if enhancements_prs: diff --git a/version_scheme.py b/version_scheme.py index 0eda6632c6..f445123bde 100644 --- a/version_scheme.py +++ b/version_scheme.py @@ -13,6 +13,11 @@ class version_info: name = "" def __init__(self, version: str): + if not isinstance(version, str): + raise ValueError( + "'{}' is not a valid version name : must be a string".format(version) + ) + if "-" in version: raise ValueError( "'{}' is not a valid version name : `-` is reserved for another usage in conda packages version names".format( From 39723978899bab252c9d3525da60b59e4bb53674 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Klaim=20=28Jo=C3=ABl=20Lamotte=29?= <142265+Klaim@users.noreply.github.com> Date: Tue, 7 Jan 2025 15:21:39 +0100 Subject: [PATCH 2/7] formatting --- releaser.py | 8 +++----- update_changelog.py | 2 +- version_scheme.py | 16 ++++------------ 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/releaser.py b/releaser.py index a0dc90a7ea..c4e7bcc939 100644 --- a/releaser.py +++ b/releaser.py @@ -14,9 +14,7 @@ "libmambapy": "libmambapy/src/libmambapy/version.py.tmpl", } - def apply_changelog(name, version, changes): - def template_substitute(contents): x = contents.replace("{{ version_major }}", version.major) x = x.replace("{{ version_minor }}", version.minor) @@ -141,11 +139,11 @@ def main(): release_re = re.compile(r"Release*:\s+(\d\.\d\.\d[\.\w]*)\s+\(([\w,\s]+)\)\s*") if matches := re.search(release_re, line): release_version = matches.group(1) - projects = matches.group(2).replace(',', " ").split() - print("projects: {}".format(projects)) + projects = matches.group(2).replace(",", " ").split() + print(f"projects: {projects}") for project in projects: # because `micromamba` is now the name of the `mamba` project's directory, we ignore it - if project != 'mamba': + if project != "mamba": changes[project] = copy.deepcopy(template) changes[project]["version"] = release_version continue diff --git a/update_changelog.py b/update_changelog.py index 9f1cdf805f..7ddf1f9a5a 100644 --- a/update_changelog.py +++ b/update_changelog.py @@ -168,7 +168,7 @@ def main(): changelog_file.write("{}\n".format(date.today().strftime("%Y.%m.%d"))) changelog_file.write("==========\n") changelog_file.write( - "\nRelease: {0} (libmamba, mamba, micromamba, libmambapy)\n".format(release_version) + f"\nRelease: {release_version} (libmamba, mamba, micromamba, libmambapy)\n" ) # PRs info if enhancements_prs: diff --git a/version_scheme.py b/version_scheme.py index f445123bde..c298b1fca7 100644 --- a/version_scheme.py +++ b/version_scheme.py @@ -14,15 +14,11 @@ class version_info: def __init__(self, version: str): if not isinstance(version, str): - raise ValueError( - "'{}' is not a valid version name : must be a string".format(version) - ) + raise ValueError(f"'{version}' is not a valid version name : must be a string") if "-" in version: raise ValueError( - "'{}' is not a valid version name : `-` is reserved for another usage in conda packages version names".format( - version - ) + f"'{version}' is not a valid version name : `-` is reserved for another usage in conda packages version names" ) VALID_VERSION_PRERELEASE_TYPES = ("alpha", "beta", "rc", "dev") @@ -30,9 +26,7 @@ def __init__(self, version: str): version_fields_count = len(version_fields) if version_fields_count < 3: raise ValueError( - "'{}' is not a valid version name : valid version scheme contains 3 or more dots-separated fields, the pre-release name starting with the 4th field (valid examples: 1.2.3, 0.1.2.alpha3, 0.1.2.alpha.3)".format( - version - ) + f"'{version}' is not a valid version name : valid version scheme contains 3 or more dots-separated fields, the pre-release name starting with the 4th field (valid examples: 1.2.3, 0.1.2.alpha3, 0.1.2.alpha.3)" ) self.major = version_fields[0] @@ -56,9 +50,7 @@ def __init__(self, version: str): VALID_VERSION_PRERELEASE_TYPES ): version_errors.append( - "'{}' is not a valid pre-release name, pre-release names must start with either : {} ".format( - self.pre_release, VALID_VERSION_PRERELEASE_TYPES - ) + f"'{self.pre_release}' is not a valid pre-release name, pre-release names must start with either : {VALID_VERSION_PRERELEASE_TYPES} " ) if len(version_errors) > 0: From 75ea5ba59b79884106c287158fc314995f8d4dc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Klaim=20=28Jo=C3=ABl=20Lamotte=29?= <142265+Klaim@users.noreply.github.com> Date: Tue, 7 Jan 2025 15:25:19 +0100 Subject: [PATCH 3/7] makes sure we only have one release version line in each changelog --- releaser.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/releaser.py b/releaser.py index c4e7bcc939..5618cdc4bc 100644 --- a/releaser.py +++ b/releaser.py @@ -138,6 +138,10 @@ def main(): if line.startswith("Release"): release_re = re.compile(r"Release*:\s+(\d\.\d\.\d[\.\w]*)\s+\(([\w,\s]+)\)\s*") if matches := re.search(release_re, line): + if release_version is not None: + raise ValueError( + "multiple release lines (starting with 'Release: ...') found in changelog for last change - consider re-running `update_changelog.py`" + ) release_version = matches.group(1) projects = matches.group(2).replace(",", " ").split() print(f"projects: {projects}") From 8c4c2e39c6d752691335dbc14ebf08d8fbb5f5aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Klaim=20=28Jo=C3=ABl=20Lamotte=29?= <142265+Klaim@users.noreply.github.com> Date: Tue, 7 Jan 2025 15:31:55 +0100 Subject: [PATCH 4/7] formatting --- releaser.py | 1 + 1 file changed, 1 insertion(+) diff --git a/releaser.py b/releaser.py index 5618cdc4bc..fb794983f9 100644 --- a/releaser.py +++ b/releaser.py @@ -14,6 +14,7 @@ "libmambapy": "libmambapy/src/libmambapy/version.py.tmpl", } + def apply_changelog(name, version, changes): def template_substitute(contents): x = contents.replace("{{ version_major }}", version.major) From 3f696056ee08cf8bf482e5d7bfafb621299ed2a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Klaim=20=28Jo=C3=ABl=20Lamotte=29?= <142265+Klaim@users.noreply.github.com> Date: Tue, 7 Jan 2025 15:38:41 +0100 Subject: [PATCH 5/7] why didnt pre-commit detect these in the past is beyond me --- releaser.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/releaser.py b/releaser.py index fb794983f9..99c58462c9 100644 --- a/releaser.py +++ b/releaser.py @@ -60,9 +60,6 @@ def template_substitute(contents): def commands(release_version, changes): commit_msg = ", ".join([f"{x} {changes[x]['version']}" for x in changes]) - today = datetime.date.today() - date_stamp = today.strftime("%Y.%m.%d") - files_to_commit = "" for c in changes: files_to_commit += f" {c}/CHANGELOG.md \\\n" From 9aaca3603b19093e45225e105871e937fc641641 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Klaim=20=28Jo=C3=ABl=20Lamotte=29?= <142265+Klaim@users.noreply.github.com> Date: Wed, 8 Jan 2025 15:43:34 +0100 Subject: [PATCH 6/7] clarification comment in releaser.py --- releaser.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/releaser.py b/releaser.py index 99c58462c9..4368006ea9 100644 --- a/releaser.py +++ b/releaser.py @@ -1,5 +1,7 @@ -# Script to release any of the mamba packages -# Please refer to `update_changelog.py` for more info about the release process +# Script to release any of the mamba packages. +# This script has no cli parameters and only read info from the root changelog +# which must have been modified by executing `update_changelog.py`. +# Please refer to `update_changelog.py` for more info about the release process. import copy import datetime From 867d52127c3c7a642b5333492776f6d19bac23b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Klaim=20=28Jo=C3=ABl=20Lamotte=29?= <142265+Klaim@users.noreply.github.com> Date: Wed, 8 Jan 2025 15:45:15 +0100 Subject: [PATCH 7/7] clarification on cli changes in update_changelog.py --- update_changelog.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/update_changelog.py b/update_changelog.py index 7ddf1f9a5a..fd48f1d593 100644 --- a/update_changelog.py +++ b/update_changelog.py @@ -2,10 +2,11 @@ # Steps: -# 1. Run this script to update the root `CHANGELOG.md` file by giving the date of +# 1. Run this script to update the root `CHANGELOG.md` file by providing the date of # the last release as input (cf. last date shown at the top of the file for reference) # or any other starting date that may be relevant for the release, -# and the release version to be made. +# and the release version name to be made. +# You can provide these input interactively or through the cli (use `--help`). # 2. If you are happy with the changes, run `releaser.py` to update the versions and # corresponding nested `CHANGELOG.md` files.