CICD—Jenkins Gitlab 远端MAC自动化打包IOS—IPA上传至蒲公英&AppStore
CICD—Jenkins Gitlab 远端MAC自动化打包IOS-IPA
温馨提示:环境搭建:Jenkins、gitlab、两者之间打通;钉钉机器人创建都已省略自己问度娘文章很多(整个打包过程全自动,开发人员只需要提交代码就可以自动构建)。
【注意:远程目录权限、登录用户权限、xcodebuild 证书配置】
#通过jenkins打包ipa包报错 给Jenkins一个用户身份。 xcodebuild archive 步骤前添加一步解锁钥匙串
security unlock-keychain -p "你的登录_PASSWD" ~/Library/Keychains/login.keychain
流水线



第三步、pipeline脚本编写:deploy/Jenkinsfile-app
#!groovy
pipeline {
//代理
agent {
label 'mac'
}
//环境变量
environment {
REPOSITORY="git@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.git" //git地址
PROJECT_NAME = "app-xxxx-ios" //服务名
BRANCH_DEV= "xxxx" //开发分支名
BRANCH_TEST = "xxxx" //测试分支
BRANCH_PRE = "xxxx" //演示分支
BRANCH_PROD = "master" //生产分支
JENKINSURL = "http://xxxxxxxxxxxxxxxxxxxxxx/jenkins/job/" //jenkins任务回调地址
BRANCH_NAME = "${params.gitbranch}" //判断变量
SCRIPT_PATH="${WORKSPACE}/deploy/" //依赖包存放地址
}
//参数化构建
parameters {
gitParameter branch: '',
branchFilter: 'origin/(.*)',
defaultValue: 'CICDXXXX',
description: '请选择git分支',
name: 'gitbranch',
quickFilterEnabled: false,
selectedValue: 'NONE',
sortMode: 'DESCENDING_SMART',
tagFilter: '*',
type: 'PT_BRANCH',
useRepository: 'git@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.git'
}
stages {
stage('拉取代码') {
parallel {
//手动构建
stage('手动构建') {
when {
not{
environment name: 'BRANCH_NAME', value: 'CICDXXXX'
}
}
environment {
BRANCH_NAME = "${params.gitbranch}" //项目的命名空间
}
steps {
echo "从代码仓库${REPOSITORY}拉取代码,分支是:${BRANCH_NAME}"
deleteDir()
checkout([$class: 'GitSCM',
branches: [[name: "${BRANCH_NAME}"]],
extensions: [],
userRemoteConfigs: [[credentialsId: '1b9ca2d6-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', url: "${REPOSITORY}"]]
])
}
}
//自动构建
stage('自动构建') {
when {
environment name: 'BRANCH_NAME', value: 'CICDXXXX'
}
environment {
BRANCH_NAME = "${gitlabBranch}" //项目的命名空间
}
steps {
echo "从代码仓库${REPOSITORY}拉取代码,分支是:${BRANCH_NAME}"
deleteDir()
checkout([$class: 'GitSCM',
branches: [[name: "${BRANCH_NAME}"]],
extensions: [],
userRemoteConfigs: [[credentialsId: '1b9ca2d6-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', url: "${REPOSITORY}"]]
])
}
}
}
}
stage('编译&导出XCARCHIVE和IPA') {
steps {
sh '''
sh ${WORKSPACE}/deploy/gradle_xxxx_ios.sh
'''
echo "编译&导出IPA成功"
}
}
stage('将IPA推送至蒲公英') {
parallel {
//手动
stage('手动打包-将IPA推送至蒲公英') {
when {
not{
environment name: 'BRANCH_NAME', value: 'CICDXXXX'
}
}
environment {
BRANCH_NAME = "${params.gitbranch}" //项目的命名空间
}
steps{
script {
sh '''
python3 ${WORKSPACE}/deploy/apk.py
'''
echo "IPA推送至蒲公英成功"
}
}
post {
success {
dingtalk (
robot:'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
type:'MARKDOWN',
title: '本次构建成功,详情请点此次!!!',
text: ["- ${PROJECT_NAME}项目构建成功!!!\n- 构建分支为: ${BRANCH_NAME}\n- 持续时间:${currentBuild.durationString}\n- 任务:${BUILD_ID}\n- 下载APP:请扫码!!!\n- \n "],
messageUrl:'${JENKINSURL}${JOB_NAME}/${BUILD_NUMBER}/console',
picUrl:'http://kmzsccfile.kmzscc.com/upload/2020/success.jpg'
)
}
failure {
dingtalk (
robot:'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
type:'LINK',
title: '本次构建失败,详情请点此次!!!',
text: ["- ${PROJECT_NAME}项目构建失败!!!\n- 构建分支为:${BRANCH_NAME}\n- 持续时间:${currentBuild.durationString}\n- 任务:${BUILD_ID}"],
messageUrl:'${JENKINSURL}${JOB_NAME}/${BUILD_NUMBER}/console',
picUrl:'http://kmzsccfile.kmzscc.com/upload/2020/error.jpg',
)
}
}
}
//自动部署应用
stage('自动打包-将IPA推送至蒲公英') {
when {
environment name: 'BRANCH_NAME', value: 'CICDXXXX'
}
environment {
BRANCH_NAME = "${gitlabBranch}" //项目的命名空间
}
steps{
script {
sh '''
python3 ${WORKSPACE}/deploy/apk.py
'''
echo "IPA推送至蒲公英成功"
}
}
post {
success {
dingtalk (
robot:'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
//type:'LINK',
type:'MARKDOWN',
title: '本次构建成功,详情请点此次!!!',
text: ["- ${PROJECT_NAME}项目构建成功!!!\n- 构建分支为: ${BRANCH_NAME}\n- 持续时间:${currentBuild.durationString}\n- 任务:${BUILD_ID}\n- 下载APP:请扫码!!!\n- \n "],
messageUrl:'${JENKINSURL}${JOB_NAME}/${BUILD_NUMBER}/console',
picUrl:'http://kmzsccfile.kmzscc.com/upload/2020/success.jpg'
)
}
failure {
dingtalk (
robot:'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
type:'LINK',
title: '本次构建失败,详情请点此次!!!',
text: ["- ${PROJECT_NAME}项目构建失败!!!\n- 构建分支为:${gitlabBranch}\n- 持续时间:${currentBuild.durationString}\n- 任务:${BUILD_ID}"],
messageUrl:'${JENKINSURL}${JOB_NAME}/${BUILD_NUMBER}/console',
picUrl:'http://kmzsccfile.kmzscc.com/upload/2020/error.jpg',
)
}
}
}
}
}
}
## !/bin/sh
##########################环境变量###############################
## 项目名
APP_NAME="app-xxxx-ios"
## Scheme名
SCHEME="Xxxxxxxxx"
##环境
BUILD_TYPE="Release"
## jenkins目录
JENKINSPATH=${WORKSPACE}
##xcarchive文件的存放路径
ARCHIVEPATH=${JENKINSPATH}/${APP_NAME}.xcarchive
## xcodebuild文件所在目录
APP_PATH="xxxxxxxxxxxxxxxxxxxxxxxxx"
#unpackage文件的存放路径
UPDATEPACKAGE="xxxxxxxxxxxxxxxxxxxxxxxxx"
## ExportOptions.plist文件的存放路径
EXPORTOPTIONSPLIST=${APP_PATH}package/exprot.plist
## 导出后的ipa路径
EXPORTPATHIPA=${JENKINSPATH}/IPA
#############################编译###############################
#删除apps下的www老文件
find ${UPDATEPACKAGE}* -exec bash -c 'rm -rf {}' \;
echo -e "============apps下的www老文件已删除============"
#更新包
cp -a ${JENKINSPATH}/www ${UPDATEPACKAGE}
echo -e "============apps下的www文件已更新============"
## 清理缓存
echo -e "============开始清除缓存============"
cd ${APP_PATH}
xcodebuild clean -scheme ${SCHEME} -configuration ${BUILD_TYPE}
echo -e "============Build Clean 成功============"
#给 通过jenkins打包ipa包报错 Jenkins一个用户身份。 build步骤前添加一步解锁钥匙串
security unlock-keychain -p "你的PASSWD" ~/Library/Keychains/login.keychain
## 编译archive包
echo -e "============开始编译 Archive============"
xcodebuild archive -scheme ${SCHEME} -archivePath ${ARCHIVEPATH} -configuration ${BUILD_TYPE}
echo -e "============Build Archive Success============"
## 导出IPA包
echo -e "============开始导出IPA包============"
xcodebuild -exportArchive -archivePath ${ARCHIVEPATH} -exportPath ${EXPORTPATHIPA} -exportOptionsPlist ${EXPORTOPTIONSPLIST}
echo -e "============Export IPA SUCCESS============"
## 编译完成时间
BUILD_DATE="$(date +'%Y%m%d_%H%M')"
import requests
import os
#账号配置信息
url = "https://upload.pgyer.com/apiv1/app/upload"
uKey = "xxxxxxxxxxxxxxxxxxxxxx"
api_key="xxxxxxxxxxxxxxxxxxxxxx"
apkPath ="xxxxxxxxxxxxxx.ipa"
apkfile = {"file":open(apkPath,"rb")}
headers = {"enctype":"multipart/form-data"}
payload= {
"uKey":uKey,
"_api_key":api_key,
"installType":1,
"updateDescription":"ios自动化打包"
}
r = requests.post(url,data= payload,headers=headers,files = apkfile)
jsonResult = r.json()
print(jsonResult)
#保存二维码至本地
appQRCodeURL = jsonResult["data"]["appQRCodeURL"]
print("appQRCodeURL: %s "%appQRCodeURL)
response = requests.get(appQRCodeURL)
imgp = "xxxxxxxxxxxxxx"
qr_image_file_path = os.path.join(imgp,"QRCode.png")
print(qr_image_file_path)
with open(qr_image_file_path,"wb") as f:

更多推荐










所有评论(0)