| 
 | 1 | +# iOS项目自动打包、上传到蒲公英、发送消息到企业微信  | 
 | 2 | + | 
 | 3 | +# author: xixi  | 
 | 4 | + | 
 | 5 | +# 赋予权限  | 
 | 6 | +# chmod 777 upload.sh   | 
 | 7 | + | 
 | 8 | +# ps:脚本需要放在项目根目录, 同时需要 ExportOptions.plist 也放在项目根目录  | 
 | 9 | +# 1、如果只需要导出ipa则只需要设置 PROJECT_TYPE 的值, 其它值不需要填写  | 
 | 10 | +# 2、如果TARGET_NAME 和 Display_Name 不一样则需要手动设置Display_Name, 如果是一样则忽略 Display_Name  | 
 | 11 | +# 3、如果你不需要提交到蒲公英 就将 UPLOADPGYER=flase 和 pgyerApiKey=""  | 
 | 12 | +# 4、如果需要添加蒲公英更新说明则在 脚本后面 添加 举个栗子: ./upload.sh 我是版本更新内容  | 
 | 13 | +# 5、导出的ipa 在你的桌面,上传完蒲公英会自动删除【如果不想删除,可以更变属性IS_Delete_IPA=false】  | 
 | 14 | + | 
 | 15 | +# 选择项目 xcodeproj or xcworkspace 这里是二选一   | 
 | 16 | +PROJECT_TYPE="xcworkspace"  | 
 | 17 | + | 
 | 18 | +# 是否需要上传到蒲公英  | 
 | 19 | +UPLOADPGYER=true  | 
 | 20 | + | 
 | 21 | +# 蒲公英的key  | 
 | 22 | +PgyerApiKey=""  | 
 | 23 | + | 
 | 24 | +#Display_NAME  | 
 | 25 | +DISPLAY_NAME="AAAA"  | 
 | 26 | + | 
 | 27 | +# 打包环境 Release / Debug  | 
 | 28 | +CONFIGURATION=Release  | 
 | 29 | + | 
 | 30 | +# 项目target名字  | 
 | 31 | +TARGET_NAME="AAAA"  | 
 | 32 | + | 
 | 33 | +#企业微信机器人key  | 
 | 34 | +BOT_KEY=  | 
 | 35 | + | 
 | 36 | +#是否需要删除编译打包遗留下来的IPA  | 
 | 37 | +IS_Delete_IPA=true  | 
 | 38 | + | 
 | 39 | +# 是否显示日志 1=enable, 0=disable  | 
 | 40 | +LOG_ENABLE=1  | 
 | 41 | + | 
 | 42 | +# ---------------------------------------------------------------  | 
 | 43 | +# function   | 
 | 44 | +# ---------------------------------------------------------------  | 
 | 45 | + | 
 | 46 | + # check api_key exists  | 
 | 47 | +if [ -z "$PgyerApiKey" ]; then  | 
 | 48 | + echo "PgyerApiKey is empty"  | 
 | 49 | + echo "PgyerApiKey is empty"  | 
 | 50 | + echo "PgyerApiKey is empty"  | 
 | 51 | + exit 1  | 
 | 52 | +fi  | 
 | 53 | + | 
 | 54 | + | 
 | 55 | +log() {  | 
 | 56 | + [ $LOG_ENABLE -eq 1 ] && echo "[$(date +'%Y-%m-%d %H:%M:%S')] $*"  | 
 | 57 | +}  | 
 | 58 | + | 
 | 59 | +logTitle() {  | 
 | 60 | + log "-------------------------------- $* --------------------------------"  | 
 | 61 | +}  | 
 | 62 | + | 
 | 63 | +execCommand() {  | 
 | 64 | + log "$@"  | 
 | 65 | + result=$(eval $@)  | 
 | 66 | +}  | 
 | 67 | + | 
 | 68 | +sendMsg() {  | 
 | 69 | + content="$@"  | 
 | 70 | + logTitle $content  | 
 | 71 | + sendPostURL="curl --location --request POST 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=${BOT_KEY}' --header 'Content-Type: application/json;charset=utf-8' --data-raw '{\"msgtype\": \"text\",\"text\": {\"content\":\"${content}\"}}'"  | 
 | 72 | + logTitle sendPostURL  | 
 | 73 | + execCommand $sendPostURL  | 
 | 74 | +}  | 
 | 75 | + | 
 | 76 | +# --------------我是分割线-------------------  | 
 | 77 | +# --------------我是分割线-------------------  | 
 | 78 | +# --------------我是分割线-------------------  | 
 | 79 | +# --------------我是分割线-------------------  | 
 | 80 | + | 
 | 81 | +logTitle '开始打包'  | 
 | 82 | + | 
 | 83 | + | 
 | 84 | +# # 项目的根目录路径  | 
 | 85 | +PROJECT_PATH="$( cd "$( dirname "$0" )" && pwd )";  | 
 | 86 | + | 
 | 87 | +gitBranchName=$(echo `git branch --show-current`)  | 
 | 88 | +echo '当前打包分支:' $gitBranchName  | 
 | 89 | +gitBranchName="qa"  | 
 | 90 | + | 
 | 91 | +function getFileName(){  | 
 | 92 | + | 
 | 93 | + for file in $(ls $PROJECT_PATH)  | 
 | 94 | + do  | 
 | 95 | + local lastFileName=${file##*.}  | 
 | 96 | + if [[ $lastFileName =~ $PROJECT_TYPE ]]  | 
 | 97 | + then  | 
 | 98 | + TARGET_NAME=$(basename ${file} .$PROJECT_TYPE)  | 
 | 99 | + fi  | 
 | 100 | + done  | 
 | 101 | +}  | 
 | 102 | +getFileName  | 
 | 103 | + | 
 | 104 | +# 判断是否获取到当前目录含有 xcode的项目文件  | 
 | 105 | +if [[ "${#TARGET_NAME}" -eq 0 ]]; then  | 
 | 106 | + echo "没有获取到项目名称"  | 
 | 107 | + exit;  | 
 | 108 | +fi  | 
 | 109 | + | 
 | 110 | + | 
 | 111 | + | 
 | 112 | +# 工程文件路径  | 
 | 113 | +APP_PATH="${PROJECT_PATH}/${TARGET_NAME}.$PROJECT_TYPE"  | 
 | 114 | + | 
 | 115 | +# Xcode clean  | 
 | 116 | +xcodebuild clean -workspace "${APP_PATH}" -configuration "${CONFIGURATION}" -scheme "${TARGET_NAME}"  | 
 | 117 | + | 
 | 118 | +# 打包目录  | 
 | 119 | +HOME_PATH=$(echo ${HOME})  | 
 | 120 | +DESKTOP_PATH="${HOME_PATH}/Desktop"  | 
 | 121 | + | 
 | 122 | +# 时间戳  | 
 | 123 | +CURRENT_TIME=$(date "+%Y-%m-%d %H-%M-%S")  | 
 | 124 | + | 
 | 125 | +# 归档路径  | 
 | 126 | +ARCHIVE_PATH="${DESKTOP_PATH}/${TARGET_NAME} ${CURRENT_TIME}/${TARGET_NAME}.xcarchive"  | 
 | 127 | + | 
 | 128 | +# 导出路径  | 
 | 129 | +EXPORT_PATH="${DESKTOP_PATH}/${TARGET_NAME} ${CURRENT_TIME}"  | 
 | 130 | + | 
 | 131 | +# plist路径  | 
 | 132 | +PLIST_PATH="${PROJECT_PATH}/ExportOptions.plist"  | 
 | 133 | + | 
 | 134 | +# archive 这边使用的工作区间 也可以使用project  | 
 | 135 | +xcodebuild archive -workspace "${APP_PATH}" -scheme "${TARGET_NAME}" -configuration "${CONFIGURATION}" -archivePath "${ARCHIVE_PATH}"   | 
 | 136 | + | 
 | 137 | +# 导出ipa  | 
 | 138 | +xcodebuild -exportArchive -archivePath "${ARCHIVE_PATH}" -exportPath "${EXPORT_PATH}" -exportOptionsPlist "${PLIST_PATH}"  | 
 | 139 | + | 
 | 140 | + | 
 | 141 | +logTitle '打包完成'  | 
 | 142 | + | 
 | 143 | +# 上传到蒲公英  | 
 | 144 | +if [ $UPLOADPGYER = true ]; then  | 
 | 145 | + # 获取第一个参数  | 
 | 146 | + varBuildUpdateDescription=$1  | 
 | 147 | +   | 
 | 148 | +   | 
 | 149 | + #如果有设置DISPLAY_NAME怎取DISPLAY_NAME ,否则默认取TARGET_NAME  | 
 | 150 | + IPAPATH=""  | 
 | 151 | + if [ -n "$DISPLAY_NAME" ]   | 
 | 152 | + then  | 
 | 153 | + IPAPATH="${EXPORT_PATH}/${DISPLAY_NAME}.ipa"  | 
 | 154 | + else  | 
 | 155 | + IPAPATH="${EXPORT_PATH}/${TARGET_NAME}.ipa"  | 
 | 156 | + fi  | 
 | 157 | + echo $IPAPATH  | 
 | 158 | + | 
 | 159 | + logTitle $IPAPATH  | 
 | 160 | + # 上传蒲公英   | 
 | 161 | + logTitle "~~~~~~~~~~~~~~~~开始上传ipa到蒲公英~~~~~~~~~~~~~~~~~~~"  | 
 | 162 | + | 
 | 163 | + execCommand "curl -s -F '_api_key=${PgyerApiKey}' -F 'buildUpdateDescription=${varBuildUpdateDescription}' -F 'buildType=ios' http://www.pgyer.com/apiv2/app/getCOSToken"  | 
 | 164 | + | 
 | 165 | + [[ "${result}" =~ \"endpoint\":\"([\:\_\.\/\\A-Za-z0-9\-]+)\" ]] && endpoint=`echo ${BASH_REMATCH[1]} | sed 's!\\\/!/!g'`  | 
 | 166 | + [[ "${result}" =~ \"key\":\"([\.a-z0-9]+)\" ]] && key=`echo ${BASH_REMATCH[1]}`  | 
 | 167 | + [[ "${result}" =~ \"signature\":\"([\=\&\_\;A-Za-z0-9\-]+)\" ]] && signature=`echo ${BASH_REMATCH[1]}`  | 
 | 168 | + [[ "${result}" =~ \"x-cos-security-token\":\"([\_A-Za-z0-9\-]+)\" ]] && x_cos_security_token=`echo ${BASH_REMATCH[1]}`  | 
 | 169 | + | 
 | 170 | + if [ -z "$key" ] || [ -z "$signature" ] || [ -z "$x_cos_security_token" ] || [ -z "$endpoint" ]; then  | 
 | 171 | + log "get upload token failed"  | 
 | 172 | + exit 1  | 
 | 173 | + fi  | 
 | 174 | + | 
 | 175 | + logTitle "开始上传文件"  | 
 | 176 | + | 
 | 177 | + execCommand "curl --connect-timeout 60 -m 60 -D - --form-string 'key=${key}' --form-string 'signature=${signature}' --form-string 'x-cos-security-token=${x_cos_security_token}' -F 'file=@${IPAPATH}' ${endpoint}"  | 
 | 178 | + | 
 | 179 | + # 如果上传成功:返回 http 状态码为 204 No Content; 如果上传失败:返回相应错误信息说明  | 
 | 180 | + logTitle "上传结果:" "$result"  | 
 | 181 | + if [[ $result -ne 204 ]]; then  | 
 | 182 | + logTitle "上传失败 Upload failed"  | 
 | 183 | + exit 1  | 
 | 184 | + fi  | 
 | 185 | + | 
 | 186 | + logTitle "上传成功"  | 
 | 187 | + | 
 | 188 | + | 
 | 189 | + | 
 | 190 | + # ---------------------------------------------------------------  | 
 | 191 | + # 检查结果  | 
 | 192 | + # ---------------------------------------------------------------  | 
 | 193 | + | 
 | 194 | + logTitle "开始 检查结果"  | 
 | 195 | + | 
 | 196 | + isSuccessGetBuildInfo=false  | 
 | 197 | + | 
 | 198 | + for i in {1..60}; do  | 
 | 199 | + logTitle "第${i}次查询"  | 
 | 200 | + execCommand "curl -s http://www.pgyer.com/apiv2/app/buildInfo?_api_key=${PgyerApiKey}\&buildKey=${key}"  | 
 | 201 | + logTitle $result  | 
 | 202 | + | 
 | 203 | + [[ "${result}" =~ \"code\":([0-9]+) ]] && code=`echo ${BASH_REMATCH[1]}`  | 
 | 204 | + if [ $code -eq 0 ]; then  | 
 | 205 | + isSuccessGetBuildInfo=true  | 
 | 206 | + logTitle $newResult  | 
 | 207 | + | 
 | 208 | + [[ "$result" =~ \"buildQRCodeURL\":\"([\:\_\.\/\\A-Za-z0-9\-]+)\" ]] && buildQRCodeURL=`echo ${BASH_REMATCH[1]} | sed 's!\\\/!/!g'`  | 
 | 209 | + [[ "$result" =~ \buildCreated\":\"(([0-9]{4}-[0-9]{2}-[0-9]{2}) [0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])\" ]] && buildCreated=`echo ${BASH_REMATCH[1]} | sed 's!\\\/!/!g'`  | 
 | 210 | +
  | 
 | 211 | + logTitle $buildQRCodeURL  | 
 | 212 | + logTitle $buildCreated  | 
 | 213 | + logTitle $varBuildUpdateDescription  | 
 | 214 | + content="上传时间: ${buildCreated} \n 二维码:${buildQRCodeURL} \n 更新内容:${varBuildUpdateDescription} \n 当前打包git分支:${gitBranchName}"  | 
 | 215 | +
  | 
 | 216 | + echo $content  | 
 | 217 | + logTitle '开始给企业微信发送消息'  | 
 | 218 | +   | 
 | 219 | + sendMsg $content   | 
 | 220 | + logTitle $result  | 
 | 221 | +   | 
 | 222 | +   | 
 | 223 | + echo $result  | 
 | 224 | + logTitle $result  | 
 | 225 | + sendResult=$(echo $result)  | 
 | 226 | + if [[ $sendResult =~ "ok" ]]; then  | 
 | 227 | + logTitle "~~~~~~~~~~~~~~~~🎆🎆🎆🎆发送到企业微信成功~~~~~~~~~~~~~~~~~~~"  | 
 | 228 | +
  | 
 | 229 | + if [ $IS_Delete_IPA = true ]; then  | 
 | 230 | + logTitle "删除导出的文件夹 - 开始"  | 
 | 231 | + logTitle "$EXPORT_PATH"  | 
 | 232 | + rm -rf "$EXPORT_PATH"  | 
 | 233 | + logTitle "删除导出的文件夹 - 结束"  | 
 | 234 | + fi  | 
 | 235 | + else   | 
 | 236 | + logTitle "~~~~~~~~~~~~~~~~⚠️⚠️⚠️⚠️发送到企业微信 失败失败 ~~~~~~~~~~~~~~~~~~~"  | 
 | 237 | + fi  | 
 | 238 | +
  | 
 | 239 | + break  | 
 | 240 | + else  | 
 | 241 | + sleep 1  | 
 | 242 | + fi  | 
 | 243 | + done  | 
 | 244 | +
  | 
 | 245 | + if [ $isSuccessGetBuildInfo = false ]; then  | 
 | 246 | + sendMsg "1分钟了,也没查到新上传的ipa相关发布信息 后续请查看 【括号里面这里填写你的蒲公英短链】 \n 描述内容是:${varBuildUpdateDescription}"  | 
 | 247 | + fi  | 
 | 248 | +
  | 
 | 249 | +fi  | 
 | 250 | +
  | 
 | 251 | +
  | 
 | 252 | +
  | 
 | 253 | +
  | 
0 commit comments