PageRenderTime 26ms CodeModel.GetById 38ms RepoModel.GetById 0ms app.codeStats 0ms

/script/upload.py

https://gitlab.com/adambuckland/electron
Python | 233 lines | 183 code | 38 blank | 12 comment | 26 complexity | 09b87bb5fed0d23775b763bdcf35573f MD5 | raw file
  1. #!/usr/bin/env python
  2. import argparse
  3. import errno
  4. import os
  5. import subprocess
  6. import sys
  7. import tempfile
  8. from lib.config import PLATFORM, get_target_arch, get_chromedriver_version, \
  9. get_platform_key
  10. from lib.util import atom_gyp, execute, get_atom_shell_version, parse_version, \
  11. scoped_cwd
  12. from lib.github import GitHub
  13. ATOM_SHELL_REPO = 'electron/electron'
  14. ATOM_SHELL_VERSION = get_atom_shell_version()
  15. PROJECT_NAME = atom_gyp()['project_name%']
  16. PRODUCT_NAME = atom_gyp()['product_name%']
  17. SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
  18. OUT_DIR = os.path.join(SOURCE_ROOT, 'out', 'R')
  19. DIST_DIR = os.path.join(SOURCE_ROOT, 'dist')
  20. DIST_NAME = '{0}-{1}-{2}-{3}.zip'.format(PROJECT_NAME,
  21. ATOM_SHELL_VERSION,
  22. get_platform_key(),
  23. get_target_arch())
  24. SYMBOLS_NAME = '{0}-{1}-{2}-{3}-symbols.zip'.format(PROJECT_NAME,
  25. ATOM_SHELL_VERSION,
  26. get_platform_key(),
  27. get_target_arch())
  28. DSYM_NAME = '{0}-{1}-{2}-{3}-dsym.zip'.format(PROJECT_NAME,
  29. ATOM_SHELL_VERSION,
  30. get_platform_key(),
  31. get_target_arch())
  32. def main():
  33. args = parse_args()
  34. if not args.publish_release:
  35. if not dist_newer_than_head():
  36. create_dist = os.path.join(SOURCE_ROOT, 'script', 'create-dist.py')
  37. execute([sys.executable, create_dist])
  38. build_version = get_atom_shell_build_version()
  39. if not ATOM_SHELL_VERSION.startswith(build_version):
  40. error = 'Tag name ({0}) should match build version ({1})\n'.format(
  41. ATOM_SHELL_VERSION, build_version)
  42. sys.stderr.write(error)
  43. sys.stderr.flush()
  44. return 1
  45. github = GitHub(auth_token())
  46. releases = github.repos(ATOM_SHELL_REPO).releases.get()
  47. tag_exists = False
  48. for release in releases:
  49. if not release['draft'] and release['tag_name'] == args.version:
  50. tag_exists = True
  51. break
  52. release = create_or_get_release_draft(github, releases, args.version,
  53. tag_exists)
  54. if args.publish_release:
  55. # Upload the SHASUMS.txt.
  56. execute([sys.executable,
  57. os.path.join(SOURCE_ROOT, 'script', 'upload-checksums.py'),
  58. '-v', ATOM_SHELL_VERSION])
  59. # Upload the index.json.
  60. execute([sys.executable,
  61. os.path.join(SOURCE_ROOT, 'script', 'upload-index-json.py')])
  62. # Press the publish button.
  63. publish_release(github, release['id'])
  64. # Do not upload other files when passed "-p".
  65. return
  66. # Upload atom-shell with GitHub Releases API.
  67. upload_atom_shell(github, release, os.path.join(DIST_DIR, DIST_NAME))
  68. upload_atom_shell(github, release, os.path.join(DIST_DIR, SYMBOLS_NAME))
  69. if PLATFORM == 'darwin':
  70. upload_atom_shell(github, release, os.path.join(DIST_DIR, DSYM_NAME))
  71. # Upload free version of ffmpeg.
  72. ffmpeg = 'ffmpeg-{0}-{1}-{2}.zip'.format(
  73. ATOM_SHELL_VERSION, get_platform_key(), get_target_arch())
  74. upload_atom_shell(github, release, os.path.join(DIST_DIR, ffmpeg))
  75. # Upload chromedriver and mksnapshot for minor version update.
  76. if parse_version(args.version)[2] == '0':
  77. chromedriver = 'chromedriver-{0}-{1}-{2}.zip'.format(
  78. get_chromedriver_version(), get_platform_key(), get_target_arch())
  79. upload_atom_shell(github, release, os.path.join(DIST_DIR, chromedriver))
  80. mksnapshot = 'mksnapshot-{0}-{1}-{2}.zip'.format(
  81. ATOM_SHELL_VERSION, get_platform_key(), get_target_arch())
  82. upload_atom_shell(github, release, os.path.join(DIST_DIR, mksnapshot))
  83. if PLATFORM == 'win32' and not tag_exists:
  84. # Upload PDBs to Windows symbol server.
  85. execute([sys.executable,
  86. os.path.join(SOURCE_ROOT, 'script', 'upload-windows-pdb.py')])
  87. # Upload node headers.
  88. execute([sys.executable,
  89. os.path.join(SOURCE_ROOT, 'script', 'upload-node-headers.py'),
  90. '-v', args.version])
  91. def parse_args():
  92. parser = argparse.ArgumentParser(description='upload distribution file')
  93. parser.add_argument('-v', '--version', help='Specify the version',
  94. default=ATOM_SHELL_VERSION)
  95. parser.add_argument('-p', '--publish-release',
  96. help='Publish the release',
  97. action='store_true')
  98. return parser.parse_args()
  99. def get_atom_shell_build_version():
  100. if get_target_arch() == 'arm' or os.environ.has_key('CI'):
  101. # In CI we just build as told.
  102. return ATOM_SHELL_VERSION
  103. if PLATFORM == 'darwin':
  104. atom_shell = os.path.join(SOURCE_ROOT, 'out', 'R',
  105. '{0}.app'.format(PRODUCT_NAME), 'Contents',
  106. 'MacOS', PRODUCT_NAME)
  107. elif PLATFORM == 'win32':
  108. atom_shell = os.path.join(SOURCE_ROOT, 'out', 'R',
  109. '{0}.exe'.format(PROJECT_NAME))
  110. else:
  111. atom_shell = os.path.join(SOURCE_ROOT, 'out', 'R', PROJECT_NAME)
  112. return subprocess.check_output([atom_shell, '--version']).strip()
  113. def dist_newer_than_head():
  114. with scoped_cwd(SOURCE_ROOT):
  115. try:
  116. head_time = subprocess.check_output(['git', 'log', '--pretty=format:%at',
  117. '-n', '1']).strip()
  118. dist_time = os.path.getmtime(os.path.join(DIST_DIR, DIST_NAME))
  119. except OSError as e:
  120. if e.errno != errno.ENOENT:
  121. raise
  122. return False
  123. return dist_time > int(head_time)
  124. def get_text_with_editor(name):
  125. editor = os.environ.get('EDITOR', 'nano')
  126. initial_message = '\n# Please enter the body of your release note for %s.' \
  127. % name
  128. t = tempfile.NamedTemporaryFile(suffix='.tmp', delete=False)
  129. t.write(initial_message)
  130. t.close()
  131. subprocess.call([editor, t.name])
  132. text = ''
  133. for line in open(t.name, 'r'):
  134. if len(line) == 0 or line[0] != '#':
  135. text += line
  136. os.unlink(t.name)
  137. return text
  138. def create_or_get_release_draft(github, releases, tag, tag_exists):
  139. # Search for existing draft.
  140. for release in releases:
  141. if release['draft']:
  142. return release
  143. if tag_exists:
  144. tag = 'do-not-publish-me'
  145. return create_release_draft(github, tag)
  146. def create_release_draft(github, tag):
  147. name = '{0} {1}'.format(PROJECT_NAME, tag)
  148. if os.environ.has_key('CI'):
  149. body = '(placeholder)'
  150. else:
  151. body = get_text_with_editor(name)
  152. if body == '':
  153. sys.stderr.write('Quit due to empty release note.\n')
  154. sys.exit(0)
  155. data = dict(tag_name=tag, name=name, body=body, draft=True)
  156. r = github.repos(ATOM_SHELL_REPO).releases.post(data=data)
  157. return r
  158. def upload_atom_shell(github, release, file_path):
  159. # Delete the original file before uploading in CI.
  160. if os.environ.has_key('CI'):
  161. try:
  162. for asset in release['assets']:
  163. if asset['name'] == os.path.basename(file_path):
  164. github.repos(ATOM_SHELL_REPO).releases.assets(asset['id']).delete()
  165. break
  166. except Exception:
  167. pass
  168. # Upload the file.
  169. params = {'name': os.path.basename(file_path)}
  170. headers = {'Content-Type': 'application/zip'}
  171. with open(file_path, 'rb') as f:
  172. github.repos(ATOM_SHELL_REPO).releases(release['id']).assets.post(
  173. params=params, headers=headers, data=f, verify=False)
  174. def publish_release(github, release_id):
  175. data = dict(draft=False)
  176. github.repos(ATOM_SHELL_REPO).releases(release_id).patch(data=data)
  177. def auth_token():
  178. token = os.environ.get('ATOM_SHELL_GITHUB_TOKEN')
  179. message = ('Error: Please set the $ATOM_SHELL_GITHUB_TOKEN '
  180. 'environment variable, which is your personal token')
  181. assert token, message
  182. return token
  183. if __name__ == '__main__':
  184. import sys
  185. sys.exit(main())