#!/usr/bin/python3
#安装requests模块(python3 -m pip install requests)
# method,打包的方式。方式分别为 development:1, ad-hoc:2, app-store:3, enterprise:4 默认为4
# python3 this.py upload=true(是否上传蒲公英)
import requests
import re,os
import sys
import subprocess
import time; # 引入time模块
from optparse import OptionParser
import biplist #python3 -m pip install biplist
import shutil
#蒲公英appkey(具体蒲公英上有详细文档)
PGYER_UPLOAD_URL = "https://www.pgyer.com/apiv2/app/upload"
API_Key = "xxx"
User_Key = "xxx"
# 是否编译工作空间 (例:若是用Cocopods管理的.xcworkspace项目,赋值true;用Xcode默认创建的.xcodeproj,赋值false)
is_workspace=True
# .xcworkspace的名字,如果is_workspace为true,则必须填。否则可不填
workspace_name="testpro"
# .xcodeproj的名字,如果is_workspace为false,则必须填。否则可不填
project_name="testpro"
# 指定项目的scheme名称(也就是工程的target名称),必填
scheme_name="testpro"
# 指定要打包编译的方式 : Release,Debug。一般用Release。必填
build_configuration="Release"
# 下面两个参数只是在手动指定Pofile文件的时候用到,如果使用Xcode自动管理Profile,直接留空就好
# (跟method对应的)mobileprovision文件名,需要先双击安装.mobileprovision文件.手动管理Profile时必填
provision_name="testpro-prod"
# 项目的bundleID,手动管理Profile时必填
bundle_identifier="com.xxx.testpro"
#工程目录
project_dir = ""
#打包方式
method = ""
#证书名称
mobileprovision_name="testpro-prod"
#是否上传
upload = False
#设置打包方式(一般不设置)
def setMethod(method_int):
global method
global mobileprovision_name
mobileprovision_name=provision_name
if method_int == 1:
method = "development"
elif method_int == 2:
method = "ad-hoc"
elif method_int == 3:
method = "app-store"
else :
method = "enterprise"
xcodeParameters()
#xcode参数配置
def xcodeParameters():
# =======================脚本的一些固定参数定义(无特殊情况不用修改)====================== #
global project_dir
global DATE
global export_path
global export_archive_path
global export_ipa_path
global ipa_name
global export_options_plist_path
# 工程根目录(脚本所在位置与xcodeproj同一目录下)
project_dir=os.getcwd()
# 时间
DATE=time.strftime("%Y%m%d_%H%M%S", time.localtime())
# 指定输出导出文件夹路径
export_path= project_dir+"/Package/"+scheme_name+"-"+DATE
# 指定输出归档文件路径
export_archive_path=export_path+"/"+scheme_name+".xcarchive"
# 指定输出ipa文件夹路径
export_ipa_path=export_path+"/"
# 指定输出ipa名称
ipa_name=scheme_name+"_"+DATE
# 指定导出ipa包需要用到的plist配置文件的路径
export_options_plist_path=project_dir+"/ExportOptions.plist"
print("--------------------脚本固定参数检查--------------------")
print("\033[33;1mproject_dir=\033[0m"+project_dir)
print("\033[33;1mDATE=\033[0m"+DATE)
print("\033[33;1mexport_path=\033[0m"+export_path)
print("\033[33;1mexport_archive_path=\033[0m"+export_archive_path)
print("\033[33;1mexport_ipa_path=\033[0m"+export_ipa_path)
print("\033[33;1mexport_options_plist_path=\033[0m"+export_options_plist_path)
print("\033[33;1mipa_name= \033[0m"+ipa_name)
archiveIPA()
#打包archive
def archiveIPA():
# =======================自动打包部分(无特殊情况不用修改)====================== #
print("------------------------------------------------------")
print("\033[32m开始构建项目 \033[0m")
# 进入项目工程目录
os.chdir(project_dir)
# 指定输出文件目录不存在则创建
if os.path.exists(export_path):
print(export_path)
else:
os.makedirs(export_path)
# 判断编译的项目类型是workspace还是project
if is_workspace:
# 编译前清理工程
xcodeClean = 'xcodebuild clean -workspace %s.xcworkspace -scheme %s -configuration %s' %(workspace_name, scheme_name, build_configuration)
os.system(xcodeClean)
archiveCmd = 'xcodebuild archive -workspace %s.xcworkspace -scheme %s -configuration %s -archivePath %s' %(workspace_name, scheme_name, build_configuration, export_archive_path)
os.system(archiveCmd)
else:
# 编译前清理工程
xcodeClean = 'xcodebuild clean -workspace %s.xcodeproj -scheme %s -configuration %s' %(project_name, scheme_name, build_configuration)
os.system(xcodeClean)
archiveCmd = 'xcodebuild archive -workspace %s.xcodeproj -scheme %s -configuration %s -archivePath %s' %(project_name, scheme_name, build_configuration, export_archive_path)
os.system(archiveCmd)
#
#
# 检查是否构建成功
# xcarchive 实际是一个文件夹不是一个文件所以使用 -d 判断
if os.path.exists(export_archive_path):
print("\033[32;1m项目构建成功 🚀 🚀 🚀 \033[0m")
else:
print("\033[31;1m项目构建失败 😢 😢 😢 \033[0m")
sys.exit(1)
existsIPA()
#导出ipa
def existsIPA():
print( "\033[32m开始导出ipa文件 \033[0m" )
# 先删除export_options_plist文件
if os.path.exists(export_options_plist_path):
print(export_options_plist_path+"文件存在,进行删除")
# rm -f $export_options_plist_path
os.remove(export_options_plist_path)
# 根据参数生成export_options_plist文件
exportOptionsPlist = "/usr/libexec/PlistBuddy -c 'Add :method String %s' %s" %(method, export_options_plist_path)
os.system(exportOptionsPlist)
exportOptionsPlist = "/usr/libexec/PlistBuddy -c 'Add :provisioningProfiles:' %s" %(export_options_plist_path)
os.system(exportOptionsPlist)
exportOptionsPlist = "/usr/libexec/PlistBuddy -c 'Add :provisioningProfiles:%s String %s' %s" %( bundle_identifier, mobileprovision_name,export_options_plist_path)
os.system(exportOptionsPlist)
exportArchive = 'xcodebuild -exportArchive -archivePath %s -exportPath %s -exportOptionsPlist %s -allowProvisioningUpdates' %(export_archive_path, export_ipa_path, export_options_plist_path)
os.system(exportArchive)
# 检查ipa文件是否存在
if os.path.exists(export_ipa_path+"/"+scheme_name+".ipa"):
print("\033[32;1mexportArchive ipa包成功,准备进行重命名\033[0m")
else:
print("\033[31;1mexportArchive ipa包失败 😢 😢 😢 \033[0m")
sys.exit(1)
# 修改ipa文件名称
os.rename(export_ipa_path+"/"+scheme_name+".ipa",export_ipa_path+"/"+ipa_name+".ipa")
# 检查文件是否存在
if os.path.exists(export_ipa_path+"/"+ipa_name+".ipa"):
print("\033[32;1m导出"+ipa_name+".ipa 包成功 🎉 🎉 🎉 \033[0m")
#上传ipa到蒲公英
if upload:
uploadIPAToPGYER()
else:
print("\033[31;1m导出"+ipa_name+".ipa 包失败 😢 😢 😢 \033[0m")
sys.exit(1)
# 删除export_options_plist文件(中间文件)
if os.path.exists(export_options_plist_path):
print(export_options_plist_path+"文件存在,准备删除")
os.remove(export_options_plist_path)
def uploadIPAToPGYER():
files = {'file': open(export_ipa_path+"/"+ipa_name+".ipa", 'rb')}
headers = {'enctype':'multipart/form-data'}
payload = {'_api_key':API_Key,'buildInstallType':2,'buildPassword':'123456'}
print ("uploading....")
print ("正在上传蒲公英(APIKEY):",API_Key)
r = requests.post(PGYER_UPLOAD_URL, data = payload ,files=files,headers=headers)
if r.status_code == requests.codes.ok:
result = r.json()
print(result);
sys.exit(0)
else:
print ('HTTPError,Code:'+r.status_code)
sys.exit(0)
def main():
start = time.time()
print ('参数个数为:', len(sys.argv), '个参数。')
tempMethod = 4
global upload
for str in sys.argv:
if 'method=' in str:
tempMethod = int(str.split('=')[1])
elif 'upload=' in str:
upload = True
print(tempMethod)
print(tempAmbient)
setMethod(tempMethod)
end = time.time()
print("\033[36;1m使用AutoPackageScript打包总用时: %ds \033[0m"%(end-start))
sys.exit(0)
if __name__ == '__main__':
main()
网友评论