Jenkins添加mac节点实现iOS自动化打包发布

由于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管理节点界面

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

选择新建节点 – 创建

配置节点参数

配置远程工作目录

启动方式选择ssh方式

由于我是通过docker 安装jenkins在本机,这里可以使用docker本机地址,如果在远程填写对应ip即可

同时,需要在该mac机器上开启ssh权限,在mac系统设置 – 共享 开启相关权限

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

添加完成

创建jenkins任务

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

我这里仅配置了分支选择和fastlane执行选择

添加构建脚本

#!/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 创建

钥匙串设置需要关闭休眠,不然可能造成其他不可控的问题

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 配置相关参数

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

执行命令可生成相关证书,也可通过配置fastlane脚本执行相关命令,后面会提到

fastlane match development
fastlane match adhoc
fastlane match appstore

执行完成后会自动上传到配置的git仓库中

fastlane脚本配置

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

获取临时密钥

执行fastlane spaceauth 获取session 用于苹果二次登陆验证(如果已经使用了App Store Connect API可跳过此节)

fastlane spaceauth -u abcd@mail.com

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

注意 session信息有效期仅为一个月,过期后需要重新执行此命令

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

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"

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

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYRAQTrQ' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片