美文网首页
iOS 自动打包 (gitlab + Jenkins + she

iOS 自动打包 (gitlab + Jenkins + she

作者: acon | 来源:发表于2019-07-29 10:59 被阅读0次

    总体流程如下表,稍后围绕下表进行分析:


    4F0E96B4-9978-4C5E-823A-E656FFACCDE9.png
    1. 实现功能: 从管理平台勾选功能模块, 然后,配置icon,启动图,首次引导图,bundleID ,打包证书, 生成可以安装的二维码.

    2. 背景说明: 项目是有一个主项目, 然后有其他很多项目都是基于此项目开发,其他项目称为 子项目. 主项目包括用户中心, 登录系统,首页动态配置,基础webview.

    3. 为什么要做成一个主项目,然后有很多子项目, 而 不把 (用户中心, 登录系统,首页动态配置, ReactNative 环境) 做成单独的库,然后集成到各个项目中呢?
      由于主工程中appdelegate 做了一些配置 ,如 首次介绍页, log收集,引导图,一些基础的功能, 为了不让子工程 每次都要写这些代码, 于是写了一个主工程, 子工程只是从主工程拉过来代码, 然后,就成为单独的工程,不在会与主工程交互.

    4. 说下主流程.
      4.1 gitlab 创建私有库工程 LNUappProject, 并把开发完成的首次版本上传.(默认包含登录,首页配置,个人中心,和 一个通用webview)
      此主工程 有主工程开发人员维护.
      当用户在后台管理平台创建一个应用, 并打包的导出应用的时候, 走的流程为:


      image.png

      此时, 把创建的命令传给后台, 后台数据库记录此应用信息
      4.2 平台应用信息:


      image.png

    此步骤后台记录创建的子应用的信息.
    配置证书界面:


    image.png

    可配置一些三方的key 值,(如有分享, 统计)


    image.png

    "保存进入下一步" 后, 进入功能配置界面.下面是配置的界面:


    image.png

    可配置tabbar,首页(可配置首页子模块的实现方式(native,h5,RN)), 轮播图.
    可更换tabbar 上的按钮位置.

    配置完功能后,进入框架的配置:


    image.png

    此时点击构建版本:


    image.png

    填写构建版本的信息.


    image.png

    点击开始构建:
    服务器创建子库, 从主工程拉取代码, 把上面的证书文件拷贝到子库中.把上传的logo 切各个尺寸, 启动图,修改系统中UAPPConfig.plist 文件. 把上述的
    通过jekins创建新任务,并分配任务到mac 打包服务器. mac 打包服务器在构建应用的时候选择 通过shell 方式.

    image.png

    此时 看下执行的shell 脚本的内容: (脚本的大概意思: 解锁钥匙串, 导入证书到钥匙串, 导入ppfile, 修改工程权限,修改appName, bundleid, 获取证书中的公司信息,公司code,构建,导入ipa, 上传ipa 到 s3服务器 ,写的乱, 暂未整理)


    image.png
    #!/bin/bash -l
    export LANG=en_US.UTF-8
    security unlock-keychain -p 'xxxx'
    ProjectName=$1 echo $ProjectName
    if [ -z "$ProjectName" ] then
    echo "⼯工程⽂文件夹不不能为空。" exit;
    else
    echo "传⼊入的⼯工程名字为: {$ProjectName},继续进⾏" fi
    workspacePath="/Users/Shared/Jenkins/Home/workspace" projectPath="/Users/Shared/Jenkins/Home/workspace/${ProjectName}"
    #sudo chown -R pcsd:pcsd $projectPath if [ ! -d "${projectPath}" ];then
    echo "⽂文件夹不不存在"
    exit;
    else
    echo "⽂文件夹存在" fi
    cd $workspacePath
    sudo chmod -R 777 $workspacePath cd $projectPath
    AppConfigPlistPath="${projectPath}/AppConfig.plist"
    #1. ==================项⽬目配置=================
    #1.1 版本号
    version=$(/usr/libexec/PlistBuddy -c "print appversion" ${AppConfigPlistPath}) #1.2 苹果证书对应的Team ID
    #developent_team=$(/usr/libexec/PlistBuddy -c "print development_team" $ {AppConfigPlistPath})
    #1.3 对应的 proversing_profile ⽂文件
    #p_p_specifier=$(/usr/libexec/PlistBuddy -c "print provisioning_profile_specifier" ${AppConfigPlistPath})
    
    #codesign_identity=$(/usr/libexec/PlistBuddy -c "print code_sign_identity" $ {AppConfigPlistPath})
    #应⽤用名称
    app_name=$(/usr/libexec/PlistBuddy -c "print app_name" $ {AppConfigPlistPath})
    #变异环境
    build_env=$(/usr/libexec/PlistBuddy -c "print build_even" ${AppConfigPlistPath}) #bundleid
    bundleid=$(/usr/libexec/PlistBuddy -c "print bundle_id" ${AppConfigPlistPath}) #证书的密码
    code_sign_pwd=$(/usr/libexec/PlistBuddy -c "print code_sign_pwd" $ {AppConfigPlistPath})
    #ipa 包路路径
    ipa_package_path=$(/usr/libexec/PlistBuddy -c "print ipa_package_path" $ {AppConfigPlistPath})
    ipaName=$(/usr/libexec/PlistBuddy -c "print ipaName" ${AppConfigPlistPath})
    echo "pwd: ${code_sign_pwd}"
    #导⼊入证书
    sudo security unlock-keychain -p 'xxxx' /Users/pcsd/Library/ Keychains/login.keychain-db
    sudo security import './LNDEV01.p12' -k /Users/pcsd/Library/Keychains/ login.keychain-db -P "${code_sign_pwd}" -A -T /usr/bin/codesign
    sudo security unlock-keychain -p 'xxxx' /Users/Shared/Jenkins/ Library/Keychains/login.keychain-db
    sudo security import './LNDEV01.p12' -k /Users/Shared/Jenkins/Library/ Keychains/login.keychain-db -P "${code_sign_pwd}" -A -T /usr/bin/codesign #导⼊入配置⽂文件
    cd $projectPath
    echo "==================${projectPath}=========================" #mobileprovision-read -f "./LNUAPPDEV.mobileprovision" -o UUID mobileprovision_plist="${projectPath}/LNUAPPDEV.plist"
    echo $mobileprovision_plist
    #吧配置⽂文件转成plist ⽂文件
    mobileprovisions=`find "${projectPath}" -name "*.mobileprovision"`
    for mp in $mobileprovisions
    do
    sudo security cms -D -i "${mp}" > $mobileprovision_plist ppUUID=`/usr/libexec/PlistBuddy -c "Print UUID" $mobileprovision_plist`
    
    p_p_specifier=`/usr/libexec/PlistBuddy -c "Print Name" $mobileprovision_plist`
    echo "********${ppUUID}*********"
    echo ${mp}
    mv "${mp}" "${ppUUID}.mobileprovision"
    sleep 1
    sudo cp "${ppUUID}.mobileprovision" "/Users/pcsd/Library/MobileDevice/ Provisioning Profiles"
    #rm $mobileprovision_plist
    mv "${ppUUID}.mobileprovision" "${mp}"
    done
    p12s=`find "./" -name "*.p12"`
    for p12 in $p12s
    do
    openssl pkcs12 -in $p12 -out ${projectPath}/temp.pem -nodes -password pass: $code_sign_pwd
    code_sign_identity_inner=`strings temp.pem | grep "friendlyName: iP"`
    echo $code_sign_identity_inner code_sign_identity_inner=${code_sign_identity_inner:18}
    echo $code_sign_identity_inner
    CODE_SIGN_IDENTITY=$code_sign_identity_inner teamid=`strings temp.pem | grep "/OU="` sub="OU="
    subIndex="${teamid#*OU=}" teamid_result="${subIndex:0:10}" DEVELOPMENT_TEAM=$teamid_result
    done
    #echo $version
    #echo $developent_team
    #echo $p_p_specifier
    #echo $version
    #证书及描述⽂文件 #CODE_SIGN_IDENTITY=$codesign_identity #DEVELOPMENT_TEAM=$developent_team PROVISIONING_PROFILE_SPECIFIER=$p_p_specifier
    cd $workspacePath
    
    sudo chmod -R 777 $workspacePath
    PROJECT_NAME="LNUniversalApplication" APP_NAME=$PROJECT_NAME APP_SCHEME=$PROJECT_NAME APP_SPACENAME="${PROJECT_NAME}.xcworkspace"
    cd ${projectPath}/
    #更更新 pod
    #pod setup
    #pod install --verbose --no-repo-update
    # info.plist路路径
    project_infoplist_path="./${APP_NAME}/Info.plist" #result_path=${workspacePath}/build/${build_env}_$(date +%Y-%m- %d_%H_%M) result_path=${workspacePath}/build/${build_env}_${ipa_package_path}
    #修改exportOptions.plist ⽂文件 exportoptions_infoplist_path="./ExportOptions.plist"
    exportteamid=$DEVELOPMENT_TEAM /usr/libexec/PlistBuddy -c "Set :teamID ${exportteamid}" $ {exportoptions_infoplist_path}
    exportoption_bundleid=$bundleid
    /usr/libexec/PlistBuddy -c "delete :provisioningProfiles " $ {exportoptions_infoplist_path}
    /usr/libexec/PlistBuddy -c "add :provisioningProfiles dict" $ {exportoptions_infoplist_path}
    /usr/libexec/PlistBuddy -c "add :provisioningProfiles:${exportoption_bundleid} string ${ppUUID}" ${exportoptions_infoplist_path}
    #修改⼯工程中的 info.plist ⽂文件 #1. 修改版本
    bundleShortVersion=$version
    /usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $ {bundleShortVersion}" ${project_infoplist_path}
    #修改项⽬目名称
    bundleDisplayName=$app_name
    /usr/libexec/PlistBuddy -c "Set :CFBundleDisplayName ${bundleDisplayName}" ${project_infoplist_path}
    
    #修改bundle ID
    bundleID=$bundleid
    /usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier ${bundleID}" $ {project_infoplist_path}
    #修改PRODUCT_BUNDLE_IDENTIFIER
    sed -i '' s/com.lenovo.lnuapp/$bundleID/g $projectPath/ LNUniversalApplication.xcodeproj/project.pbxproj
    sleep 2
    #构建路路径设置
    mkdir -p "${result_path}"
    setting_out=${result_path}/build_setting.txt
    xcodebuild -showBuildSettings -workspace "${APP_SPACENAME}" -scheme "$ {APP_NAME}" -configuration Debug > ${setting_out}
    build_path=`echo $(grep -w "CONFIGURATION_BUILD_DIR" ${setting_out} | awk -F= '{print $2}')`
    echo "======build_path: ${build_path}======" archive_path=${build_path}/${APP_NAME}.xcarchive
    echo "======开始构建======"
    security unlock-keychain -p 'xxxx' &
    xcodebuild clean archive -workspace "${APP_SPACENAME}" \ -scheme "${APP_NAME}" \
    -archivePath ${archive_path} \
    -configuration Debug \ CODE_SIGN_IDENTITY="${CODE_SIGN_IDENTITY}" \ DEVELOPMENT_TEAM="${DEVELOPMENT_TEAM}" \ PROVISIONING_PROFILE_SPECIFIER="$ {PROVISIONING_PROFILE_SPECIFIER}"
    echo "======检查是否构建成功======" if [ -d "${archive_path}" ]; then
    echo "构建成功......" else
    echo -e " 构建失败,请修正后重新运⾏行行!" rm -rf ${result_path}
    exit 1
    fi ipa_path=${result_path}
    
    ExportOptionsPlist=${projectPath}/ExportOptions.plist #XCODE8 需要使⽤用系统的ruby
    which rvm > /dev/null
    if [[ $? -eq 0 ]]; then
    echo "RVM detected, forcing to use system ruby"
    [ -s "$HOME/.rvm/scripts/rvm" ] && . "$HOME/.rvm/scripts/rvm" rvm use system
    fi
    xcodebuild -exportArchive \
    -archivePath ${archive_path} \ -exportOptionsPlist ${ExportOptionsPlist} \ -exportPath ${ipa_path}
    echo "======检查是否成功导出ipa======" ipa_temp_path=${ipa_path}/"LNUniversalApplication".ipa
    echo "--------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------- -----------------------------------------------"
    if [ -f "${ipa_temp_path}" ]; then
    echo "导出ipa成功......"
    #ipa重命名
    mv "${ipa_temp_path}" "${ipa_path}/${ipaName}.ipa"
    else
    echo -e "\033[31m 导出ipa失败...... \033[0m"
    exit 1
    fi
    echo "======共耗时${SECONDS}秒======"
    #curl http://xxx.xxx.xxx.xxx:8082/fileNamagement/upload -F "file=@$ {ipa_temp_path}"
    aws s3 cp "${ipa_path}/${ipaName}.ipa" s3://uapp-test/ --grants read=uri=http:// acs.amazonaws.com/groups/global/AllUsers
    
    
    

    可能遇到的问题:

    • 权限问题,由于 安装 jenkins,电脑默认创建了 一个jenkins 用户 , 通过终端来操作,和通过浏览器执行脚本,所需权限不同,
    • jenkins 用户去操作钥匙串中的证书有权限问题.
    • Sudo 免密操作.由于需要给文件更大权限,读写权限,所以脚本中使用sudo 命令要免密.
    • 修改文件 /磁盘/etc/sudoers 文件中免密的配置. 由于这个文件是只读只读无权限的文件,所以要修改该文件权限.开启mac 系统的超级管理员.
      ** 开启超级管理员方法: (系统偏好设置/登录选项/网络账户服务器:(加入) / 打开目录使用工具/在状态栏找到 “编辑” ,下拉找到启用Root 用户)
      ** 切换到root 用户,修改sudoers 文件中内容.
    • Ssh 免密信任配置.(A机器如果想免密登录B机器,B机器需要有A机器生成的RSA_public key 放到 B机器的.ssh/authorized_keys 文件中.)
    • 读取p12 文件中公司信息,公司ID (首先要把p12证书文件转换成pem 文件,然后把pem 文件转换成plist 文集,查看公司信息 )
    • 读取mobileprovision 文件中team 信息,和 UUID,修改mobileprovision 文件名为UUID,然后倒入到本地 pcsd/mobileDevice 中
    • Ssh 免密配置失败. 使用expect -c spawn su - jenkins …. 脚本来模拟登录.
    • 电脑启动自动和服务器连接

    主流程目录:


    image.png

    相关文章

      网友评论

          本文标题:iOS 自动打包 (gitlab + Jenkins + she

          本文链接:https://www.haomeiwen.com/subject/btsvrctx.html