From c2fc717de9413553933fbce3a1574a914ba970d4 Mon Sep 17 00:00:00 2001 From: cookiecutter-e3 Date: Wed, 11 Dec 2024 10:45:39 +0000 Subject: [PATCH 1/2] New versioning system for e3 packages The number of commits since the last tagged version will be appended to the version of the package as the patch version by build_wheel.py instead of the date. The minor version of each package will be bumped in their respective MRs to avoid conflicts with the old versioning system. Ref it/org/operation_support/iaas/issues#214 See merge request it/cookiecutter-e3!60 of the template --- .gitlab-ci.yml | 9 +-- build_wheel.py | 166 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 169 insertions(+), 6 deletions(-) create mode 100644 build_wheel.py diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b43cb903..54a75f69 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -235,21 +235,18 @@ documentations: - if: $CI_PIPELINE_SOURCE == "merge_request_event" upload-python-registry: - extends: .linux-image stage: upload + services: + - image:e3 before_script: - - !reference [.linux-image, before_script] - python -m pip install twine script: - - CURRENT_DATE=$(date +"%Y%m%d%H%M") - - sed -i "s|[0-9][0-9.]*|&.${CURRENT_DATE}|" VERSION - - python -m pip wheel . -q --no-deps -C--python-tag=py3 -w build + - python build_wheel.py - python -m twine upload --skip-existing --repository-url https://${CI_SERVER_HOST}:${CI_SERVER_PORT}/api/v4/projects/202/packages/pypi build/*.whl rules: - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH variables: - PYTHON_VERSION: "3.11" TWINE_PASSWORD: $CI_JOB_TOKEN TWINE_USERNAME: gitlab-ci-token diff --git a/build_wheel.py b/build_wheel.py new file mode 100644 index 00000000..0ec63ec7 --- /dev/null +++ b/build_wheel.py @@ -0,0 +1,166 @@ +#!/usr/bin/env python +"""Build the wheel. + +The number of commits since the last tagged version is automatically +added to the version of the package as the patch version. + +For that, a tag v..0 must be manually added after the +merge when a major or minor version change occurs. +""" +from __future__ import annotations +import sys +from pathlib import Path +import re +import tomllib + +from e3.main import Main +from e3.os.process import Run +from e3.log import getLogger + +logger = getLogger("build_wheel") + +ROOT_DIR = Path(__file__).parent + + +def run(cmd: list[str], fail_ok: bool | None = None) -> Run: + """Print a command, run it, and print the result. + + :param cmd: the command + :param fail_ok: allow the command to fail + :return: the Run instance + """ + logger.info(f"$ {' '.join(cmd)}") + p = Run(cmd, cwd=str(ROOT_DIR)) + if p.status != 0 and not fail_ok: + logger.error(p.out) + sys.exit(1) + + logger.info(p.out) + return p + + +def main() -> None: + """Entrypoint.""" + main = Main() + + parser = main.argument_parser + parser.description = "Build the wheel" + parser.add_argument( + "--last-tag", + help="Provide the last tagged version", + ) + + main.parse_args() + assert main.args + + # Find and read version file + with open(ROOT_DIR / "pyproject.toml", "rb") as f: + version_config = tomllib.load(f)["tool"]["setuptools"]["dynamic"]["version"] + + version_path = ROOT_DIR / ( + version_config["file"] + if "file" in version_config + else f'src/{version_config["attr"].replace(".", "/")}.py' + ) + with open(version_path) as f: + version_content = f.read() + + # Extract the .(.)? part. + # We will replace the patch version by the number of commits since the most + # recent tagged version + match = re.search( + r"(?P(?P\d+)\.(?P\d+)(\.\w+)?)", + version_content, + ) + if not match: + logger.error( + f"No .(.)? version found in {version_path.name}" + ) + sys.exit(1) + + version_major = match.group("major") + version_minor = match.group("minor") + version = match.group("version") + logger.info(f"Version is {version}") + + # Find previous version from the most recent tag + last_tag = main.args.last_tag + if not last_tag: + # Need to unshallow the clone so we get the list of tags. + # That command can fail for an already complete clone + run(["git", "fetch", "--unshallow", "--tags"], fail_ok=True) + # Describe the most recent tag + p = run(["git", "describe", "--tags"]) + output = p.out + assert output is not None + last_tag = output.strip() + + # Format is v..(-)? with commits omitted if + # the current commit is also the one tagged + match = re.match( + r"v(?P\d+)\.(?P\d+)\.(?P\w+)(\-(?P\d+))?", + last_tag, + ) + if not match: + logger.error( + f"Expected v..(-)? format for tag {last_tag}" + ) + sys.exit(1) + + # Ensure the major and minor versions match. + # Also ensure the patch version is 0 because multiple tags for the same + # . would mess up with the versioning system and then only + # ..0 should exist + tagged_version_major = match.group("major") + tagged_version_minor = match.group("minor") + tagged_version_patch = match.group("patch") + if (version_major, version_minor, "0") != ( + tagged_version_major, + tagged_version_minor, + tagged_version_patch, + ): + logger.error( + "Found tag " + f"v{tagged_version_major}.{tagged_version_minor}.{tagged_version_patch} " + f"but was expecting v{version_major}.{version_minor}.0. " + "Please manually create the tag if not done yet or make sure this " + "is the most recent tag" + ) + sys.exit(1) + + # match.group("commits") is None only if the current commit is also + # the one tagged so there is 0 commits since that tag + new_version = "{}.{}.{}".format( + version_major, + version_minor, + match.group("commits") or "0", + ) + + # Replace the version in the file + logger.info(f"Set version to {new_version}") + with open(version_path, "w") as f: + f.write(version_content.replace(version, new_version)) + + try: + # Build the wheel + run( + [ + sys.executable, + "-m", + "pip", + "wheel", + ".", + "-q", + "--no-deps", + "-C--python-tag=py3", + "-w", + "build", + ] + ) + finally: + # Revert change to version file + run(["git", "restore", str(version_path)], fail_ok=True) + + +if __name__ == "__main__": + main() From b3940c53e877b0f9763856c93ff1cef587166cf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Morosi?= Date: Wed, 11 Dec 2024 11:57:09 +0100 Subject: [PATCH 2/2] Bump minor version To avoid conflict with previous versioning system --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index fcdfa8e4..8dc248c0 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -22.7 +22.8