由于iOS打包有必要依靠Mac设备,本文将介绍在Jenkins中增加远程Mac节点完结自动化打包

当时已配备Mac节点环境

Mac OS 12.6.2
Xcode 14.2
rvm 1.29.12 ruby处理
ruby 2.7.2
cocoapods 1.11.3 用于iOS项目三方库处理
fastlane 2.212.0 用于打包发布,账号证书处理
jenkins 2.375.3
openjdk 11.0.18

设备Jenkins

已设备或已布置Jenkins服务可跳过此节

本次在Mac机器上设备,运用Docker设备

下载镜像文件

docker pull jenkins/jenkins

挂载docker卷并发起jenkins

docker run \
  --name jenkins \
  --privileged=true \
  --env hostip=127.0.0.1 \
  -d \
  -p 8080:8080 \
  -p 50000:50000 \
  -v jenkins-data:/var/jenkins_home \
  jenkins/jenkins

发起后即可 访问 localhost:8080 初始化jenkins,初始化暗码获取经过实行一下指令获取

docker exec -it jenkins bash cat /var/jenkins_home/secrets/initialAdminPassword

设备引荐插件

增加Mac节点

设备好Jenkins后,增加一台mac机器为远程打包节点

进入Jenkins – Manage Jenkins – Manage Node and Clouds处理节点界面

Jenkins增加mac节点完结iOS自动化打包发布

Built-In Node 是原始Jenkins的内建节点

选择新建节点 – 创建

Jenkins增加mac节点完结iOS自动化打包发布

配备节点参数

配备远程作业目录

Jenkins增加mac节点完结iOS自动化打包发布

发起方式选择ssh方式

Jenkins增加mac节点完结iOS自动化打包发布

由于我是经过docker 设备jenkins在本机,这儿可以运用docker本机地址,假设在远程填写对应ip即可

一起,需求在该mac机器上敞开ssh权限,在mac体系设置 – 共享 敞开相关权限

Jenkins增加mac节点完结iOS自动化打包发布

jenkins中创建登陆账号暗码, 点击增加,将本机登陆账号和暗码增加

Jenkins增加mac节点完结iOS自动化打包发布

增加完结

Jenkins增加mac节点完结iOS自动化打包发布

创建jenkins任务

创建相关jenkins任务,配备打包参数

我这儿仅配备了分支选择和fastlane实行选择

Jenkins增加mac节点完结iOS自动化打包发布

增加构建脚本

Jenkins增加mac节点完结iOS自动化打包发布

#!/bin/bash -l
echo "选择构建参数$BRANCH,$LANE_OPT"
if [ $LANE_OPT == 'BUILD_BETA' ]
then
        echo "构建adhoc发布至蒲公英"
        source ~/.zshrc
    proxy_on 
    pod install
        proxy_off
    fastlane beta
elif [ $LANE_OPT == 'SYNC_DEVICES' ]
then
        echo "注册新设备"
    fastlane sync_devices
else
        echo "没有契合条件"
fi

其中 proxy_on proxy_off 为署理,没有署理删去此行代码

fastlane sync_devicesfastlane beta 为 fastlane实行指令,需求在项目中配备fastlane相关设置,后边会提到

钥匙串访问束缚需求增加

security -v unlock-keychain -p xxx ~/Library/Keychains/login.keychain-db

xxx为mac登陆暗码, 可以增加到~/.zshrc中,像我这样打包前实行 source ~/.zshrc 即可

假设目录下没有login.keychain-db, 实行security create-keychain -p xxx ~/Library/Keychains/login.keychain-db 创建

钥匙串设置需求封闭休眠,不然或许构成其他不可控的问题

Jenkins增加mac节点完结iOS自动化打包发布

Jenkins增加mac节点完结iOS自动化打包发布

Jenkins增加mac节点完结iOS自动化打包发布

fastlane设备

设备rvm,选择ruby版别2.7.2

设备fastlane

gem install fastlane -NV

进入项目初始化fastlane,选择4.手动模式

fastlane init

设备版别处理插件、蒲公英插件

fastlane add_plugin versioning
fastlane add_plugin pgyer

开发者证书处理

经过fastlane match处理开发和出产证书, 提前准备好证书存放的git仓库

fastlane match init

翻开 Matchfile 配备相关参数

Jenkins增加mac节点完结iOS自动化打包发布

由于远程仓库禁用ssh,我这儿的git地址可以写成 git_url("http://username:psd``@xxx.git``") 提前设置好用户名和暗码

实行指令可生成相关证书,也可经过配备fastlane脚本实行相关指令,后边会提到

fastlane match development
fastlane match adhoc
fastlane match appstore

实行完结后会自动上传到配备的git仓库中

Jenkins增加mac节点完结iOS自动化打包发布

fastlane脚本配备

从苹果开发者后台创建增加 App Store Connect API 密钥

Jenkins增加mac节点完结iOS自动化打包发布

获取暂时密钥

实行fastlane spaceauth 获取session 用于苹果二次登陆验证(假设现已运用了App Store Connect API可跳过此节)

fastlane spaceauth -u abcd@mail.com

可以将session保存到jenkins环境变量中,或许增加到mac节点中的环境变量中

留意 session信息有效期仅为一个月,过期后需求从头实行此指令

我的ci和mac节点是同一台机器,可以直接增加到jenkins大局的环境变量中

Jenkins增加mac节点完结iOS自动化打包发布

fastfile文件

下面初步编写fastfile文件,该文件包括详细的打包、证书更新脚本

default_platform(:ios)
platform :ios do
  target = "项目target称谓"
  scheme_name = "项目scheme称谓"
  output_directory = "./build"
  team_id = "xxxxx"
  fir_token = ""
  pgyer_token = "蒲公英token"
  fir_feishu_token = ""
  issuer_id = ""
  key_id = ""
  key_filepath = "./Cers/itc_AuthKey_xxx.p8"
  api_key = app_store_connect_api_key(
    key_id: key_id,
    issuer_id: issuer_id,
    key_filepath: key_filepath,
    duration: 1200, # optional (maximum 1200)
    in_house: false, # optional but may be required if using match/sigh
  )
  lane :match_all do
    desc "下载所需求的证书和描绘文件到本地(只读)"
    match(api_key: api_key, type: "development", readonly: true)
    match(api_key: api_key, type: "adhoc", readonly: true)
    match(api_key: api_key, type: "appstore", readonly: true)
  end
  lane :force_match do
    desc "同步证书,假设证书过期或新增了设备,会从头创建证书和描绘文件"
    match(api_key: api_key, type: "development", force_for_new_devices: true)
    match(api_key: api_key, type: "adhoc", force_for_new_devices: true)
    match(api_key: api_key, type: "appstore")
  end
  lane :sync_devices do
    desc "注册设备,并更新描绘文件"
    # devices.txt模板:
    # http://devimages.apple.com/downloads/devices/Multiple-Upload-Samples.zip
    register_devices(api_key: api_key, devices_file: "./fastlane/devices.txt")
    match(api_key: api_key, type: "development", force_for_new_devices: true)
    match(api_key: api_key, type: "adhoc", force_for_new_devices: true)
  end
  lane :beta do
    desc "上传到检验版别到蒲公英"
    # register_devices(
    #   devices_file: "./fastlane/devices.txt",
    #   api_key: api_key,
    #   team_id: team_id
    # )
    match(api_key: api_key, type: "adhoc", readonly: true)
    increment_build_number
    version = get_version_number_from_xcodeproj(
      target: target,
      build_configuration_name: 'Debug'
    )
    build = get_build_number_from_xcodeproj(
      target: target,
      build_configuration_name: 'Debug'
    )
    # output_name = "#{scheme_name}_dev_#{version}_#{build}_#{Time.now.strftime('%Y%m%d%H%M%S')}.ipa"
    output_name = "#{scheme_name}.ipa"
    gym(
      include_bitcode: false,
      export_method: "ad-hoc",
      export_xcargs: "-allowProvisioningUpdates",
      scheme: scheme_name,
      configuration: "Release",
      # clean: true,
      output_directory: output_directory,
      output_name: output_name
    )
    pgyer(api_key: pgyer_token, update_description: "update!")
    # fir_cli api_token: fir_token,  changelog: "to fir.im #{option[:desc]}", feishu_access_token: fir_feishu_token, feishu_custom_message: "fir.im新版已发 #{option[:desc]}"
  end
end

至此可以实行 fastlane beta 即可打包发布到蒲公英, fastlane sync_devices注册新设备,更新证书

协同证书导出

运用fastlane match 生成的相关证书文件内部进行了加密,所以无法从git仓库中直接下载运用,需求参照fastlane官方文档进行解密才可以运用。或许运用正常match指令获取证书,但这要求新的开发人员的机器上有fastlane环境,不是十分便利。

这儿我们可以经过创建一个jenkins任务,在mac节点上运转脚本后直接导出并下载相关文件

创建jenkins任务,增加证书处理的仓库地址,增加构建脚本

#!/bin/bash -l
export_dis_P12() {
  local password=$1
  local p12_filename=$2
  # decrypt private key
  openssl aes-256-cbc -k "$password" -in "certs/distribution/$p12_filename.p12" -out dis_key.pem -a -d
  # decrypt cert
  openssl aes-256-cbc -k "$password" -in "certs/distribution/$p12_filename.cer" -out dis_cert.der -a -d
  # convert cert from der to pem
  openssl x509 -inform der -in dis_cert.der -out dis_cert.pem
  # combine private key + cert into p12 (enter password to secure output p12 file)
  openssl pkcs12 -export -out dis_cert.p12 -inkey dis_key.pem -in dis_cert.pem -password pass:"$password"
}
export_dev_P12() {
  local password=$1
  local p12_filename=$2
  # decrypt private key
  openssl aes-256-cbc -k "$password" -in "certs/development/$p12_filename.p12" -out dev_key.pem -a -d
  # decrypt cert
  openssl aes-256-cbc -k "$password" -in "certs/development/$p12_filename.cer" -out dev_cert.der -a -d
  # convert cert from der to pem
  openssl x509 -inform der -in dev_cert.der -out dev_cert.pem
  # combine private key + cert into p12 (enter password to secure output p12 file)
  openssl pkcs12 -export -out dev_cert.p12 -inkey dev_key.pem -in dev_cert.pem -password pass:"$password"
}
exportProfile() {
  local password=$1
  local bundle_id=$2
  # decrypt AdHoc profile
  openssl aes-256-cbc -k "$password" -in "profiles/adhoc/AdHoc_$bundle_id.mobileprovision" -out "AdHoc_$bundle_id.mobileprovision" -a -d
  # decrypt Development profile
  openssl aes-256-cbc -k "$password" -in "profiles/development/Development_$bundle_id.mobileprovision" -out "Development_$bundle_id.mobileprovision" -a -d
  # decrypt AppStore profile
  openssl aes-256-cbc -k "$password" -in "profiles/appstore/AppStore_$bundle_id.mobileprovision" -out "AppStore_$bundle_id.mobileprovision" -a -d
}
PASSWORD="xxxxxx"
DEV_P12_FILENAME="xxxxxx"
DIS_P12_FILENAME="xxxxxx"
BUNDLE_ID="com.xxxxxx.xxxxxx"
export_dev_P12 "$PASSWORD" "$DEV_P12_FILENAME"
export_dis_P12 "$PASSWORD" "$DIS_P12_FILENAME"
exportProfile "$PASSWORD" "$BUNDLE_ID"
zip all_export.zip "AdHoc_${BUNDLE_ID}.mobileprovision" "Development_${BUNDLE_ID}.mobileprovision" "AppStore_${BUNDLE_ID}.mobileprovision" dev_cert.p12 dis_cert.p12
echo "请至作业区下载all_export.zip, 或许访问 http://yourJenkinsIp:8080/job/$JOB_NAME/ws/all_export.zip"

构建后到作业区下载该压缩包