unity之Jenkins自动化出包shell脚本
Posted jietian331
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了unity之Jenkins自动化出包shell脚本相关的知识,希望对你有一定的参考价值。
jenkins工具自动化出包,此功能不是我做的。
用到的shell脚本分享一下,以备将来研究之用。
Jenkins中构建:
命令为:
1 #!C:/Program Files/Git/bin/bash 2 python -u D:/buildApk_New/USA/sgmyPackge/package.py $Versions E:/WorkTool/Unity2017.4/Unity/Editor/Unity.exe $VersionIncrease $BuildFlavor $BigPackage
shell脚本如下:
1. utils.py
1 import hashlib 2 import subprocess 3 import platform 4 import shutil 5 import os 6 7 _FILE_SLIM = (100 * 1024 * 1024) # 100MB 8 cur_os = platform.system() 9 10 def subprocess_return(cmd): 11 print(cmd) 12 status = subprocess.call(cmd,shell = True) 13 return status 14 15 def subprocess_call(cmd): 16 print (cmd) 17 status = subprocess.call(cmd,shell = True) 18 if status != 0: 19 exit(status) 20 21 def CheckUnity(): 22 cmd = "ps -ef|grep MacOS/Unity |grep -v CheckUnity |grep -v grep " 23 if cur_os == "Windows": 24 cmd = "tasklist | findstr Unity" 25 status = subprocess.call(cmd,shell = True) 26 if status == 0 : 27 print ("Unity is running!!") 28 return status 29 30 def killUnity(): 31 cmd = "killall -9 Unity" 32 if cur_os == "Windows": 33 cmd = "taskkill /f /im Unity.exe" 34 status = subprocess.call(cmd,shell = True) 35 if status == 0 : 36 print ("no running Unity") 37 return status 38 39 def file_md5(filename): 40 calltimes = 0 41 hmd5 = hashlib.md5() 42 fp = open(filename,"rb") 43 f_size = os.stat(filename).st_size 44 if f_size>_FILE_SLIM: 45 while(f_size>_FILE_SLIM): 46 hmd5.update(fp.read(_FILE_SLIM)) 47 f_size/=_FILE_SLIM 48 calltimes += 1 #delete 49 if(f_size>0) and (f_size<=_FILE_SLIM): 50 hmd5.update(fp.read()) 51 else: 52 hmd5.update(fp.read()) 53 54 return (hmd5.hexdigest(),calltimes) 55 56 def copyc(path, out): 57 for files in os.listdir(path): 58 name = os.path.join(path, files) 59 back_name = os.path.join(out, files) 60 if os.path.isfile(name): 61 shutil.copy(name, back_name) 62 else: 63 if not os.path.isdir(back_name): 64 os.makedirs(back_name) 65 copyc(name, back_name) 66 67 def copyd(path,out): 68 for files in os.listdir(path): 69 name = os.path.join(path,files) 70 back_name = os.path.join(out,files) 71 if os.path.exists(back_name): 72 pass 73 else: 74 if os.path.isfile(name): 75 shutil.copy(name, back_name) 76 else: 77 if not os.path.isdir(back_name): 78 os.makedirs(back_name) 79 copyd(name, back_name) 80 def buildpackage_unity(unity_bin, rootpath, printpath): 81 ###unity build by command line 82 83 cmd = "%s -batchmode 84 -quit -projectPath 85 %s/UnityClient 86 -executeMethod ProjectBuilder.BuildPlayerForASProject 87 Path=%s" % (unity_bin, rootpath, printpath) 88 89 status = subprocess_return(cmd) 90 return status 91 92 def buildBigPackage(unity_bin,rootpath): 93 94 cmd = "%s -batchmode 95 -quit -projectPath 96 %s/UnityClient 97 -executeMethod ReduceLocalAssetBundleTool.ReduseLocalAssets " % (unity_bin, rootpath) 98 99 status = subprocess_return(cmd) 100 return status 101 102 def buildBigPackageRe(unity_bin,rootpath): 103 104 cmd = "%s -batchmode 105 -quit -projectPath 106 %s/UnityClient 107 -executeMethod ReduceLocalAssetBundleTool.RevertReduseLocalAssets " % (unity_bin, rootpath) 108 109 status = subprocess_return(cmd) 110 return status 111 def showlastline(filepath, num): 112 text = [] 113 f = open(filepath, ‘rb‘) 114 115 lines = f.readlines() 116 count = len(lines) 117 if count > 100: 118 num = 100 119 else: 120 num = count 121 122 for i in range(1, (num+1)): 123 if lines: 124 n = -i 125 lastline = lines[n].strip() 126 text.append(lastline) 127 128 f.close() 129 while text: 130 #print (text.pop()) 131 pass 132 133 def showlog_buildfailed(unitylogfile): 134 print (" build failed!!!! ###Editor.log############################################################################") 135 if os.path.exists(unitylogfile): 136 os.remove(unitylogfile) 137 file = open(unitylogfile,"w") 138 file.close() 139 showlastline(unitylogfile,100) 140 exit(1) 141 pass 142 143 def CheckXcode(): 144 if cur_os == "Darwin" : 145 cmd = "ps -ef|grep Xcode |grep -v grep " 146 status = subprocess.call(cmd,shell = True) 147 if status == 0 : 148 print ("Xcode is running!!") 149 return status 150 151 def CheckiTunes(): 152 if cur_os == "Darwin" : 153 cmd = "ps -ef|grep iTunes |grep -v grep " 154 status = subprocess.call(cmd,shell = True) 155 if status == 0 : 156 print ("iTunes is running!!") 157 return status 158 159 def killXcode(): 160 if cur_os == "Darwin": 161 cmd = "killall -9 Xcode" 162 status = subprocess.call(cmd,shell = True) 163 if status == 0 : 164 print ("no running Xcode") 165 return status 166 167 def killiTunes(): 168 if cur_os == "Darwin": 169 cmd = "killall -9 iTunes" 170 status = subprocess.call(cmd,shell = True) 171 if status == 0 : 172 print ("no running iTunes") 173 return status 174 175 def svn_cleanup(path): 176 cmd = ‘svn cleanup %s‘ %(path) 177 subprocess_call(cmd) 178 179 def svn_up(path): 180 cmd = "svn up %s --non-interactive" %(path) 181 subprocess_call(cmd) 182 183 def svn_add(path): 184 cmd = "svn add %s --force" %(path) 185 subprocess_call(cmd) 186 187 def svn_ci(path,desc): 188 cmd = "svn ci %s -m %s" %(path,desc) 189 subprocess_call(cmd) 190 191 def rw_vconfig_autoincrement(path,autoIncreament): 192 f = open(path,‘r‘) 193 configStr = f.read() 194 versionCodeStr = configStr.split(" ")[0].replace("versionCode=","") 195 versionNameStr = configStr.split(" ")[1].replace("versionName=","") 196 versionCode = int(versionCodeStr) 197 versionName = float(versionNameStr) 198 versionCode_add = versionCode +1 199 versionCodeName_add = round(versionName + 0.1, 1) 200 changedConfigStr = "versionCode=%s versionName=%s" % (versionCode_add, versionCodeName_add) 201 f.close() 202 if autoIncreament == "true": 203 f = open(path, ‘w‘) 204 f.write(changedConfigStr) 205 f.close() 206 return versionCode,versionName 207 208 # def os_popen_show(cmd): 209 # print (cmd) 210 # rs = os.popen(cmd).readlines() 211 # matched = len(rs) 212 # count = 0 213 # while count < matched: 214 # print (rs[count].replace(‘ ‘,‘‘)) 215 # count = count + 1 216 # return matched
2. package.py
1 ### 2 ###python3 3 ###请在该py文件中配置手动配置svnPath变量的值及输出apk上传的本地svn路径,productName及Unity中PlyerSetting中ProductName 4 ###Unity日志输出路径为Unity项目下面Editor.log 5 ### 6 7 import shutil 8 import os 9 import time 10 import math 11 import sys 12 import json 13 import utils 14 import a360syb 15 16 17 print("-----------------starting build package--------------------") 18 time1 = time.time() 19 20 21 print() 22 print() 23 """ 24 第一个参数为Untiy的路径 25 第二个参数为Unity项目的路径 如:E:\\Git\\UnityClient-vn 26 """ 27 28 rootpath = "E:\\Versions\\"+sys.argv[1]+"\\UnityClient" 29 unity_bin = sys.argv[2] 30 auIncreVer = sys.argv[3] 31 packageFlavor = sys.argv[4] 32 bigPackage = sys.argv[5] 33 34 productName = "AU2 Mobile-EN"# 35 showName = "AU2Dance Idol"; 36 svnPath = "D:\\ApkVersions\\SGMY" 37 targetGradle = "E:\\buildApk_New\\SGMY\\SuperIdolMobile\\" 38 targetproject = targetGradle +"app" 39 Unitylogfile = rootpath+"\\Editor.log" 40 asprojectfile = rootpath+"\\UnityClient\\androidstudio" 41 resRelativePath = "\\src\\main\\res" 42 libsRelativePath = "\\libs" 43 soRelativePath = "\\src\\main\\jniLibs" 44 assetsRelativePath = "\\src\\main\\assets" 45 #TODO 46 iconName = "app_icon.png" 47 versionConfig = "E:\\buildApk_New\\SGMY\\sgmyPackge\\versionConfig" 48 49 #unity判断什么的 50 while utils.CheckUnity() == 0: 51 print("Unity进程正在运行") 52 utils.killUnity() 53 time.sleep(2) 54 55 print("------- building as project from Unity--------") 56 print() 57 58 status=0 59 if bigPackage == "false": 60 status = utils.buildBigPackage(unity_bin,rootpath) 61 if status != 0: 62 utils.showlog_buildfailed(Unitylogfile) 63 64 if os.path.exists(asprojectfile): 65 shutil.rmtree(asprojectfile) 66 67 status = utils.buildpackage_unity(unity_bin,rootpath,asprojectfile) 68 if status != 0: 69 utils.showlog_buildfailed(Unitylogfile) 70 if not os.path.exists(asprojectfile): 71 print("未能正确打出As工程") 72 exit(1) 73 print() 74 print("------- build as project finish--------") 75 76 """ 77 创建Unity打出的as工程内部资源和目标资源的路径 78 """ 79 asprojectfile_libs = asprojectfile+"\\"+productName+libsRelativePath 80 targetProjectfile_libs = targetproject+libsRelativePath 81 asprojectfile_res = asprojectfile+"\\"+productName+resRelativePath 82 targetProjectfile_res = targetproject+resRelativePath 83 asprojectfile_assets = asprojectfile+"\\"+productName+assetsRelativePath 84 targetProjectfile_assets = targetproject+assetsRelativePath 85 asprojectfile_so = asprojectfile+"\\"+productName+soRelativePath 86 targetProjectfile_so = targetproject+soRelativePath 87 88 print("---------compareing libs--------------") 89 print() 90 91 92 if bigPackage == "false": 93 status = utils.buildBigPackageRe(unity_bin,rootpath) 94 if status != 0: 95 utils.showlog_buildfailed(Unitylogfile) 96 """ 97 比对Libs文件夹,只比对。如果不匹配就提示 98 """ 99 asLibsDict = {} 100 targetLibsDict = {} 101 for root,dirs,files in os.walk(asprojectfile_libs): 102 for name in dirs: 103 print("AAAAA",os.path.join(root,name)) 104 for name in files: 105 asLibsDict[name] = utils.file_md5(os.path.join(root,name))[0] 106 #print (asLibsDict) 107 108 for root,dirs,files in os.walk(targetProjectfile_libs): 109 for name in dirs: 110 pass 111 # print("A",os.path.join(root,name)) 112 for name in files: 113 targetLibsDict[name] = utils.file_md5(os.path.join(root,name))[0] 114 defalutTip = "NONE" 115 for key,value in asLibsDict.items(): 116 tv = targetLibsDict.get(key,defalutTip) 117 if tv == defalutTip: 118 tv = "在targetLib中没有 " + key + " 文件,如需要请手动配置" 119 print(tv) 120 else : 121 if tv == value: 122 pass 123 else : 124 tv = "在targetLib中 "+key+" 文件与unity打出as工程中文件MD5值不一样,如需要请手动配置" 125 print(tv) 126 127 print() 128 print("---------compare libs finish--------------") 129 130 print("---------compareing icon and appName--------------") 131 print() 132 133 """ 134 res下面的内容,1比对icon,2比对appName 135 """ 136 asIconsDict = {} 137 targetIconsDict = {} 138 for root,dirs,files in os.walk(asprojectfile_res): 139 for name in dirs: 140 pass 141 for name in files: 142 fullpath = os.path.join(root, name) 143 arr = fullpath.split("\\") 144 if iconName == arr[len(arr) - 1]: 145 dirName = arr[len(arr) - 2] 146 dirName = dirName.replace("drawable","mipmap",1) 147 asIconsDict[dirName] = (utils.file_md5(os.path.join(root, name))[0],fullpath) 148 else : 149 pass 150 #print(asIconsDict) 151 #遍历目标文件的res文件 152 for root,dirs,files in os.walk(targetProjectfile_res): 153 for name in dirs: 154 pass 155 #print("A",os.path.join(root,name)) 156 for name in files: 157 fullpath = os.path.join(root, name) 158 arr = fullpath.split("\\") 159 if iconName == arr[len(arr) - 1]: 160 # print(arr[len(arr) - 2]) 161 dirName = arr[len(arr) - 2] 162 targetIconsDict[dirName] = (utils.file_md5(os.path.join(root, name))[0],fullpath) 163 else : 164 pass 165 #print(targetIconsDict) 166 167 #ValueError: too many values to unpack(expected 3) 没有加items() 168 defalutTip = "NONE" 169 for key,value in asIconsDict.items(): 170 ti = targetIconsDict.get(key,defalutTip) 171 # as文件中有一个文件夹,目标工程中没有这个文件夹,提示,并拷贝 172 if ti == defalutTip: 173 aspath = value[1] 174 asarr = aspath.split("\\") 175 folderName = asarr[len(asarr)-2] 176 folderName = folderName.replace("drawable","mipmap",1) 177 # 第一种情况 没有mipmap-?hdp1文件 178 if not os.path.exists(targetProjectfile_res +"\\" +folderName): 179 os.mkdir(targetProjectfile_res +"\\" +folderName) 180 # 第二种情况 mipmap-?hdpi文件中没有改文件 181 print(value[1]) 182 print(targetProjectfile_res +"\\" +folderName+"\\"+asarr[len(asarr)-1]) 183 shutil.copyfile(value[1],targetProjectfile_res +"\\" +folderName+"\\"+asarr[len(asarr)-1] ) 184 print("target文件夹中没有"+value[1]+"已经拷贝") 185 #有的话判断icon的MD5,看是不是同一张图片 186 else : 187 #如果是同一张图片,忽略 188 if value[0] == ti[0]: 189 pass 190 #如果不是同一张图片,提示并覆盖 191 else : 192 shutil.copyfile(value[1], ti[1]) 193 ti = key,"中icon文件与不一致,已替换" 194 print(ti) 195 196 print() 197 print("---------compare icon and appName finish--------------") 198 199 print("----------collating jinLibs and assets file-------------") 200 print() 201 202 """ 203 jniLibs下面的文件 204 """ 205 for root, dirs, files in os.walk(asprojectfile_so): 206 for name in dirs: 207 if not os.path.exists(targetProjectfile_libs+"\\"+name): 208 os.mkdir(targetProjectfile_libs+"\\"+name) 209 for name in files: 210 fullpath = os.path.join(root, name) 211 libarr = fullpath.split("\\") 212 if utils.file_md5(os.path.join(root, name))[0] != utils.file_md5(targetProjectfile_so + "\\" + libarr[len(libarr) - 2] + "\\" + name)[0]: 213 shutil.copyfile(os.path.join(root, name), 214 targetProjectfile_so + "\\" + libarr[len(libarr) - 2] + "\\" + name) 215 216 217 """ 218 assets下面的文件 219 """ 220 ### 221 ###新马assets下面的保护文件 www, plugin_config.xml package_config.json globalizationLang.json 222 ### 223 #如果没有这个文件夹会报错 224 # shutil.rmtree(targetProjectfile_assets) # 递归删除文件夹 225 if not os.path.exists(targetProjectfile_assets): 226 os.makedirs(targetProjectfile_assets) 227 else : 228 for root, dirs, files in os.walk(targetProjectfile_assets): 229 for name in dirs: 230 filePath = os.path.join(root, name) 231 if not name == "www" : 232 if not "\\assets\\www\\" in filePath: 233 dirPath = os.path.join(root, name) 234 shutil.rmtree(dirPath) 235 for name in files: 236 if not name == "plugin_config.xml" and not name == "package_config.json" and not name == "globalizationLang.json": 237 filePath = os.path.join(root, name) 238 if not "\\assets\\www\\" in filePath: 239 os.remove(filePath) 240 241 242 utils.copyd(asprojectfile_assets,targetProjectfile_assets) 243 244 print() 245 print("-----------collate jinLibs and assets file finish--------------") 246 247 248 print("-----------building apk-----------") 249 print() 250 251 """ 252 编译出apk 253 """ 254 #gradlew assembleRelease 255 256 verList = utils.rw_vconfig_autoincrement(versionConfig,auIncreVer) 257 os.chdir(targetGradle) 258 259 if packageFlavor == "googleAll": 260 buildApkCmd = "gradlew assemblegoogle -PversionCode=%s -PversionName=%s" % (verList[0], verList[1]) 261 elif packageFlavor == "googleRelease": 262 buildApkCmd = "gradlew assemblegoogleRelease -PversionCode=%s -PversionName=%s" % (verList[0], verList[1]) 263 elif packageFlavor == "guanwangAll": 264 buildApkCmd = "gradlew assembleguanwang -PversionCode=%s -PversionName=%s" % (verList[0], verList[1]) 265 elif packageFlavor == "guanwangRelease": 266 buildApkCmd = "gradlew assembleguanwangRelease -PversionCode=%s -PversionName=%s" % (verList[0], verList[1]) 267 buildApkCmd = buildApkCmd + " --info" 268 statusEnd = utils.subprocess_return(buildApkCmd) 269 print(statusEnd) 270 if statusEnd != 0: 271 utils.showlog_buildfailed(Unitylogfile) 272 273 print() 274 print("-----------build apk over-----------") 275 276 print("------------begin 360 jiagu--------------") 277 print() 278 279 print() 280 print("------------360 jiagu finish--------------") 281 282 283 284 285 286 # shutil.copyfile(defaltOutputApk,outputName) 287 #加固 288 print("---------360jiagu start------------") 289 ###打出来4个包 290 #|--google 291 #|-----debug 292 #|-----release 293 #|--guanwang 294 #|-----debug 295 #|-----release 296 defaltOutputApk = targetproject+"\\build\\outputs\\apk\\" 297 nowTime = time.strftime("%m-%d_%H-%M", time.localtime()) 298 outputName = svnPath+"\\"+nowTime+"_"+showName 299 300 print() 301 if packageFlavor == "googleAll": 302 apk1 = defaltOutputApk + "google\\debug\\app-google-debug.apk" 303 apk2 = defaltOutputApk + "google\\release\\app-google-release.apk" 304 defaltOutputApk = [apk1,apk2] 305 out1 = (outputName + "google-debug.apk").replace(" ","") 306 out2 = (outputName + "google-release.apk").replace(" ","") 307 outputName = [out1,out2]; 308 elif packageFlavor == "googleRelease": 309 defaltOutputApk = defaltOutputApk + "google\\release\\app-google-release.apk" 310 outputName = (outputName + "google-release.apk").replace(" ", "") 311 elif packageFlavor == "guanwangAll": 312 apk1 = defaltOutputApk + "guanwang\\debug\\app-guanwang-debug.apk" 313 apk2 = defaltOutputApk + "guanwang\\release\\app-guanwang-release.apk" 314 defaltOutputApk = [apk1, apk2] 315 out1 = (outputName + "guanwang-debug.apk").replace(" ", "") 316 out2 = (outputName + "guanwang-release.apk").replace(" ", "") 317 outputName = [out1, out2]; 318 elif packageFlavor == "guanwangRelease": 319 defaltOutputApk = defaltOutputApk + "guanwang\\release\\app-guanwang-release.apk" 320 outputName = (outputName + "guanwang-release.apk").replace(" ", "") 321 322 323 324 print(outputName) 325 326 if not type(defaltOutputApk) is list: 327 a360syb.begin(defaltOutputApk,outputName) 328 else: 329 for i in range(len(defaltOutputApk)) : 330 a360syb.begin(defaltOutputApk[i], outputName[i]) 331 332 333 print() 334 print("---------360jiagu finish------------") 335 336 print("---------copy apk and svn update------------") 337 print() 338 utils.svn_cleanup(svnPath) 339 utils.svn_up(svnPath) 340 if not type(defaltOutputApk) is list: 341 utils.svn_add(outputName) 342 utils.svn_ci(outputName, "buildSuccesAutoUpdate") 343 else: 344 for i in range(len(outputName)) : 345 utils.svn_add(outputName[i]) 346 utils.svn_ci(outputName[i], "buildSuccesAutoUpdate") 347 348 349 print() 350 print("---------copy apk and svn update finish ------------") 351 352 353 time2 = time.time() 354 print() 355 print("共用时" + str(math.ceil(time2 - time1)) + "S") 356 print("-----------------build over--------------------")
3. a360syb.py
1 # -*- coding: utf-8 -*- 2 import os 3 import utils 4 import time 5 import shutil 6 7 _cacheDir = os.path.abspath(".") + "/cache" 8 zipAlignPath = "E:/buildApk_New/SGMY/sgmyPackge/shouyoubao" 9 _keystorePath = "E:/buildApk_New/SGMY/SuperIdolMobile/app/dancehappy.keystore" 10 _keystorePassWord = "dancehappy" 11 _keystoreAlias = "dancehappy" 12 _keystoreAliasPassWord = "dancehappy" 13 14 _360JiaguToolsPath = "E:/buildApk_New/SGMY/sgmyPackge/shouyoubao/jiagu" 15 _360JiaguUserName = "youniu88" 16 _360JiaguPassWord = "Youniu66" 17 18 19 def cleancaches(): 20 if os.path.exists(_cacheDir): 21 shutil.rmtree(_cacheDir) 22 23 def gencache(): 24 exist = os.path.exists(_cacheDir) 25 if not exist: 26 os.makedirs(_cacheDir) 27 28 def signApk(targetFile): 29 os.chdir(zipAlignPath) 30 31 cmdSignApk = "java -jar apksigner.jar -keystore " + _keystorePath + " -alias " + _keystoreAlias + " -pswd " + _keystorePassWord + " -aliaspswd " + _keystoreAliasPassWord + " "+targetFile 32 return utils.subprocess_return(cmdSignApk) 33 34 35 def zipAlignAndCopy(targetFile,copyToFile): 36 os.chdir(zipAlignPath) 37 cmdZipAlign ="zipalign -v 4 "+targetFile +" "+ copyToFile 38 return utils.subprocess_return(cmdZipAlign) 39 40 def start(_360JiaguApkPath,_outputApkPath): 41 42 # _360JiaguApkPath = "D:/Work/program/client_version/CN/20181115渠道/bilibili.apk" 43 # _outputApkPath = "C:/Users/96952/Desktop/aaa.apk" 44 45 _thereMinute = 3 * 60 46 cmdLogin = "java -jar jiagu.jar -login " + _360JiaguUserName + " " + _360JiaguPassWord 47 cmdCheckConfig = "java -jar jiagu.jar -showconfig" 48 cmdImportSign = "java -jar jiagu.jar -importsign " + _keystorePath + " " + _keystorePassWord + " " + _keystoreAlias + " " + _keystoreAliasPassWord 49 cmdSign = "java -jar jiagu.jar -jiagu " + _360JiaguApkPath + " " + _cacheDir 50 51 os.chdir(_360JiaguToolsPath) 52 53 cmdLoginCall = os.popen(cmdLogin) 54 cmdLoginCallInfo = cmdLoginCall.readlines() 55 tipLine =cmdLoginCallInfo[len(cmdLoginCallInfo)-1].strip() 56 57 if tipLine != "login success": 58 print("登录360手游保失败") 59 exit(1) 60 61 utils.subprocess_return(cmdCheckConfig) 62 # cmdImportSignCall = os.popen(cmdImportSign) 63 # cmdImportSignCallInfo = cmdImportSignCall.readlines() 64 # if "save sign success" not in cmdImportSignCallInfo: 65 # canAutoSign = False 66 # if canAutoSign: 67 # cmdSign = cmdSign +" -autosign" 68 result = os.system(cmdSign) 69 if not result: 70 print("------------加固成功-------------") 71 for file in os.listdir(_cacheDir): 72 if os.path.splitext(file)[1] == ".apk": 73 if file.endswith("jiagu.apk") or file.endswith("jiagu_sign.apk"): 74 if time.time()-os.path.getmtime(_cacheDir+"/"+file) < _thereMinute: 75 #这就是我刚打出来的包 76 #step 1 签名 77 if signApk(_cacheDir+"/"+file) != 0: 78 print(_cacheDir+"/"+file +" 签名失败") 79 exit(1) 80 else: 81 print(_cacheDir+"/"+file + " 签名成功") 82 # step 2 align 83 # step3 拷贝到指定位置 84 if zipAlignAndCopy(_cacheDir+"/"+file, _outputApkPath) != 0: 85 print("对齐失败") 86 exit(1) 87 88 def begin(targetFile,outputFile): 89 cleancaches() 90 gencache() 91 start(targetFile,outputFile) 92 93 94 # begin()
转载请注明出处:
https://www.cnblogs.com/jietian331/p/12842006.html
以上是关于unity之Jenkins自动化出包shell脚本的主要内容,如果未能解决你的问题,请参考以下文章