create_rpm_git_repo.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #!/usr/bin/env python3
  2. from __future__ import print_function
  3. import argparse
  4. import os
  5. import re
  6. import subprocess
  7. import sys
  8. from github import Github
  9. TEAMS = {
  10. "Hypervisor & Kernel": ['hk', 'hypervisor'],
  11. "OS Platform & Release": ['opr', 'platform'],
  12. 'Security': ['security'],
  13. 'Storage': ['storage'],
  14. 'XAPI & Network': ['xn', 'network', 'xapi'],
  15. }
  16. TEAM_CHOICES = list(TEAMS.keys()) + [n for ns in TEAMS.values() for n in ns]
  17. TEAM_ALIASES = dict([(alias, team) for team, aliases in TEAMS.items() for alias in aliases]
  18. + [(team, team) for team in TEAMS])
  19. def to_gh_team(maintainer: str):
  20. return '@xcp-ng-rpms/' + re.sub(r'\W+', '-', maintainer.lower())
  21. def main():
  22. parser = argparse.ArgumentParser(description='Creates a git repository in current directory for RPM spec file and'
  23. ' sources')
  24. parser.add_argument('name', help='name of repository')
  25. parser.add_argument('--local',
  26. help='do not create github repository',
  27. action='store_true')
  28. parser.add_argument('-m', '--maintainer', choices=TEAM_CHOICES, help='Configure code owners to this team')
  29. parser.add_argument('token_file',
  30. help='file containing github authentication token',
  31. nargs='?',
  32. default=os.path.join(os.path.dirname(os.path.realpath(__file__)), 'github.txt'))
  33. args = parser.parse_args()
  34. if args.maintainer is None:
  35. print('error: please assign a team with --maintainer', file=sys.stderr)
  36. exit(1)
  37. maintainer = TEAM_ALIASES[args.maintainer]
  38. if not args.local:
  39. # authenticate to Github
  40. if os.access(args.token_file, os.R_OK):
  41. with open(args.token_file) as f:
  42. token = f.read().strip()
  43. elif 'GITHUB_TOKEN' in os.environ:
  44. token = os.environ['GITHUB_TOKEN']
  45. else:
  46. print('error: please provide a github access token', file=sys.stderr)
  47. exit(1)
  48. g = Github(token)
  49. # create repository
  50. org = g.get_organization('xcp-ng-rpms')
  51. org.create_repo(args.name, "RPM sources for %s" % args.name)
  52. # initial commit to master
  53. gitignore = """BUILD
  54. BUILDROOT
  55. RPMS
  56. SRPMS
  57. """
  58. readme = """RPM sources for the %s package in XCP-ng (https://xcp-ng.org/).
  59. Make sure to have `git-lfs` installed before cloning. It is used for handling source archives separately.
  60. Branches:
  61. * `master` contains sources for the next `x.y` release of XCP-ng.
  62. * `x.y` (e.g. `7.5`) contains sources for the `x.y` release of XCP-ng, with their bugfix and/or security updates.
  63. * `XS-x.y` (e.g. `XS-7.5`), when they exist, contain sources from the `x.y` release of XenServer, with trademarked
  64. or copyrighted material stripped if needed.
  65. Built RPMs and source RPMs are available on https://updates.xcp-ng.org.
  66. """ % args.name
  67. if args.local:
  68. subprocess.check_call(['git', 'init', '-b', 'master', args.name])
  69. subprocess.check_call(['git', '-C', args.name,
  70. 'remote', 'add', 'origin',
  71. 'https://github.com/xcp-ng-rpms/%s.git' % args.name])
  72. else:
  73. subprocess.check_call(['git', 'clone', 'https://github.com/xcp-ng-rpms/%s.git' % args.name])
  74. os.chdir(args.name)
  75. if "git@github.com" not in subprocess.check_output(
  76. ['git', 'remote', 'get-url', '--push', 'origin'],
  77. universal_newlines=True):
  78. # only set if pushInsteadOf was not configured
  79. subprocess.check_call(['git', 'remote', 'set-url', '--push', 'origin',
  80. 'git@github.com:xcp-ng-rpms/%s.git' % args.name])
  81. with open('.gitignore', 'w') as f:
  82. f.write(gitignore)
  83. subprocess.check_call(['git', 'add', '.gitignore'])
  84. with open('README.md', 'w') as f:
  85. f.write(readme)
  86. subprocess.check_call(['git', 'add', 'README.md'])
  87. # create the CODEOWNERS file
  88. content = f"* {to_gh_team(maintainer)}\n"
  89. # make sure the platform team is owner of all the repositories
  90. if maintainer != TEAM_ALIASES['platform']:
  91. content += f"* {to_gh_team(TEAM_ALIASES['platform'])}\n"
  92. os.mkdir('.github')
  93. with open('.github/CODEOWNERS', 'w') as f:
  94. f.write(content)
  95. subprocess.check_call(['git', 'add', '.github'])
  96. subprocess.check_call(['git', 'add', 'README.md'])
  97. subprocess.check_call(['git', 'lfs', 'install'])
  98. subprocess.check_call(['git', 'lfs', 'track', '*.gz'])
  99. subprocess.check_call(['git', 'lfs', 'track', '*.bz2'])
  100. subprocess.check_call(['git', 'lfs', 'track', '*.xz'])
  101. subprocess.check_call(['git', 'lfs', 'track', '*.zip'])
  102. subprocess.check_call(['git', 'lfs', 'track', '*.tar'])
  103. subprocess.check_call(['git', 'lfs', 'track', '*.tgz'])
  104. subprocess.check_call(['git', 'lfs', 'track', '*.tbz'])
  105. subprocess.check_call(['git', 'add', '.gitattributes'])
  106. subprocess.check_call(['git', 'commit', '-s', '-m', 'Initial commit'])
  107. if not args.local:
  108. subprocess.check_call(['git', 'push'])
  109. if __name__ == "__main__":
  110. main()