From 9d9c7ff308c61749281221212f5f287e6c25a94e Mon Sep 17 00:00:00 2001 From: "Frederik F. Van der Veken" Date: Mon, 28 Oct 2024 17:09:19 +0100 Subject: [PATCH 1/4] Created release branch release/v0.5.9rc0. --- pyproject.toml | 2 +- tests/test_version.py | 2 +- xcoll/general.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 97214344..558d03f4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "xcoll" -version = "0.5.8" +version = "0.5.9rc0" description = "Xsuite collimation package" homepage = "https://github.com/xsuite/xcoll" repository = "https://github.com/xsuite/xcoll" diff --git a/tests/test_version.py b/tests/test_version.py index 21686c3f..178233f0 100644 --- a/tests/test_version.py +++ b/tests/test_version.py @@ -6,4 +6,4 @@ from xcoll import __version__ def test_version(): - assert __version__ == '0.5.8' + assert __version__ == '0.5.9rc0' diff --git a/xcoll/general.py b/xcoll/general.py index f58044f4..a97b2e8e 100644 --- a/xcoll/general.py +++ b/xcoll/general.py @@ -12,5 +12,5 @@ # ====================== # Do not change # ====================== -__version__ = '0.5.8' +__version__ = '0.5.9rc0' # ====================== From 9fb8c8feb81c0d82201f8d3231c538dadf67fab8 Mon Sep 17 00:00:00 2001 From: "Frederik F. Van der Veken" Date: Mon, 28 Oct 2024 17:13:49 +0100 Subject: [PATCH 2/4] Moved release API to xaux (pinning versions) --- gh.py | 166 --------------------------------------- make_release_branch.py | 87 +------------------- pyproject.toml | 2 +- release.py | 127 +----------------------------- rename_release_branch.py | 102 +----------------------- 5 files changed, 7 insertions(+), 477 deletions(-) delete mode 100644 gh.py diff --git a/gh.py b/gh.py deleted file mode 100644 index ae8053f3..00000000 --- a/gh.py +++ /dev/null @@ -1,166 +0,0 @@ -import sys -import json -from pathlib import Path -from subprocess import run, PIPE - -_GIT_REPO = False -_GH_INSTALLED = False -_POETRY_INSTALLED = False - - -def assert_git_repo(): - global _GIT_REPO - if not _GIT_REPO: - cmd = run(["git", "status"], capture_output=True) - if cmd.returncode != 0: - raise GitError(f"{Path.cwd()} is not a git repository.") - else: - _GIT_REPO = True - -def assert_gh_installed(): - global _GH_INSTALLED - if not _GH_INSTALLED: - cmd = run(["gh", "--version"], capture_output=True) - if cmd.returncode != 0: - raise GhError("gh is not installed.") - else: - _GH_INSTALLED = True - -def assert_poetry_installed(): - global _POETRY_INSTALLED - if not _POETRY_INSTALLED: - cmd = run(["poetry", "--version"], capture_output=True) - if cmd.returncode != 0: - raise PoetryError("poetry is not installed.") - else: - _POETRY_INSTALLED = True - - -def git_assert_working_tree_clean(): - assert_git_repo() - cmd = run(["git", "diff", "--quiet"], capture_output=True) - if cmd.returncode != 0: - raise GitError("Some changes are not staged. Stage and commit first.") - cmd = run(["git", "diff", "--staged", "--quiet"], capture_output=True) - if cmd.returncode != 0: - raise GitError("Some changes are staged. Commit first.") - -def _run_git(cmds): - assert_git_repo() - cmd = run(["git", *cmds], capture_output=True) - if cmd.returncode == 0: - return cmd.stdout.decode('UTF-8').strip() - else: - raise GitError(' '.join(cmds) + ":\n" + cmd.stderr.decode('UTF-8').strip()) - -def git_current_branch(): - return _run_git(["symbolic-ref", "--short", "HEAD"]) - -def git_rename_current_branch(new_branch, set_upstream=False): - old_branch = git_current_branch() - if old_branch == 'main': - raise GitError("Cannot rename the main branch.") - out = _run_git(["branch", "-m", new_branch]) - if out: print(out) - if set_upstream: - out = _run_git(["push", "origin", "--delete", old_branch]) - if out: print(out) - git_push(set_upstream=True) - -def git_switch(branch, create=False): - cc = ['-c'] if create else [] - out = _run_git(["switch", *cc, branch]) - if out: print(out) - -def git_add(files): - out = _run_git(["add", *files]) - if out: print(out) - -def git_commit(message, no_verify=False): - vv = ['--no-verify'] if no_verify else [] - out = _run_git(["commit", *vv, '-m', message]) - if out: print(out) - -def git_pull(): - out = _run_git(["pull"]) - if out: print(out) - -def git_push(set_upstream=False): - uu = ["--set-upstream", "origin", git_current_branch()] if set_upstream else [] - out = _run_git(["push", *uu]) - if out: print(out) - -def git_make_tag(tag): - out = _run_git(["tag", tag]) - if out: print(out) - out = _run_git(["push", "origin", tag]) - if out: print(out) - - -def _run_gh(cmds): - assert_gh_installed() - cmd = run(["gh", *cmds], capture_output=True) - if cmd.returncode == 0: - return cmd.stdout.decode('UTF-8').strip() - else: - raise GhError(' '.join(cmds) + ":\n" + cmd.stderr.decode('UTF-8').strip()) - -def gh_pr_create(base_branch, title): - out = _run_gh(["pr", "create", "--base", base_branch, "--title", title, '--fill']) - if out: print(out) - -def gh_pr_list(base=None, head=None): - bb = [] if base is None else ["-B", base] - hh = [] if head is None else ["-H", head] - out = _run_gh(["pr", "list", *bb, *hh, "--json", - "number,author,headRepositoryOwner,headRepository,headRefName"]) - data = json.loads(out) - return {int(pr['number']): - f"{pr['headRepositoryOwner']['login']}:{pr['headRepository']['name']}/{pr['headRefName']}" - for pr in data} - -def gh_pr_merge(pr_id, admin=False, delete_branch=False): - adm = ["--admin"] if admin else [] - db = ["--delete-branch"] if delete_branch else [] - out = _run_gh(["pr", "merge", str(pr_id), "--merge", *adm, *db]) - if out: print(out) - -def gh_release_create(version, title, draft=False): - dr = ["--draft"] if draft else [] - out = _run_gh(["release", "create", version, *dr, "--generate-notes", - "--title", title, "--verify-tag"]) - if out: print(out) - - -def _run_poetry(cmds): - assert_poetry_installed() - cmd = run(["poetry", *cmds], capture_output=True) - if cmd.returncode == 0: - return cmd.stdout.decode('UTF-8').strip() - else: - raise PoetryError(' '.join(cmds) + ":\n" + cmd.stderr.decode('UTF-8').strip()) - -def poetry_bump_version(bump): - out = _run_poetry(["version", bump]) - if out: print(out) - -def poetry_get_version(): - return _run_poetry(["version"]).split()[-1] - -def poetry_get_expected_version(bump): - return _run_poetry(["version", bump, "--dry-run"]).split()[-1] - -def poetry_publish(build=False): - pp = ["--build"] if build else [] - out = _run_poetry(["publish", *pp]) - if out: print(out) - - -class GitError(OSError): - pass - -class GhError(OSError): - pass - -class PoetryError(OSError): - pass diff --git a/make_release_branch.py b/make_release_branch.py index 1e43fa03..f3ac7d96 100755 --- a/make_release_branch.py +++ b/make_release_branch.py @@ -4,91 +4,8 @@ # Copyright (c) CERN, 2024. # # ######################################### # -import sys -import platform -from gh import * +from xaux.tools import dev_make_release_branch # sys.tracebacklimit = 0 -class VersionError(OSError): - pass - - -# Check necessary setup and installs -assert_git_repo() -assert_poetry_installed() - - -# Check the script arguments -if len(sys.argv) != 2: - raise ValueError("This script needs exactly one argument: the new version number or a bump. " - "The latter can be: patch, minor, major.") -bump = sys.argv[1] - - -# Check our working directory is clean -git_assert_working_tree_clean() -branch = git_current_branch() -if branch != "main": - raise GitError("This script needs to be ran on the main branch.") -git_push() # Sync with the remote to be sure we don't delete an incomplete branch later -git_pull() -expected_ver = poetry_get_expected_version(bump) - - -# Check that we are not accidentally bumping a major version -major_ver = int(expected_ver.split('.')[0]) -if major_ver != 0: - raise VersionError("Bumping a major version! If this is really what you want, " - "then adapt make_release_branch.py manually.") - - -# Confirm version bump -branch = f"release/v{expected_ver}" -expected_ver = f"{expected_ver}rc0" -current_ver = poetry_get_version() -print(f"Bumping from {current_ver} to {expected_ver}.") -print("Type y to continue (or anything else to cancel):") -answer = input() -if answer not in ["y", "Y"]: - print("Cancelled.") - sys.exit(1) - - -# Create release branch -print("Creating release branch...") -git_switch(branch, create=True) - - -# Update version in the release branch -print("Poetry version bump...") -poetry_bump_version(expected_ver) -new_ver = poetry_get_version() -if new_ver != expected_ver: - raise VersionError(f"Fatal error: `poetry --dry-run` expected {expected_ver}, but result is {new_ver}..." - "Need to recover manually!") - - -# Adapt version files -for file, pattern in zip(["xcoll/general.py", "tests/test_version.py"], - ["__version__ = ", " assert __version__ == "]): - file_adapted = False - with Path(file).open("r") as fid: - lines = fid.readlines() - with Path(file).open("w") as fid: - for line in lines: - if line.startswith(pattern): - fid.write(f"{pattern}'{new_ver}'\n") - file_adapted = True - else: - fid.write(line) - if not file_adapted: - raise VersionError(f"Fatal error: could not adapt {file}...") - - -# Commit and push -git_add(['pyproject.toml', 'xcoll/general.py', 'tests/test_version.py']) -git_commit(f"Created release branch release/v{new_ver}.", no_verify=True) -git_push(set_upstream=True) - -print("All done!") +dev_make_release_branch("xcoll") diff --git a/pyproject.toml b/pyproject.toml index 558d03f4..20fc63e7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,10 +29,10 @@ xobjects = ">=0.2.6" xdeps = ">=0.1.1" xpart = ">=0.15.0" xtrack = ">=0.36.5" -xfields = ">=0.12.1" [tool.poetry.dev-dependencies] pytest = ">=7.3" +xaux [tool.poetry.extras] tests = ["pytest", "ruamel-yaml"] diff --git a/release.py b/release.py index 9bb7896c..9c20c265 100755 --- a/release.py +++ b/release.py @@ -4,131 +4,8 @@ # Copyright (c) CERN, 2024. # # ######################################### # -import sys -import platform -from gh import * +from xaux.tools import dev_release # sys.tracebacklimit = 0 -class VersionError(OSError): - pass - -# Check necessary setup and installs -assert_git_repo() -assert_poetry_installed() -assert_gh_installed() - - -# Check the script arguments -if len(sys.argv) < 2 or len(sys.argv) > 3: - raise ValueError("This script needs exactly one argument: the new version number or a bump. " - "The latter can be: patch, minor, major.") -force = False -bump = sys.argv[1] -if len(sys.argv) == 3: - force = True - if sys.argv[1] == "--force": - bump = sys.argv[2] - elif sys.argv[2] != "--force": - raise ValueError("Only '--force' is allowed as an option.") - - -# Check our working directory is clean -print("Verifying repository status...") -git_assert_working_tree_clean() -branch = git_current_branch() -if branch == "main": - raise GitError("\nThis script cannot be ran on the main branch." - "Make a release branch and make the new release from there." - "Make sure that the release branch has an upstream version (i.e." - "push at least once before running this script), or this script" - "will fail.") -expected_ver = poetry_get_expected_version(bump) -if not force: - if branch != f"release/v{expected_ver}": - raise VersionError(f"\nYou are bumping to {expected_ver} but this branch is {branch}. " - "If this is intentional, use --force.") -git_push() # Sync with the remote to be sure we don't delete an incomplete branch later -git_pull() -print("Repository is clean.") - - -# Check that there are no conflicting PRs open -prs = gh_pr_list(base=branch) -if prs: - raise GitError(f"There are open PRs to the release branch:\n" \ - + "\n".join([f"PR#{pr} from {br}" for pr, br in prs.items()]) \ - + "\nThese would be automatically closed by this script, " \ - + "as the target branch disappears. Please close them manually, " \ - + "or change the target branch.") -prs = gh_pr_list(base='main', head=branch) -if prs: - raise GitError(f"There are open PRs from the release branch to main:\n" \ - + "\n".join([f"PR#{pr} from {br}" for pr, br in prs.items()]) \ - + "\nThese would conflict with the versioning script. " - + "Please close them manually.") - - -# Check that we are not accidentally bumping a major version -major_ver = int(expected_ver.split('.')[0]) -if major_ver != 0: - raise VersionError("Bumping a major version! If this is really what you want, " - "then adapt version.py manually.") - - -# Confirm version bump -current_ver = poetry_get_version() -print(f"Bumping from {current_ver} to {expected_ver}.") -print("Type y to continue (or anything else to cancel):") -answer = input() -if answer not in ["y", "Y"]: - print("Cancelled.") - sys.exit(1) - - -print("Updating version in the release branch...") -# Make the bump -poetry_bump_version(bump) -new_ver = poetry_get_version() -if new_ver != expected_ver: - raise VersionError(f"Fatal error: `poetry --dry-run` expected {expected_ver}, but result is {new_ver}..." - "Need to recover manually!") -# Adapt version files -for file, pattern in zip(["xcoll/general.py", "tests/test_version.py"], - ["__version__ = ", " assert __version__ == "]): - file_adapted = False - with Path(file).open("r") as fid: - lines = fid.readlines() - with Path(file).open("w") as fid: - for line in lines: - if line.startswith(pattern): - fid.write(f"{pattern}'{new_ver}'\n") - file_adapted = True - else: - fid.write(line) - if not file_adapted: - raise VersionError(f"Fatal error: could not adapt {file}...") -# Commit and push -git_add(['pyproject.toml', 'xcoll/general.py', 'tests/test_version.py']) -git_commit(f"Updated version number to v{new_ver}.", no_verify=True) -git_push() - - -print("Creating and merging pull request to main branch...") -gh_pr_create('main', f"Release {new_ver}") -git_switch('main') -git_pull() -prs = gh_pr_list(base='main', head=branch) -if len(prs) != 1: - raise GitError(f"Expected one PR from {branch} to main, found {len(prs)}:\n" - + "\n".join([f"PR#{pr} from {br}" for pr, br in prs.items()])) -gh_pr_merge(list(prs.keys())[0], admin=True, delete_branch=True) -git_pull() -git_make_tag(f"v{new_ver}") - - -print("Creating draft release and publishing to PyPi...") -gh_release_create(f"v{new_ver}", f"Xcoll release {new_ver}", draft=True) -poetry_publish(build=True) - -print("All done!") +dev_release("xcoll") diff --git a/rename_release_branch.py b/rename_release_branch.py index c39fa3af..222bd34b 100755 --- a/rename_release_branch.py +++ b/rename_release_branch.py @@ -4,106 +4,8 @@ # Copyright (c) CERN, 2024. # # ######################################### # -import sys -from gh import * +from xaux.tools import dev_rename_release_branch # sys.tracebacklimit = 0 -class VersionError(OSError): - pass - - -# Check necessary setup and installs -assert_git_repo() -assert_poetry_installed() - - -# Check the script arguments -if len(sys.argv) != 2: - raise ValueError("This script needs exactly one argument: the new version number or a bump. " - "The latter can be: patch, minor, major.") -bump = sys.argv[1] - - -# Check our working directory is clean -git_assert_working_tree_clean() -git_push() # Sync with the remote to be sure we don't delete an incomplete branch later -git_pull() -branch = git_current_branch() -current_ver = poetry_get_version() -if not branch == f"release/v{current_ver[:-3]}": - raise GitError("This script needs to be ran from a release branch.") - - -# Check that there are no conflicting PRs open -prs = gh_pr_list(base=branch) -if prs: - raise GitError("There are open PRs to the current release branch:\n" \ - + "\n".join([f"PR#{pr} from {br}" for pr, br in prs.items()]) \ - + "\nThese would be automatically closed by this script, " \ - + "as the target branch disappears. Please close them manually, " \ - + "or change the target branch.") -prs = gh_pr_list(head=branch) -if prs: - raise GitError("There are open PRs from the current release branch:\n" \ - + "\n".join([f"PR#{pr} from {br}" for pr, br in prs.items()]) \ - + "\nThese would be automatically closed by this script, " \ - + "as the head branch disappears. Please close or resolve them " \ - + "manually.") - - -# Check that we are not accidentally bumping a major version -expected_ver = poetry_get_expected_version(bump) -major_ver = int(expected_ver.split('.')[0]) -if major_ver != 0: - raise VersionError("Bumping a major version! If this is really what you want, " - "then adapt make_release_branch.py manually.") - - -# Confirm version bump -new_branch = f"release/v{expected_ver}" -expected_ver = f"{expected_ver}rc0" -print(f"Bumping from {current_ver} to {expected_ver}.") -print("Type y to continue (or anything else to cancel):") -answer = input() -if answer not in ["y", "Y"]: - print("Cancelled.") - sys.exit(1) - - -# Rename release branch -git_rename_current_branch(new_branch, set_upstream=True) - - -# Update version in the release branch -print("Poetry version bump...") -poetry_bump_version(expected_ver) -new_ver = poetry_get_version() -if new_ver != expected_ver: - raise VersionError(f"Fatal error: `poetry --dry-run` expected {expected_ver}, but result is {new_ver}..." - "Need to recover manually!") - - -# Adapt version files -for file, pattern in zip(["xcoll/general.py", "tests/test_version.py"], - ["__version__ = ", " assert __version__ == "]): - file_adapted = False - with Path(file).open("r") as fid: - lines = fid.readlines() - with Path(file).open("w") as fid: - for line in lines: - if line.startswith(pattern): - fid.write(f"{pattern}'{new_ver}'\n") - file_adapted = True - else: - fid.write(line) - if not file_adapted: - raise VersionError(f"Fatal error: could not adapt {file}...") - - -# Commit and push -git_add(['pyproject.toml', 'xcoll/general.py', 'tests/test_version.py']) -git_commit(f"Renamed release branch {branch} into {new_branch}.", no_verify=True) -git_push(set_upstream=True) - -print("All done!") +dev_rename_release_branch("xcoll") From 8160a1b2fa0c6755587965e07347db75893bab7c Mon Sep 17 00:00:00 2001 From: "Frederik F. Van der Veken" Date: Mon, 28 Oct 2024 17:19:31 +0100 Subject: [PATCH 3/4] Needed to fix xaux version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 20fc63e7..adc3b913 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,7 +32,7 @@ xtrack = ">=0.36.5" [tool.poetry.dev-dependencies] pytest = ">=7.3" -xaux +xaux = "0.2.0" [tool.poetry.extras] tests = ["pytest", "ruamel-yaml"] From bdc6267d4ffcf4a257102254f1621677b96b48b0 Mon Sep 17 00:00:00 2001 From: "Frederik F. Van der Veken" Date: Mon, 28 Oct 2024 17:19:54 +0100 Subject: [PATCH 4/4] Updated version number to v0.5.9. --- pyproject.toml | 12 ++++++------ tests/test_version.py | 2 +- xcoll/general.py | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index adc3b913..a63e7dd5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "xcoll" -version = "0.5.9rc0" +version = "0.5.9" description = "Xsuite collimation package" homepage = "https://github.com/xsuite/xcoll" repository = "https://github.com/xsuite/xcoll" @@ -25,14 +25,14 @@ python = ">=3.8" ruamel-yaml = { version = "^0.17.31", optional = true } numpy = ">=1.0" pandas = ">=1.4" -xobjects = ">=0.2.6" -xdeps = ">=0.1.1" -xpart = ">=0.15.0" -xtrack = ">=0.36.5" +xobjects = ">=0.4.5" +xdeps = ">=0.7.3" +xpart = ">=0.19.1" +xtrack = ">=0.69.7" [tool.poetry.dev-dependencies] pytest = ">=7.3" -xaux = "0.2.0" +xaux = ">=0.2.1" [tool.poetry.extras] tests = ["pytest", "ruamel-yaml"] diff --git a/tests/test_version.py b/tests/test_version.py index 178233f0..8bd5fb0f 100644 --- a/tests/test_version.py +++ b/tests/test_version.py @@ -6,4 +6,4 @@ from xcoll import __version__ def test_version(): - assert __version__ == '0.5.9rc0' + assert __version__ == '0.5.9' diff --git a/xcoll/general.py b/xcoll/general.py index a97b2e8e..6d6023d5 100644 --- a/xcoll/general.py +++ b/xcoll/general.py @@ -12,5 +12,5 @@ # ====================== # Do not change # ====================== -__version__ = '0.5.9rc0' +__version__ = '0.5.9' # ======================