release.py 3.0 KB

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