Skip to content

Commit 02b6fb5

Browse files
Add Nox task for triggering the release and function to release by a release type
1 parent 948674c commit 02b6fb5

File tree

2 files changed

+117
-15
lines changed

2 files changed

+117
-15
lines changed

exasol/toolbox/nox/_release.py

Lines changed: 100 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
import argparse
4+
import sys
45
from pathlib import Path
56
from typing import (
67
List,
@@ -24,18 +25,31 @@
2425
new_unreleased,
2526
)
2627
from noxconfig import PROJECT_CONFIG
27-
28+
from enum import Enum
29+
import subprocess
30+
import re
2831

2932
def _create_parser() -> argparse.ArgumentParser:
3033
parser = argparse.ArgumentParser(
3134
prog="nox -s release:prepare",
32-
usage="nox -s release:prepare -- [-h] version",
35+
usage="nox -s release:experimental -- [-h] [-v | --version VERSION] [-t | --type {major,minor,patch}]",
3336
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
3437
)
35-
parser.add_argument(
36-
"version",
38+
group = parser.add_mutually_exclusive_group(required=True)
39+
group.add_argument(
40+
"-v", "--version",
3741
type=cli.version,
38-
help=("A version string of the following format:" '"NUMBER.NUMBER.NUMBER"'),
42+
help="A version string of the following format:" '"NUMBER.NUMBER.NUMBER"',
43+
required=False,
44+
default=argparse.SUPPRESS
45+
)
46+
group.add_argument(
47+
"-t", "--type",
48+
type=ReleaseTypes,
49+
help="specifies which type of upgrade is to be performed",
50+
required=False,
51+
choices=[rt.value for rt in list(ReleaseTypes)],
52+
default=argparse.SUPPRESS
3953
)
4054
parser.add_argument(
4155
"--no-add",
@@ -89,6 +103,42 @@ def _add_files_to_index(session: Session, files: list[Path]) -> None:
89103
session.run("git", "add", f"{file}")
90104

91105

106+
class ReleaseTypes(Enum):
107+
Major = "major"
108+
Minor = "minor"
109+
Patch = "patch"
110+
111+
112+
def _type_release(release_type: ReleaseTypes, old_version: Version) -> Version:
113+
upgrade = {
114+
ReleaseTypes.Major: Version(old_version.major + 1, 0, 0),
115+
ReleaseTypes.Minor: Version(old_version.major, old_version.minor + 1, 0),
116+
ReleaseTypes.Patch: Version(old_version.major, old_version.minor, old_version.patch + 1),
117+
}
118+
return upgrade[release_type]
119+
120+
121+
def _version_control(session: Session, args: argparse.Namespace,) -> Version:
122+
has_release_version = hasattr(args, "version")
123+
has_release_type = hasattr(args, "type")
124+
125+
old_version = Version.from_poetry()
126+
127+
if has_release_version and has_release_type:
128+
session.error("choose either a release version or a release type")
129+
130+
if has_release_version and not has_release_type:
131+
if not _is_valid_version(old=old_version, new=args.version):
132+
session.error(
133+
f"Invalid version: the release version ({args.version}) "
134+
f"must be greater than or equal to the current version ({args.version})"
135+
)
136+
return args.version
137+
138+
if not has_release_version and has_release_type:
139+
return _type_release(release_type=args.type, old_version=old_version)
140+
141+
92142
@nox.session(name="release:prepare", python=False)
93143
def prepare_release(session: Session, python=False) -> None:
94144
"""
@@ -97,14 +147,7 @@ def prepare_release(session: Session, python=False) -> None:
97147
parser = _create_parser()
98148
args = parser.parse_args(session.posargs)
99149

100-
if not _is_valid_version(
101-
old=(old_version := Version.from_poetry()),
102-
new=(new_version := args.version),
103-
):
104-
session.error(
105-
f"Invalid version: the release version ({new_version}) "
106-
f"must be greater than or equal to the current version ({old_version})"
107-
)
150+
new_version = _version_control(session, args)
108151

109152
if not args.no_branch and not args.no_add:
110153
session.run("git", "switch", "-c", f"release/prepare-{new_version}")
@@ -146,3 +189,47 @@ def prepare_release(session: Session, python=False) -> None:
146189
"--body",
147190
'""',
148191
)
192+
193+
194+
@nox.session(name="release:trigger", python=False)
195+
def release(session: Session) -> None:
196+
197+
parser = argparse.ArgumentParser(
198+
prog="nox -s release:experimental",
199+
usage="nox -s release:experimental -- [-h] [-v | --version VERSION] [-t | --type {major,minor,patch}]",
200+
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
201+
)
202+
group = parser.add_mutually_exclusive_group(required=True)
203+
group.add_argument(
204+
"-v", "--version",
205+
type=cli.version,
206+
help="A version string of the following format:" '"NUMBER.NUMBER.NUMBER"',
207+
default=argparse.SUPPRESS
208+
)
209+
group.add_argument(
210+
"-t", "--type",
211+
type=ReleaseTypes,
212+
help="specifies which type of upgrade is to be performed",
213+
choices=list(ReleaseTypes),
214+
default=argparse.SUPPRESS
215+
)
216+
217+
args = parser.parse_args(session.posargs)
218+
219+
new_version = _version_control(session, args)
220+
print(str(new_version))
221+
222+
result = subprocess.run(["git", "remote", "show", "origin"], capture_output=True)
223+
match = re.search(r"HEAD branch: (\S+)", result.stdout.decode("utf-8"))
224+
if not match:
225+
session.error("Default branch could not be found")
226+
default_branch = match.group(1) if match else None
227+
subprocess.run(["git", "checkout", default_branch])
228+
subprocess.run(["git", "pull"])
229+
key = False
230+
if not key:
231+
return
232+
print(":(")
233+
subprocess.run(["git", "tag", str(new_version)])
234+
subprocess.run(["git", "push", "origin", str(new_version)])
235+
pass

test/unit/release_test.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@
1010
extract_release_notes,
1111
new_changelog,
1212
)
13-
14-
13+
from exasol.toolbox.nox._release import (
14+
ReleaseTypes,
15+
_type_release
16+
)
1517
@pytest.mark.parametrize(
1618
"input,expected",
1719
[
@@ -143,3 +145,16 @@ def test_extract_release_notes(unreleased_md):
143145
)
144146
actual = extract_release_notes(unreleased_md)
145147
assert expected == actual
148+
149+
150+
@pytest.mark.parametrize(
151+
"rtype,old,expected",[
152+
("major", "1.2.3", "2.0.0"),
153+
("minor", "1.2.3", "1.3.0"),
154+
("patch", "1.2.3", "1.2.4"),
155+
]
156+
)
157+
def test_type_release(rtype, old, expected):
158+
actual = _type_release(ReleaseTypes(rtype), Version.from_string(old))
159+
expected = Version.from_string(expected)
160+
assert actual == expected

0 commit comments

Comments
 (0)