autobuild.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. #./autobuild.py -p youproject.xcodeproj
  4. #./autobuild.py -w youproject.xcworkspace
  5. import argparse
  6. import subprocess
  7. import requests
  8. import os
  9. import datetime
  10. #configuration for iOS build setting
  11. CONFIGURATION = "Release"
  12. EXPORT_OPTIONS_PLIST = "exportOptions.plist"
  13. #发布版本号
  14. VERSION = '1.0.6'
  15. BUILD = '1'
  16. #要打包的TARGET名字
  17. TARGET = 'SolarLamp'
  18. #Info.plist路径
  19. PLIST_PATH = "../SolarLamp/SolarLampShare/Info.plist"
  20. #存放路径以时间命令
  21. DATE = datetime.datetime.now().strftime('%Y-%m-%d_%H.%M.%S')
  22. #会在桌面创建输出ipa文件的目录
  23. EXPORT_MAIN_DIRECTORY = "~/Desktop/" + TARGET + DATE
  24. #xcarchive文件路径(含有dsym),后续查找BUG用途
  25. ARCHIVEPATH = EXPORT_MAIN_DIRECTORY + "/%s%s.xcarchive" %(TARGET,VERSION)
  26. #ipa路径
  27. IPAPATH = EXPORT_MAIN_DIRECTORY + "/%s.ipa" %(TARGET)
  28. #苹果开发者账号
  29. APPLEID = 'zhnansong@hotmail.com'
  30. APPLEPWD = 'Tw060538'
  31. # configuration for pgyer
  32. PGYER_UPLOAD_URL = "http://www.pgyer.com/apiv1/app/upload"
  33. DOWNLOAD_BASE_URL = "http://www.pgyer.com"
  34. USER_KEY = "dc86bc578930052ae83ca5866dd2ea26"
  35. API_KEY = "0ff3943f4ddb2a4e52cab07e51f705a7"
  36. #设置从蒲公英下载应用时的密码
  37. PYGER_PASSWORD = ""
  38. def cleanArchiveFile():
  39. cleanCmd = "rm -r %s" %(ARCHIVEPATH)
  40. process = subprocess.Popen(cleanCmd, shell = True)
  41. process.wait()
  42. print "cleaned archiveFile: %s" %(ARCHIVEPATH)
  43. def uploadIpaToAppStore():
  44. print "iPA上传中...."
  45. altoolPath = "/Applications/Xcode.app/Contents/Applications/Application\ Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/altool"
  46. exportCmd = "%s --validate-app -f %s -u %s -p %s -t ios --output-format xml" % (altoolPath, IPAPATH, APPLEID,APPLEPWD)
  47. process = subprocess.Popen(exportCmd, shell=True)
  48. (stdoutdata, stderrdata) = process.communicate()
  49. validateResult = process.returncode
  50. if validateResult == 0:
  51. print '~~~~~~~~~~~~~~~~iPA验证通过~~~~~~~~~~~~~~~~'
  52. exportCmd = "%s --upload-app -f %s -u %s -p %s -t ios --output-format normal" % (
  53. altoolPath, IPAPATH, APPLEID, APPLEPWD)
  54. process = subprocess.Popen(exportCmd, shell=True)
  55. (stdoutdata, stderrdata) = process.communicate()
  56. uploadresult = process.returncode
  57. if uploadresult == 0:
  58. print '~~~~~~~~~~~~~~~~iPA上传成功'
  59. else:
  60. print '~~~~~~~~~~~~~~~~iPA上传失败'
  61. else:
  62. print "~~~~~~~~~~~~~~~~iPA验证失败~~~~~~~~~~~~~~~~"
  63. def parserUploadResult(jsonResult):
  64. resultCode = jsonResult['code']
  65. if resultCode == 0:
  66. downUrl = DOWNLOAD_BASE_URL +"/"+jsonResult['data']['appShortcutUrl']
  67. print "Upload Success"
  68. print "DownUrl is:" + downUrl
  69. else:
  70. print "Upload Fail!"
  71. print "Reason:"+jsonResult['message']
  72. def uploadIpaToPgyer(ipaPath):
  73. print "ipaPath:"+ipaPath
  74. ipaPath = os.path.expanduser(ipaPath)
  75. ipaPath = unicode(ipaPath, "utf-8")
  76. files = {'file': open(ipaPath, 'rb')}
  77. headers = {'enctype':'multipart/form-data'}
  78. payload = {'uKey':USER_KEY,'_api_key':API_KEY,'publishRange':'2','isPublishToPublic':'2', 'password':PYGER_PASSWORD}
  79. print "uploading...."
  80. r = requests.post(PGYER_UPLOAD_URL, data = payload ,files=files,headers=headers)
  81. if r.status_code == requests.codes.ok:
  82. result = r.json()
  83. parserUploadResult(result)
  84. else:
  85. print 'HTTPError,Code:'+r.status_code
  86. def exportArchive():
  87. exportCmd = "xcodebuild -exportArchive -archivePath %s -exportPath %s -exportOptionsPlist %s" %(ARCHIVEPATH, EXPORT_MAIN_DIRECTORY, EXPORT_OPTIONS_PLIST)
  88. process = subprocess.Popen(exportCmd, shell=True)
  89. (stdoutdata, stderrdata) = process.communicate()
  90. signReturnCode = process.returncode
  91. if signReturnCode != 0:
  92. print "export %s failed" %(TARGET)
  93. return ""
  94. else:
  95. return EXPORT_MAIN_DIRECTORY
  96. def buildProject(project):
  97. archiveCmd = 'xcodebuild -project %s -scheme %s -configuration %s archive -archivePath %s -destination generic/platform=iOS' %(project, TARGET, CONFIGURATION, ARCHIVEPATH)
  98. process = subprocess.Popen(archiveCmd, shell=True)
  99. process.wait()
  100. archiveReturnCode = process.returncode
  101. if archiveReturnCode != 0:
  102. print "archive project %s failed" %(project)
  103. cleanArchiveFile()
  104. def buildWorkspace(workspace):
  105. archiveCmd = 'xcodebuild -workspace %s -scheme %s -configuration %s archive -archivePath %s -destination generic/platform=iOS' %(workspace, TARGET, CONFIGURATION, ARCHIVEPATH)
  106. process = subprocess.Popen(archiveCmd, shell=True)
  107. process.wait()
  108. archiveReturnCode = process.returncode
  109. if archiveReturnCode != 0:
  110. print "archive workspace %s failed" %(workspace)
  111. cleanArchiveFile()
  112. def uploadIpaToAll():
  113. # uploadIpaToPgyer(IPAPATH)
  114. uploadIpaToAppStore()
  115. def sendChoice(sendtype):
  116. if sendtype == "no":
  117. return
  118. elif sendtype == "pgy":
  119. uploadIpaToPgyer(IPAPATH)
  120. else:
  121. uploadIpaToAll()
  122. def select_option_run(options):
  123. project = options.project
  124. workspace = options.workspace
  125. command = options.command
  126. sendtype = options.sendtype
  127. if command == "build":
  128. if project is None and workspace is None:
  129. pass
  130. elif project is not None:
  131. buildProject(project)
  132. elif workspace is not None:
  133. buildWorkspace(workspace)
  134. exportarchive = exportArchive()
  135. sendChoice(sendtype)
  136. elif command == "send":
  137. sendChoice(sendtype)
  138. def main():
  139. parser = argparse.ArgumentParser()
  140. parser.add_argument("-w", "--workspace", help="Build the workspace name.xcworkspace.", metavar="name.xcworkspace")
  141. parser.add_argument("-p", "--project", help="Build the project name.xcodeproj.", metavar="name.xcodeproj")
  142. parser.add_argument("-c", "--command", help="Select your arction command", metavar="build", default="build")
  143. parser.add_argument("-t", "--sendtype", help="Select your arction command", metavar="no", default="no")
  144. options = parser.parse_args()
  145. print "options: %s" % (options)
  146. os.system('/usr/libexec/PlistBuddy -c "Set:CFBundleShortVersionString %s" %s' % (VERSION,PLIST_PATH))
  147. os.system('/usr/libexec/PlistBuddy -c "Set:CFBundleVersion %s" %s' % (BUILD, PLIST_PATH))
  148. select_option_run(options)
  149. if __name__ == '__main__':
  150. main()