bulid.sh文件
#!/bin/zsh
echo "Begin build.sh script"
path=`pwd`
branch=$1
type=$2
build=$3
echo ">>> path=${path} branch=${branch} type=${type} build=${build}"
handle_branch() {
remote_branch="${branch}"
remote_branch=$(echo "${remote_branch}" | awk -F'/' '{print $NF}')
echo "远程分支:${remote_branch}"
git checkout .
git fetch
git branch -a --no-pager
echo "列出分支"
git checkout "${remote_branch}"
echo "切换分支完成"
git pull
echo "拉取完成"
flutter doctor
flutter pub get
}
pullcode() {
REPO_NATIVE_BRIDGE_URL="git@gitcode.deepway-inc.com:base-infrastructure/basic-client/flutter/dw_flutter_native_bridge.git"
REPO_MODULE_URL="git@gitcode.deepway-inc.com:base-infrastructure/basic-client/flutter/dw_flutter_module.git"
BRANCH_NAME="main"
LOCAL_NATIVE_BRIDGE_REPO_PATH="../dw_flutter_native_bridge"
LOCAL_MODULE_REPO_PATH="../dw_flutter_module"
if [ -d "$LOCAL_NATIVE_BRIDGE_REPO_PATH" ]; then
cd $LOCAL_NATIVE_BRIDGE_REPO_PATH
git pull origin $BRANCH_NAME
cd $path
else
git clone -b $BRANCH_NAME $REPO_NATIVE_BRIDGE_URL $LOCAL_NATIVE_BRIDGE_REPO_PATH
fi
if [ -d "$LOCAL_MODULE_REPO_PATH" ]; then
cd $LOCAL_MODULE_REPO_PATH
git pull origin $BRANCH_NAME
cd $path
else
git clone -b $BRANCH_NAME $REPO_MODULE_URL $LOCAL_MODULE_REPO_PATH
fi
echo "拉取完成"
}
pullcode
handle_branch "${branch}"
echo ">>>>>>>> 开始调用 upload.py 打包"
python3 upload.py -t ${type} -u ${type} -b ${build}
echo "End build.sh script"
upload.py文件:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import requests
import os
import getopt
import sys
from enum import Enum
from requests_toolbelt.multipart import encoder
# 检查第三方包是否安装
def check_requirement(package):
try:
exec("import {0}".format(package))
except ModuleNotFoundError:
inquiry = input("This script requires {0}. Do you want to install {0}? [y/n]".format(package))
while (inquiry != "y") and (inquiry != "n") and (inquiry != "N") and (inquiry != "Y") :
inquiry = input("This script requires {0}. Do you want to install {0}? [y/n]".format(package))
if inquiry == "y" or inquiry == "Y":
import os
print("Execute commands: pip install {0}".format(package))
if int(sys.version.split('.')[0])==2:
os.system("pip install {0}".format(package))
elif int(sys.version.split('.')[0])==3:
os.system("pip3 install {0}".format(package))
else:
print("{0} is missing, so the program exits!".format(package))
exit(-1)
# 编译类型 #注:只需要用默认release就行
class BuildMode(Enum):
all=0
debug = 1
release =2
@staticmethod
def load(value):
if value == 0:
return BuildMode.all
elif value == 1:
return BuildMode.debug
elif value ==2:
return BuildMode.release
# 上传类型
class UploadMode(Enum):
all = 0
apk = 1
ipa = 2
@staticmethod
def load(value):
if value == 0:
return UploadMode.all
elif value == 1:
return UploadMode.apk
elif value ==2:
return UploadMode.ipa
# 编译类别 安卓还是ios
class BuildType(Enum):
all = 0
apk = 1
ipa = 2
@staticmethod
def load(value):
if value == 1:
return BuildType.apk
elif value == 2:
return BuildType.ipa
elif value ==0:
return BuildType.all
class Runner:
buildMode = BuildMode.release
uploadMode = None
buildType = None
fileLength=1
currentPath=''
def main(self,argv):
try:
ops,args = getopt.getopt(argv,'-h-b:-u:-t:',['help','build=','upload=','type='])
except getopt.GetoptError:
sys.exit()
count = 0
for op,value in ops:
if op in ('-h','--help'):
count +=1
self.pHelp()
return
elif op in ('-u', '--upload'):
count += 1
if ['all','apk','ipa'].__contains__(value) ==False:
self.pHelp()
else:
self.uploadMode=UploadMode(['all','apk','ipa'].index(value))
elif op in('-b','--build'):
count += 1
# self.p('-b:{0}'.format(value))
if ['all','debug','release'].__contains__(value)==False:
self.pHelp()
else:
self.buildMode=BuildMode.load(['all','debug','release'].index(value))
elif op in('-t','--type'):
count += 1
# self.p('-t:{0}'.format(value))
if ['all','apk','ipa'].__contains__(value)==False:
self.pHelp()
else:
self.buildType=BuildType.load(['all','apk','ipa'].index(value))
if count ==0:
self.pHelp()
return
else:
if not self.buildType:
self.p('\n 请输入 -b buildType 参数 \n')
self.pHelp()
return
if not self.uploadMode:
self.p('\n 请输入 -u uploadMode 参数 \n')
self.pHelp()
return
self.p('{0}{1}{2}'.format(self.buildMode, self.buildType,self.uploadMode))
# 开始编译和上传ipa
self.currentPath = os.getcwd()
self.build()
self.upload()
def p(self,str):
# 结束标示: \n\033[0m
print('\033[0;35;48m '+str+'')
def pHelp(self):
self.p('-h --help 获取帮助信息')
self.p('-b --build 编译模式[release(default),debug,all]注:只需要用默认release就行')
self.p('-u --upload 上传模式[apk,ipa]')
self.p('-t --type 编译种类[all,apk,ipa]')
def buildAPK(self):
try:
if self.buildMode==BuildMode.release :
os.system('flutter --no-color build apk --flavor env_release -t lib/main_env_release.dart'),
if self.buildMode==BuildMode.debug :
os.system('flutter --no-color build apk --flavor env_debug -t lib/main_env_debug.dart'),
except KeyError as e:
print(e)
def buildIPA(self,):
try:
if self.buildMode==BuildMode.release:
os.system('source ~/.bash_profile'),
os.system('flutter --no-color build ios --flavor env_release -t lib/main_env_release.dart'),
os.chdir(self.currentPath+'/ios')
plus='agvtool next-version -all'
arch = 'xcodebuild -workspace Runner.xcworkspace -scheme Runner archive -archivePath ./build/Runner.xcarchive'
export = 'xcodebuild -exportArchive -archivePath $PWD/build/Runner.xcarchive -exportOptionsPlist "./exportOptions.plist" -exportPath ./build/'
os.system(arch)
os.system(plus)
os.system(export)
elif self.buildMode==BuildMode.debug:
os.system('source ~/.bash_profile'),
os.system('flutter --no-color build ios --flavor env_debug -t lib/main_env_debug.dart'),
os.chdir(self.currentPath+'/ios')
plus='agvtool next-version -all'
arch = 'xcodebuild -workspace Runner.xcworkspace -scheme Runner archive -archivePath ./build/Runner.xcarchive'
export = 'xcodebuild -exportArchive -archivePath $PWD/build/Runner.xcarchive -exportOptionsPlist "./exportOptions.plist" -exportPath ./build/'
os.system(arch)
os.system(plus)
os.system(export)
except KeyError as e:
print(e)
# 编译函数
def build(self,):
if self.buildType==BuildType.apk:
self.buildAPK()
elif self.buildType==BuildType.ipa:
self.buildIPA()
elif self.buildType==BuildType.all:
self.buildAPK()
self.buildIPA()
def uploadFile(self,filePath,name='DeepWay服务.ipa'):
self.p(' 开始上传' + filePath)
url = 'https://www.pgyer.com/apiv2/app/upload'
file = open(filePath, 'rb')
e = encoder.MultipartEncoder(
fields={
'_api_key': '3f74f8fe3044845cebbd76964dd204a3',
'file': (name,file,'application/x-www-form-urlencoded'),
},
)
m = encoder.MultipartEncoderMonitor(e, self.my_callback)
h = {'Content-Type': m.content_type,"enctype":"multipart/form-data"}
self.fileLength = os.path.getsize(filePath)
r = requests.post(url, data=m,headers=h).json()
if int(dict(r).get('code')) != 0:
raise Exception('上传失败:{0}'.format(dict(r).get('message')), )
else:
self.p(str(r).replace('u\'','\''))# 去掉前边的u
self.p(filePath + '上传成功')
def my_callback(self,monitor):
total = 50
pro =int((monitor.bytes_read *1.0)/self.fileLength * 1.0 * total)
unit = 1000 * 1000.0
sys.stdout.write(
'\r' + str(pro * '\033[46;34m \033[0m') + str((total - pro) * '\033[40;30m \033[0m') + '[{0}M/{1}M]'.format( round(monitor.bytes_read/unit,2),round(self.fileLength/unit,2)))
sys.stdout.flush()
# 上传函数
def upload(self,):
currentPath=self.currentPath
if self.uploadMode== UploadMode.apk or self.uploadMode==UploadMode.all:
if self.buildMode==BuildMode.debug or self.buildMode==BuildMode.all:
filePath=currentPath+'/build/app/outputs/apk/env_debug/release/app-env_debug-release.apk'
try:
self.uploadFile(filePath, name='app-env_debug-release.apk')
except Exception as e:
self.p(e.__str__())
exit()
if self.buildMode==BuildMode.release or self.buildMode==BuildMode.all:
filePath = currentPath+'/build/app/outputs/apk/env_release/release/app-env_release-release.apk'
try:
self.uploadFile(filePath, name='app-env_release-release.apk')
except Exception as e:
self.p(e.__str__())
exit()
if self.uploadMode==UploadMode.ipa or self.uploadMode==UploadMode.all:
file = self.currentPath+'/ios/build/DeepWay服务.ipa'
if os.path.isdir(file) or os.path.isfile(file):
self.uploadFile(file,name='DeepWay服务.ipa')
source_file = os.path.join(self.currentPath, 'ios', 'build', 'DeepWay服务.ipa')
destination_file = os.path.join(self.currentPath, 'ios', 'output', 'DeepWay服务.ipa')
source_save_file = os.path.join(self.currentPath, 'ios', 'build/')
os.system(f'mv {source_file} {destination_file}') # 移动ipa
os.system(f'rm -rf {source_save_file}')# 删除 build文件夹
else:
self.p('没有发现ipa文件:'+file)
if __name__ == '__main__':
libs = ['requests','requests_toolbelt']
for i in libs:
check_requirement(i) # 检查是否安装该安装包
Runner().main(sys.argv[1:])
jenkins中shell脚本配置
#!/bin/bash
export LANG=en_US.UTF-8
pwd
path=`pwd`
echo "path=${path}"
export PATH=/Users/deepway/flutter/bin:$PATH
sh build.sh ${branch} ${type} ${build}
本地可执行
python3 upload.py -t ipa -u ipa -b debug
python3 upload.py -t apk -u apk -b debug
sh build.sh origin/main ipa debug
配置多环境参考 juejin.cn/post/705003…