updates.py 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. import os, sys, re, subprocess, datetime, time
  2. executePath = os.getcwd()
  3. scriptPath = os.path.dirname(os.path.realpath(__file__))
  4. lastCommit = ''
  5. today = ''
  6. uuid = ''
  7. nextLast = False
  8. nextDate = False
  9. nextUuid = False
  10. building = True
  11. composing = False
  12. conf = 'Release'
  13. for arg in sys.argv:
  14. if nextLast:
  15. lastCommit = arg
  16. nextLast = False
  17. elif nextDate:
  18. today = arg
  19. nextDate = False
  20. elif nextUuid:
  21. uuid = arg
  22. nextUuid = False
  23. elif arg == 'send':
  24. building = False
  25. composing = False
  26. elif arg == 'from':
  27. nextLast = True
  28. building = False
  29. composing = True
  30. elif arg == 'date':
  31. nextDate = True
  32. elif arg == 'request_uuid':
  33. nextUuid = True
  34. elif arg == 'debug':
  35. conf = 'Debug'
  36. def finish(code, error = ''):
  37. if error != '':
  38. print('[ERROR] ' + error)
  39. global executePath
  40. os.chdir(executePath)
  41. sys.exit(code)
  42. os.chdir(scriptPath + '/..')
  43. if 'AC_USERNAME' not in os.environ:
  44. finish(1, 'AC_USERNAME not found!')
  45. username = os.environ['AC_USERNAME']
  46. if today == '':
  47. today = datetime.datetime.now().strftime("%d_%m_%y")
  48. outputFolder = 'updates/' + today
  49. archive = 'tdesktop_macOS_' + today + '.zip'
  50. if building:
  51. print('Building ' + conf + ' version for OS X 10.13+..')
  52. if os.path.exists('../out/' + conf + '/' + outputFolder):
  53. finish(1, 'Todays updates version exists.')
  54. if uuid == '':
  55. result = subprocess.call('./configure.sh', shell=True)
  56. if result != 0:
  57. finish(1, 'While calling GYP.')
  58. os.chdir('../out')
  59. if uuid == '':
  60. result = subprocess.call('cmake --build . --config ' + conf + ' --target Telegram', shell=True)
  61. if result != 0:
  62. finish(1, 'While building Telegram.')
  63. os.chdir(conf);
  64. if uuid == '':
  65. if not os.path.exists('Telegram.app'):
  66. finish(1, 'Telegram.app not found.')
  67. result = subprocess.call('strip Telegram.app/Contents/MacOS/Telegram', shell=True)
  68. if result != 0:
  69. finish(1, 'While stripping Telegram.')
  70. result = subprocess.call('codesign --force --deep --timestamp --options runtime --sign "Developer ID Application: Telegram FZ-LLC (C67CF9S4VU)" Telegram.app --entitlements "../../Telegram/Telegram/Telegram.entitlements"', shell=True)
  71. if result != 0:
  72. finish(1, 'While signing Telegram.')
  73. if not os.path.exists('Telegram.app/Contents/Frameworks/Updater'):
  74. finish(1, 'Updater not found.')
  75. elif not os.path.exists('Telegram.app/Contents/Helpers/crashpad_handler'):
  76. finish(1, 'crashpad_handler not found.')
  77. elif not os.path.exists('Telegram.app/Contents/_CodeSignature'):
  78. finish(1, 'Signature not found.')
  79. if os.path.exists(today):
  80. subprocess.call('rm -rf ' + today, shell=True)
  81. result = subprocess.call('mkdir -p ' + today + '/TelegramForcePortable', shell=True)
  82. if result != 0:
  83. finish(1, 'Creating folder ' + today + '/TelegramForcePortable')
  84. result = subprocess.call('cp -r Telegram.app ' + today + '/', shell=True)
  85. if result != 0:
  86. finish(1, 'Cloning Telegram.app to ' + today + '.')
  87. result = subprocess.call('zip -r ' + archive + ' ' + today, shell=True)
  88. if result != 0:
  89. finish(1, 'Adding tdesktop to archive.')
  90. print('Beginning notarization process.')
  91. result = subprocess.call('xcrun notarytool submit "' + archive + '" --keychain-profile "preston" --wait', shell=True)
  92. if result != 0:
  93. finish(1, 'Notarizing the archive.')
  94. result = subprocess.call('xcrun stapler staple Telegram.app', shell=True)
  95. if result != 0:
  96. finish(1, 'Error calling stapler')
  97. subprocess.call('rm -rf ' + today + '/Telegram.app', shell=True)
  98. subprocess.call('rm ' + archive, shell=True)
  99. result = subprocess.call('cp -r Telegram.app ' + today + '/', shell=True)
  100. if result != 0:
  101. finish(1, 'Re-Cloning Telegram.app to ' + today + '.')
  102. result = subprocess.call('zip -r ' + archive + ' ' + today, shell=True)
  103. if result != 0:
  104. finish(1, 'Re-Adding tdesktop to archive.')
  105. print('Re-Archived.')
  106. subprocess.call('mkdir -p ' + outputFolder, shell=True)
  107. subprocess.call('mv ' + archive + ' ' + outputFolder + '/', shell=True)
  108. subprocess.call('rm -rf ' + today, shell=True)
  109. print('Finished.')
  110. finish(0)
  111. commandPath = scriptPath + '/../../out/' + conf + '/' + outputFolder + '/command.txt'
  112. if composing:
  113. templatePath = scriptPath + '/../../../DesktopPrivate/updates_template.txt'
  114. if not os.path.exists(templatePath):
  115. finish(1, 'Template file "' + templatePath + '" not found.')
  116. if not re.match(r'^[a-f0-9]{9,40}$', lastCommit):
  117. finish(1, 'Wrong last commit: ' + lastCommit)
  118. log = subprocess.check_output(['git', 'log', lastCommit+'..HEAD']).decode('utf-8')
  119. logLines = log.split('\n')
  120. firstCommit = ''
  121. commits = []
  122. for line in logLines:
  123. if line.startswith('commit '):
  124. commit = line.split(' ')[1]
  125. if not len(firstCommit):
  126. firstCommit = commit
  127. commits.append('')
  128. elif line.startswith(' '):
  129. stripped = line[4:]
  130. if not len(stripped):
  131. continue
  132. elif not len(commits):
  133. print(log)
  134. finish(1, 'Bad git log output.')
  135. if len(commits[len(commits) - 1]):
  136. commits[len(commits) - 1] += '\n' + stripped
  137. else:
  138. commits[len(commits) - 1] = '- ' + stripped
  139. commits.reverse()
  140. if not len(commits):
  141. finish(1, 'No commits since last build :(')
  142. changelog = '\n'.join(commits)
  143. print('\n\nReady! File: ' + archive + '\nChangelog:\n' + changelog)
  144. with open(templatePath, 'r') as template:
  145. with open(commandPath, 'w') as f:
  146. for line in template:
  147. if line.startswith('//'):
  148. continue
  149. line = line.replace('{path}', scriptPath + '/../../out/' + conf + '/' + outputFolder + '/' + archive)
  150. line = line.replace('{caption}', 'TDesktop at ' + today.replace('_', '.') + ':\n\n' + changelog)
  151. f.write(line)
  152. print('\n\nEdit:\n')
  153. print('vi ' + commandPath)
  154. finish(0)
  155. if not os.path.exists(commandPath):
  156. finish(1, 'Command file not found.')
  157. readingCaption = False
  158. caption = ''
  159. with open(commandPath, 'r') as f:
  160. for line in f:
  161. if readingCaption:
  162. caption = caption + line
  163. elif line.startswith('caption: '):
  164. readingCaption = True
  165. caption = line[len('caption: '):]
  166. if not caption.startswith('TDesktop at ' + today.replace('_', '.') + ':'):
  167. finish(1, 'Wrong caption start.')
  168. print('\n\nSending! File: ' + archive + '\nChangelog:\n' + caption)
  169. if len(caption) > 1024:
  170. print('Length: ' + str(len(caption)))
  171. print('vi ' + commandPath)
  172. finish(1, 'Too large.')
  173. if not os.path.exists('../out/' + conf + '/' + outputFolder + '/' + archive):
  174. finish(1, 'Not built yet.')
  175. subprocess.call(scriptPath + '/../../out/' + conf + '/Telegram.app/Contents/MacOS/Telegram -sendpath interpret://' + scriptPath + '/../../out/' + conf + '/' + outputFolder + '/command.txt', shell=True)
  176. finish(0)