remove RCs from release tool

This commit is contained in:
Alex Grintsvayg 2019-07-16 13:02:15 -04:00 committed by Lex Berezhny
parent f72b07d0f4
commit d97d738880

View file

@ -74,28 +74,19 @@ def get_release_text(desc: str):
yield line[len(RELEASE_TEXT):] yield line[len(RELEASE_TEXT):]
def get_previous_final(repo, current_release):
assert current_release.rc is not None, "Need an rc to find the previous final release."
previous = None
for tag in repo.tags(current_release.rc+1):
previous = tag
return previous
class Version: class Version:
def __init__(self, major=0, minor=0, micro=0, rc=None): def __init__(self, major=0, minor=0, micro=0):
self.major = int(major) self.major = int(major)
self.minor = int(minor) self.minor = int(minor)
self.micro = int(micro) self.micro = int(micro)
self.rc = rc if rc is None else int(rc)
@classmethod @classmethod
def from_string(cls, version_string): def from_string(cls, version_string):
(major, minor, micro), rc = version_string.split('.'), None (major, minor, micro), rc = version_string.split('.'), None
if 'rc' in micro: if 'rc' in micro:
micro, rc = micro.split('rc') micro, rc = micro.split('rc')
return cls(major, minor, micro, rc) return cls(major, minor, micro)
@classmethod @classmethod
def from_content(cls, content): def from_content(cls, content):
@ -106,20 +97,12 @@ class Version:
def increment(self, action): def increment(self, action):
cls = self.__class__ cls = self.__class__
if action == '*-rc': if action == 'major':
assert self.rc is not None, f"Can't drop rc designation because {self} is already not an rc." return cls(self.major+1)
return cls(self.major, self.minor, self.micro) elif action == 'minor':
elif action == '*+rc': return cls(self.major, self.minor+1)
assert self.rc is not None, "Must already be an rc to increment." elif action == 'micro':
return cls(self.major, self.minor, self.micro, self.rc+1) return cls(self.major, self.minor, self.micro+1)
assert self.rc is None, f"Can't start a new rc because {self} is already an rc."
if action == 'major+rc':
return cls(self.major+1, rc=1)
elif action == 'minor+rc':
return cls(self.major, self.minor+1, rc=1)
elif action == 'micro+rc':
return cls(self.major, self.minor, self.micro+1, 1)
raise ValueError(f'unknown action: {action}') raise ValueError(f'unknown action: {action}')
@ -128,10 +111,7 @@ class Version:
return f'v{self}' return f'v{self}'
def __str__(self): def __str__(self):
version = '.'.join(str(p) for p in [self.major, self.minor, self.micro]) return '.'.join(str(p) for p in [self.major, self.minor, self.micro])
if self.rc is not None:
version += f'rc{self.rc}'
return version
def release(args): def release(args):
@ -139,15 +119,15 @@ def release(args):
repo = gh.repository('lbryio', 'lbry-sdk') repo = gh.repository('lbryio', 'lbry-sdk')
version_file = repo.file_contents('lbry/lbry/__init__.py') version_file = repo.file_contents('lbry/lbry/__init__.py')
if not args.confirm:
print("\nDRY RUN ONLY. RUN WITH --confirm TO DO A REAL RELEASE.\n")
current_version = Version.from_content(version_file) current_version = Version.from_content(version_file)
print(f'Current Version: {current_version}') print(f'Current Version: {current_version}')
new_version = current_version.increment(args.action) new_version = current_version.increment(args.action)
print(f' New Version: {new_version}') print(f' New Version: {new_version}')
if args.action == '*-rc': previous_release = repo.release_from_tag(current_version.tag)
previous_release = repo.release_from_tag(args.start_tag or get_previous_final(repo, current_version))
else:
previous_release = repo.release_from_tag(current_version.tag)
print(f' Changelog From: {previous_release.tag_name} ({previous_release.created_at})') print(f' Changelog From: {previous_release.tag_name} ({previous_release.created_at})')
print() print()
@ -165,7 +145,7 @@ def release(args):
incompats.append(f' * [{area_name}] {incompat.strip()} ({pr.html_url})') incompats.append(f' * [{area_name}] {incompat.strip()} ({pr.html_url})')
for release_text in get_release_text(pr.body): for release_text in get_release_text(pr.body):
release_texts.append(f'{release_text.strip()} ({pr.html_url})') release_texts.append(f'{release_text.strip()} ({pr.html_url})')
if not (args.action == '*-rc' and type_label == 'fixup'): if type_label != 'fixup':
area = areas.setdefault(area_name, []) area = areas.setdefault(area_name, [])
area.append(f' * [{type_label}] {pr.title} ({pr.html_url}) by {pr.user["login"]}') area.append(f' * [{type_label}] {pr.title} ({pr.html_url}) by {pr.user["login"]}')
else: else:
@ -203,7 +183,7 @@ def release(args):
for skipped in unlabeled: for skipped in unlabeled:
print(skipped) print(skipped)
if not args.dry_run: if args.confirm:
commit = version_file.update( commit = version_file.update(
new_version.tag, new_version.tag,
@ -223,9 +203,10 @@ def release(args):
name=new_version.tag, name=new_version.tag,
body=body.getvalue(), body=body.getvalue(),
draft=True, draft=True,
prerelease=new_version.rc is not None
) )
return 0
class TestReleaseTool(unittest.TestCase): class TestReleaseTool(unittest.TestCase):
@ -235,44 +216,34 @@ class TestReleaseTool(unittest.TestCase):
def test_version_increment(self): def test_version_increment(self):
v = Version.from_string('1.2.3') v = Version.from_string('1.2.3')
self.assertTrue(str(v.increment('major+rc')), '2.0.0rc1') self.assertTrue(str(v.increment('major')), '2.0.0')
self.assertTrue(str(v.increment('minor+rc')), '1.3.0rc1') self.assertTrue(str(v.increment('minor')), '1.3.0')
self.assertTrue(str(v.increment('micro+rc')), '1.2.4rc1') self.assertTrue(str(v.increment('micro')), '1.2.4')
with self.assertRaisesRegex(AssertionError, "Must already be an rc to increment."):
v.increment('*+rc')
with self.assertRaisesRegex(AssertionError, "Can't drop rc designation"):
v.increment('*-rc')
v = Version.from_string('1.2.3rc3')
self.assertTrue(str(v.increment('*+rc')), '1.2.3rc4')
self.assertTrue(str(v.increment('*-rc')), '1.2.3')
with self.assertRaisesRegex(AssertionError, "already an rc"):
v.increment('major+rc')
with self.assertRaisesRegex(AssertionError, "already an rc"):
v.increment('minor+rc')
with self.assertRaisesRegex(AssertionError, "already an rc"):
v.increment('micro+rc')
def test(): def test():
runner = unittest.TextTestRunner(verbosity=2) runner = unittest.TextTestRunner(verbosity=2)
loader = unittest.TestLoader() loader = unittest.TestLoader()
suite = loader.loadTestsFromTestCase(TestReleaseTool) suite = loader.loadTestsFromTestCase(TestReleaseTool)
runner.run(suite) return 0 if runner.run(suite).wasSuccessful() else 1
def main(): def main():
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("--test", default=False, action="store_true", help="run unit tests") parser.add_argument("--confirm", default=False, action="store_true",
parser.add_argument("--dry-run", default=False, action="store_true", help="show what will be done") help="without this flag, it will only print what it will do but will not actually do it")
parser.add_argument("--start-tag", help="custom starting tag for changelog generation") parser.add_argument("--start-tag", help="custom starting tag for changelog generation")
parser.add_argument("action", nargs="?", choices=['major+rc', 'minor+rc', 'micro+rc', '*+rc', '*-rc']) parser.add_argument("action", choices=['test', 'major', 'minor', 'micro'])
args = parser.parse_args() args = parser.parse_args()
if args.test:
test() if args.action == "test":
code = test()
else: else:
release(args) code = release(args)
print()
return code
if __name__ == "__main__": if __name__ == "__main__":
main() sys.exit(main())