mirror of https://github.com/mamba-org/mamba.git
Unique Release Tag (#3732)
This commit is contained in:
parent
8f58fce381
commit
c7734ce08b
80
releaser.py
80
releaser.py
|
@ -1,5 +1,7 @@
|
||||||
# Script to release any of the mamba packages
|
# Script to release any of the mamba packages.
|
||||||
# Please refer to `update_changelog.py` for more info about the release process
|
# 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 copy
|
||||||
import datetime
|
import datetime
|
||||||
|
@ -15,16 +17,14 @@ templates = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def apply_changelog(name, version_name, changes):
|
def apply_changelog(name, version, changes):
|
||||||
version = version_info(version_name)
|
|
||||||
|
|
||||||
def template_substitute(contents):
|
def template_substitute(contents):
|
||||||
x = contents.replace("{{ version_major }}", version.major)
|
x = contents.replace("{{ version_major }}", version.major)
|
||||||
x = x.replace("{{ version_minor }}", version.minor)
|
x = x.replace("{{ version_minor }}", version.minor)
|
||||||
x = x.replace("{{ version_patch }}", version.patch)
|
x = x.replace("{{ version_patch }}", version.patch)
|
||||||
x = x.replace("{{ version_is_prerelease }}", "1" if version.pre_release else "0")
|
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_prerelease_name }}", version.pre_release)
|
||||||
x = x.replace("{{ version_name }}", version_name)
|
x = x.replace("{{ version_name }}", version.name)
|
||||||
return x
|
return x
|
||||||
|
|
||||||
if name in templates:
|
if name in templates:
|
||||||
|
@ -59,12 +59,9 @@ def apply_changelog(name, version_name, changes):
|
||||||
fo.write(res + prev_cl)
|
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])
|
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 = ""
|
files_to_commit = ""
|
||||||
for c in changes:
|
for c in changes:
|
||||||
files_to_commit += f" {c}/CHANGELOG.md \\\n"
|
files_to_commit += f" {c}/CHANGELOG.md \\\n"
|
||||||
|
@ -82,9 +79,7 @@ def commands(changes):
|
||||||
files_to_commit += " CHANGELOG.md \\\n"
|
files_to_commit += " CHANGELOG.md \\\n"
|
||||||
print(f"git commit -m 'release {commit_msg}' \\\n{files_to_commit[:-3]}")
|
print(f"git commit -m 'release {commit_msg}' \\\n{files_to_commit[:-3]}")
|
||||||
|
|
||||||
print(f"git tag {date_stamp}")
|
print(f"git tag {release_version}")
|
||||||
for c in changes:
|
|
||||||
print(f"git tag {c}-{changes[c]['version']}")
|
|
||||||
|
|
||||||
|
|
||||||
class Section:
|
class Section:
|
||||||
|
@ -137,58 +132,73 @@ def main():
|
||||||
sections = []
|
sections = []
|
||||||
in_section = False
|
in_section = False
|
||||||
|
|
||||||
|
release_version = None
|
||||||
contents = contents[release_start:]
|
contents = contents[release_start:]
|
||||||
for idx, c in enumerate(contents):
|
for idx, line in enumerate(contents):
|
||||||
if c.startswith("Releases"):
|
if line.startswith("Release"):
|
||||||
releases = [x.strip() for x in c[len("Releases: ") :].split(",")]
|
release_re = re.compile(r"Release*:\s+(\d\.\d\.\d[\.\w]*)\s+\(([\w,\s]+)\)\s*")
|
||||||
for r in releases:
|
if matches := re.search(release_re, line):
|
||||||
rsplit = r.split()
|
if release_version is not None:
|
||||||
changes[rsplit[0].strip()] = copy.deepcopy(template)
|
raise ValueError(
|
||||||
changes[rsplit[0].strip()]["version"] = rsplit[1].strip()
|
"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}")
|
||||||
|
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
|
continue
|
||||||
|
|
||||||
if contents[idx + 1].startswith("===="):
|
if contents[idx + 1].startswith("===="):
|
||||||
break
|
break
|
||||||
|
|
||||||
if c.strip() == "" or c[0] == "-":
|
if line.strip() == "" or line[0] == "-":
|
||||||
in_section = False
|
in_section = False
|
||||||
|
|
||||||
if c.strip() == "":
|
if line.strip() == "":
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if c[0] != "-":
|
if line[0] != "-":
|
||||||
if not in_section:
|
if not in_section:
|
||||||
sections.append(Section())
|
sections.append(Section())
|
||||||
in_section = True
|
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:
|
if in_section:
|
||||||
sections[-1].applies_to = [x.strip() for x in m.groups(1)[0].split(",")]
|
sections[-1].applies_to = [x.strip() for x in m.groups(1)[0].split(",")]
|
||||||
else:
|
else:
|
||||||
sections[-1].items.append(Item())
|
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(",")]
|
sections[-1].items[-1].applies_to = [x.strip() for x in m.groups(1)[0].split(",")]
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if c.startswith(" "):
|
if line.startswith(" "):
|
||||||
if in_section:
|
if in_section:
|
||||||
sections[-1].text += " " + c.strip()
|
sections[-1].text += " " + line.strip()
|
||||||
else:
|
else:
|
||||||
sections[-1].items[-1].text += c.strip()
|
sections[-1].items[-1].text += line.strip()
|
||||||
else:
|
else:
|
||||||
if not in_section:
|
if not in_section:
|
||||||
sections[-1].items.append(Item())
|
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"]
|
sections[-1].items[-1].applies_to = ["all"]
|
||||||
|
|
||||||
for c in changes:
|
if release_version is None:
|
||||||
populate_changes(c, sections, changes)
|
raise ValueError("Version to release not found - use `update_changelog.py` to specify it")
|
||||||
|
|
||||||
for el in changes:
|
release_version = version_info(release_version)
|
||||||
apply_changelog(el, changes[el]["version"], changes[el]["changes"])
|
|
||||||
|
|
||||||
commands(changes)
|
for project_name in changes:
|
||||||
|
populate_changes(project_name, sections, changes)
|
||||||
|
|
||||||
|
for project_name in changes:
|
||||||
|
apply_changelog(project_name, release_version, changes[project_name]["changes"])
|
||||||
|
|
||||||
|
commands(release_version, changes)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -2,10 +2,11 @@
|
||||||
|
|
||||||
# Steps:
|
# 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)
|
# 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,
|
# 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
|
# 2. If you are happy with the changes, run `releaser.py` to update the versions and
|
||||||
# corresponding nested `CHANGELOG.md` files.
|
# corresponding nested `CHANGELOG.md` files.
|
||||||
|
@ -168,7 +169,7 @@ def main():
|
||||||
changelog_file.write("{}\n".format(date.today().strftime("%Y.%m.%d")))
|
changelog_file.write("{}\n".format(date.today().strftime("%Y.%m.%d")))
|
||||||
changelog_file.write("==========\n")
|
changelog_file.write("==========\n")
|
||||||
changelog_file.write(
|
changelog_file.write(
|
||||||
"\nReleases: libmamba {0}, libmambapy {0}, micromamba {0}\n".format(release_version)
|
f"\nRelease: {release_version} (libmamba, mamba, micromamba, libmambapy)\n"
|
||||||
)
|
)
|
||||||
# PRs info
|
# PRs info
|
||||||
if enhancements_prs:
|
if enhancements_prs:
|
||||||
|
|
|
@ -13,11 +13,12 @@ class version_info:
|
||||||
name = ""
|
name = ""
|
||||||
|
|
||||||
def __init__(self, version: str):
|
def __init__(self, version: str):
|
||||||
|
if not isinstance(version, str):
|
||||||
|
raise ValueError(f"'{version}' is not a valid version name : must be a string")
|
||||||
|
|
||||||
if "-" in version:
|
if "-" in version:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"'{}' is not a valid version name : `-` is reserved for another usage in conda packages version names".format(
|
f"'{version}' is not a valid version name : `-` is reserved for another usage in conda packages version names"
|
||||||
version
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
VALID_VERSION_PRERELEASE_TYPES = ("alpha", "beta", "rc", "dev")
|
VALID_VERSION_PRERELEASE_TYPES = ("alpha", "beta", "rc", "dev")
|
||||||
|
@ -25,9 +26,7 @@ class version_info:
|
||||||
version_fields_count = len(version_fields)
|
version_fields_count = len(version_fields)
|
||||||
if version_fields_count < 3:
|
if version_fields_count < 3:
|
||||||
raise ValueError(
|
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(
|
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)"
|
||||||
version
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.major = version_fields[0]
|
self.major = version_fields[0]
|
||||||
|
@ -51,9 +50,7 @@ class version_info:
|
||||||
VALID_VERSION_PRERELEASE_TYPES
|
VALID_VERSION_PRERELEASE_TYPES
|
||||||
):
|
):
|
||||||
version_errors.append(
|
version_errors.append(
|
||||||
"'{}' is not a valid pre-release name, pre-release names must start with either : {} ".format(
|
f"'{self.pre_release}' is not a valid pre-release name, pre-release names must start with either : {VALID_VERSION_PRERELEASE_TYPES} "
|
||||||
self.pre_release, VALID_VERSION_PRERELEASE_TYPES
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if len(version_errors) > 0:
|
if len(version_errors) > 0:
|
||||||
|
|
Loading…
Reference in New Issue