iOS自动打包上传脚本
source link: https://www.devashen.com/blog/2017/02/22/autobuild/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
iOS自动打包上传脚本
Feb 22nd, 2017 4:46 pm | 评论
自从将swift2.2升级到swift3.0, 每次使用Xcode8编译都很慢,很是不爽,于是有了研究下xcodebuild命令行打包的想法,起初不知道用shell,还是用python, 在网上大概搜了一下,关于python的比较多点,于是就先学习python的基础语法,然后再去看看大神的一些脚本,就开始专研命令行打包了。总之,过程很艰辛,结果很满意,以下便是我修改后的python自动打包脚本,命令行使用,打包完成会询问是否上传蒲公英平台,以及询问是否上传appstore,还有是否保留archive文件。
自动打包脚本下载地址
1、下载完成后,将autobuild.py以及exportOptions.plist文件放到你的项目跟目录下(即与xx.xcworkspace或者xx.xcworkspace在同一个目录下)
2、打开autobuild.py,修改配置信息
3、打开命令终端,进入项目根目录
a.如果你是xx.xcodeproj
./autobuild.py -p youproject.xcodeproj
b.如果你是xx.xcworkspace
./autobuild.py -w youproject.xcworkspace
4、等待终端回应,依据终端提示进行相关操作
5、最终会在桌面生成带有时间戳的文件夹,含义ipa以及xcarchive文件
#!/usr/bin/env python # -*- coding:utf-8 -*- #./autobuild.py -p youproject.xcodeproj #./autobuild.py -w youproject.xcworkspace import argparse import subprocess import requests import os import datetime #configuration for iOS build setting CONFIGURATION = "Release" EXPORT_OPTIONS_PLIST = "exportOptions.plist" #发布版本号 VERSION = '1.0.0' BUILD = '17021803' #要打包的TARGET名字 TARGET = 'ULife' #Info.plist路径 PLIST_PATH = "xxxxxx/Info.plist" #存放路径以时间命令 DATE = datetime.datetime.now().strftime('%Y-%m-%d_%H.%M.%S') #会在桌面创建输出ipa文件的目录 EXPORT_MAIN_DIRECTORY = "~/Desktop/" + TARGET + DATE #xcarchive文件路径(含有dsym),后续查找BUG用途 ARCHIVEPATH = EXPORT_MAIN_DIRECTORY + "/%s%s.xcarchive" %(TARGET,VERSION) #ipa路径 IPAPATH = EXPORT_MAIN_DIRECTORY + "/%s.ipa" %(TARGET) #苹果开发者账号 APPLEID = 'xxxxxx' APPLEPWD = 'xxxxx' # configuration for pgyer PGYER_UPLOAD_URL = "http://www.pgyer.com/apiv1/app/upload" DOWNLOAD_BASE_URL = "http://www.pgyer.com" USER_KEY = "xxxxxx" API_KEY = "xxxxx" #设置从蒲公英下载应用时的密码 PYGER_PASSWORD = "xxxxx" def cleanArchiveFile(): cleanCmd = "rm -r %s" %(ARCHIVEPATH) process = subprocess.Popen(cleanCmd, shell = True) process.wait() print "cleaned archiveFile: %s" %(ARCHIVEPATH) def uploadIpaToAppStore(): print "iPA上传中...." altoolPath = "/Applications/Xcode.app/Contents/Applications/Application\ Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/altool" exportCmd = "%s --validate-app -f %s -u %s -p %s -t ios --output-format xml" % (altoolPath, IPAPATH, APPLEID,APPLEPWD) process = subprocess.Popen(exportCmd, shell=True) (stdoutdata, stderrdata) = process.communicate() validateResult = process.returncode if validateResult == 0: print '~~~~~~~~~~~~~~~~iPA验证通过~~~~~~~~~~~~~~~~' exportCmd = "%s --upload-app -f %s -u %s -p %s -t ios --output-format normal" % ( altoolPath, IPAPATH, APPLEID, APPLEPWD) process = subprocess.Popen(exportCmd, shell=True) (stdoutdata, stderrdata) = process.communicate() uploadresult = process.returncode if uploadresult == 0: print '~~~~~~~~~~~~~~~~iPA上传成功' else: print '~~~~~~~~~~~~~~~~iPA上传失败' else: print "~~~~~~~~~~~~~~~~iPA验证失败~~~~~~~~~~~~~~~~" def parserUploadResult(jsonResult): resultCode = jsonResult['code'] if resultCode == 0: downUrl = DOWNLOAD_BASE_URL +"/"+jsonResult['data']['appShortcutUrl'] print "Upload Success" print "DownUrl is:" + downUrl else: print "Upload Fail!" print "Reason:"+jsonResult['message'] def uploadIpaToPgyer(ipaPath): print "ipaPath:"+ipaPath ipaPath = os.path.expanduser(ipaPath) ipaPath = unicode(ipaPath, "utf-8") files = {'file': open(ipaPath, 'rb')} headers = {'enctype':'multipart/form-data'} payload = {'uKey':USER_KEY,'_api_key':API_KEY,'publishRange':'2','isPublishToPublic':'2', 'password':PYGER_PASSWORD} print "uploading...." r = requests.post(PGYER_UPLOAD_URL, data = payload ,files=files,headers=headers) if r.status_code == requests.codes.ok: result = r.json() parserUploadResult(result) else: print 'HTTPError,Code:'+r.status_code def exportArchive(): exportCmd = "xcodebuild -exportArchive -archivePath %s -exportPath %s -exportOptionsPlist %s" %(ARCHIVEPATH, EXPORT_MAIN_DIRECTORY, EXPORT_OPTIONS_PLIST) process = subprocess.Popen(exportCmd, shell=True) (stdoutdata, stderrdata) = process.communicate() signReturnCode = process.returncode if signReturnCode != 0: print "export %s failed" %(TARGET) return "" else: return EXPORT_MAIN_DIRECTORY def buildProject(project): archiveCmd = 'xcodebuild -project %s -scheme %s -configuration %s archive -archivePath %s -destination generic/platform=iOS' %(project, TARGET, CONFIGURATION, ARCHIVEPATH) process = subprocess.Popen(archiveCmd, shell=True) process.wait() archiveReturnCode = process.returncode if archiveReturnCode != 0: print "archive project %s failed" %(project) cleanArchiveFile() def buildWorkspace(workspace): archiveCmd = 'xcodebuild -workspace %s -scheme %s -configuration %s archive -archivePath %s -destination generic/platform=iOS' %(workspace, TARGET, CONFIGURATION, ARCHIVEPATH) process = subprocess.Popen(archiveCmd, shell=True) process.wait() archiveReturnCode = process.returncode if archiveReturnCode != 0: print "archive workspace %s failed" %(workspace) cleanArchiveFile() def xcbuild(options): project = options.project workspace = options.workspace if project is None and workspace is None: pass elif project is not None: buildProject(project) elif workspace is not None: buildWorkspace(workspace) #导出ipa文件 exportarchive = exportArchive() print "~~~~~~~~~~~~~~~~是否上传到蒲公英~~~~~~~~~~~~~~~~" print " 1 不上传 (默认)" print " 2 上传 " isuploadpgyer = raw_input("您的决定:") if isuploadpgyer == "2" and exportarchive != "": uploadIpaToPgyer(IPAPATH) print "~~~~~~~~~~~~~~~~是否上传到AppStore~~~~~~~~~~~~~~~~" print " 1 不上传 (默认)" print " 2 上传 " isuploadappstore = raw_input("您的决定:") if isuploadappstore == '2': uploadIpaToAppStore() else: print "~~~~~~~~~~~~~~~~是否删除archive文件~~~~~~~~~~~~~~~~" print " 1 保留 (默认)" print " 2 删除 " iscleararchive = raw_input("您的决定:") if iscleararchive == "2": cleanArchiveFile() def main(): parser = argparse.ArgumentParser() parser.add_argument("-w", "--workspace", help="Build the workspace name.xcworkspace.", metavar="name.xcworkspace") parser.add_argument("-p", "--project", help="Build the project name.xcodeproj.", metavar="name.xcodeproj") options = parser.parse_args() print "options: %s" % (options) os.system('/usr/libexec/PlistBuddy -c "Set:CFBundleShortVersionString %s" %s' % (VERSION,PLIST_PATH)) os.system('/usr/libexec/PlistBuddy -c "Set:CFBundleVersion %s" %s' % (BUILD, PLIST_PATH)) xcbuild(options) if __name__ == '__main__': main()
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK