release.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. #!/usr/bin/env python3
  2. import re
  3. import click
  4. from git import Repo
  5. from utils import update_init_py_version
  6. from utils import update_run_sh_version
  7. from utils import yesno
  8. VALID_VERSION_PATTERN = re.compile(r"^\d+\.\d+\.\d+(-rc\d+)?$")
  9. class Version(str):
  10. def matching_groups(self):
  11. match = VALID_VERSION_PATTERN.match(self)
  12. if not match:
  13. return False
  14. return match.groups()
  15. def is_ga_version(self):
  16. groups = self.matching_groups()
  17. if not groups:
  18. return False
  19. rc_suffix = groups[1]
  20. return not rc_suffix
  21. def validate(self):
  22. return len(self.matching_groups()) > 0
  23. def branch_name(self):
  24. if not self.validate():
  25. return None
  26. rc_part = self.matching_groups()[0]
  27. ver = self
  28. if rc_part:
  29. ver = ver[:-len(rc_part)]
  30. tokens = ver.split(".")
  31. tokens[-1] = 'x'
  32. return ".".join(tokens)
  33. def create_bump_commit(repository, version):
  34. print('Creating bump commit...')
  35. repository.commit('-a', '-s', '-m "Bump {}"'.format(version), '--no-verify')
  36. def validate_environment(version, repository):
  37. if not version.validate():
  38. print('Version "{}" has an invalid format. This should follow D+.D+.D+(-rcD+). '
  39. 'Like: 1.26.0 or 1.26.0-rc1'.format(version))
  40. return False
  41. expected_branch = version.branch_name()
  42. if str(repository.active_branch) != expected_branch:
  43. print('Cannot tag in this branch with version "{}". '
  44. 'Please checkout "{}" to tag'.format(version, version.branch_name()))
  45. return False
  46. return True
  47. @click.group()
  48. def cli():
  49. pass
  50. @cli.command()
  51. @click.argument('version')
  52. def tag(version):
  53. """
  54. Updates the version related files and tag
  55. """
  56. repo = Repo(".")
  57. version = Version(version)
  58. if not validate_environment(version, repo):
  59. return
  60. update_init_py_version(version)
  61. update_run_sh_version(version)
  62. input('Please add the release notes to the CHANGELOG.md file, then press Enter to continue.')
  63. proceed = False
  64. while not proceed:
  65. print(repo.git.diff())
  66. proceed = yesno('Are these changes ok? y/N ', default=False)
  67. if repo.git.diff():
  68. create_bump_commit(repo.git, version)
  69. else:
  70. print('No changes to commit. Exiting...')
  71. return
  72. repo.create_tag(version)
  73. print('Please, check the changes. If everything is OK, you just need to push with:\n'
  74. '$ git push --tags upstream {}'.format(version.branch_name()))
  75. @cli.command()
  76. @click.argument('version')
  77. def push_latest(version):
  78. """
  79. TODO Pushes the latest tag pointing to a certain GA version
  80. """
  81. raise NotImplementedError
  82. @cli.command()
  83. @click.argument('version')
  84. def ghtemplate(version):
  85. """
  86. TODO Generates the github release page content
  87. """
  88. version = Version(version)
  89. raise NotImplementedError
  90. if __name__ == '__main__':
  91. cli()