Jenkins iOS 打包步骤
1.前言
整体思路:
1.在打包机弄一个工程,手动让它打包成功一次(此步骤含iOS证书配置等工作)
2.配置fastlane脚本,让他成功打包(此步骤含安装fastlane,配置fastlane脚本)
3.配置fastlane 上传蒲公英(此步骤有2个方案,a,通过fastlane脚本实现 b,通过Jenkins插件实现)
4.安装Jenkins
5.配置Jenkins,以及webhook连接云效
6.配置飞书机器人,让Jenkins完成打包上传后发送通知到群里
2.详细步骤
1.手动打包
安装Xcode 以及Xcode 命令行
新建一个Xcode工程,配置cocodpods,安装基本的SDK。
然后再Xcode - Setting - Account里添加开发者账号
然后配置自动证书或者去appledevelop后台下载手动证书
配置完成后进行Achive 打包
打包成功后进行下一个步骤
(由于这个文档主要是面向iOS开发,所以手动打包部分不赘述,此部分有疑问可查询相关文档)
2.配置fastlane脚本
1.在命令行安装fastlane
下面2行代码选择一个执行
sudo gem install fastlane -NV
brew install fastlane
执行成功后,执行
fastlane -v
如果能看到版本号说明执行成功了
2.初始化fastlane
cd到项目xcodeproj的上级目录
执行
fastlane init
选择Manual setup - manually setup your project to automate your tasks
初始化fastlane成功后
点Gemfile进去 替换源
source "https://gems.ruby-china.com"
3.配置fastlane
首先安装蒲公英插件
fastlane add_plugin pgyer
再次编辑gemfile文件
source "https://gems.ruby-china.com"
gem 'fastlane'
plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile')
eval_gemfile(plugins_path) if File.exist?(plugins_path)
然后通过VSCode打开Appfile
复制下面代码,根据项目修改bundle id,苹果账号,team_id
# app_identifier("") # The bundle identifier of your app
# apple_id("[[APPLE_ID]]") # Your Apple Developer Portal username
# For more information about the Appfile, see:
# https://docs.fastlane.tools/advanced/#appfile
#bundle id
app_identifier("bundle id")
#苹果账号
apple_id("addid@xx.com")
#teamid 在苹果后台查看
team_id("TEAMID")
然后通过VSCode打开Fastfile
复制下面代码,根据项目修改里面的相应参数
# This file contains the fastlane.tools configuration
# You can find the documentation at https://docs.fastlane.tools
#
# For a list of all available actions, check out
#
# https://docs.fastlane.tools/actions
#
# For a list of all available plugins, check out
#
# https://docs.fastlane.tools/plugins/available-plugins
#
# Uncomment the line if you want fastlane to automatically update itself
# update_fastlane
default_platform(:iOS)
platform :iOS do
lane :eynamics_test do
# add actions here: https://docs.fastlane.tools/actions
gym(
clean: true,
output_directory: './fastlane/build',#输出路径
output_name:"{ipa包名称}.ipa",
scheme: 'ios-eynamics-app',#iOS Target scheme
configuration: 'Debug',#/配置开发模式还是发布模式:Debug or Release
# sdk:"iOS 12.0",
# archive_path:"./fastlane/Archive",
include_symbols:true,
export_options: {
method: 'development',#测试包
// 有这些导出的类型,需要有相应的证书配对才能导出成功ipa。
// app-store, ad-hoc, package, enterprise, development, developer-id
# provisioningProfiles: {
# "com.xxxx.xxx" => "20210906_dev" #测试打包描述文件
# },
}
)
# 使用jenkins 插件上传。fastlane只打包
# pgyer(api_key: "e9f8563c95a396ecea6b6e597e2a3341")
#current_time = Time.now.in_time_zone("Asia/Shanghai")
#pgyer(api_key: "", update_description: "update by fastlane #{current_time}")
end
end
然后执行
fastlane eynamics_test
传值版本
# This file contains the fastlane.tools configuration
# You can find the documentation at https://docs.fastlane.tools
#
# For a list of all available actions, check out
#
# https://docs.fastlane.tools/actions
#
# For a list of all available plugins, check out
#
# https://docs.fastlane.tools/plugins/available-plugins
#
# Uncomment the line if you want fastlane to automatically update itself
# update_fastlane
default_platform(:ios)
platform :ios do
lane :'iOS_EICharge_Test' do |options|
# add actions here: https://docs.fastlane.tools/actions
method_to_use = options[:build_type] == '_Pre' ? 'ad-hoc' : 'development'
configuration_to_use = options[:build_type] == '_Pre' ? 'Release' : 'Debug'
gym(
clean: true,
output_directory: './fastlane/build',
output_name:"EICharge_test_debug.ipa",
scheme: 'iOS-PINGALAX-alps-app',
configuration: configuration_to_use,###########
# sdk:"iOS 12.0",
# archive_path:"./fastlane/Archive",
include_symbols:true,
export_options: {
method: method_to_use,#测试包
# provisioningProfiles: {
# "com.xxxx.xxx" => "20210906_dev" #测试打包描述文件
# },
}
)
# 使用jenkins 插件上传。fastlane只打包
# pgyer(api_key: "e9f8563c95a396ecea6b6e597e2a3341")
# current_time = Time.now.in_time_zone("Asia/Shanghai")
# pgyer(api_key: "e9f8563c95a396ecea6b6e597e2a3341", update_description: "update by fastlane #{current_time}")
end
end
执行
fastlane iOS_EICharge_Test build_type:_Pre
如果打包成功的话fastlane部分配置完成了
记得要把这个包,上传到相应的Git地址里,或者Git地址那个包也要安装fastlane,走fastlane步骤
3. 安装Jenkins
这部分不是我做的后续根据相关文档更新
或者搜寻相关参考文档
4.配置Jenkins
创建自由风格的软件
然后进行配置
General 部分填写基本信息
源码配置
这部分的细节
1.最好用ssh配置,在相应的git上配置ssh秘钥,然后再jenkins的Credentials新建ssh的证书,匹配后就可以添加完成。
设定分支-第一个是首先检出的分支
补充:通过Build with Parameters选择分支的方式
https://juejin.cn/post/7014021599988809735
构建触发器
https://help.aliyun.com/document_detail/306411.html
这是云效官方文档
首先按照上面安装触发器插件,然后勾选Generic Webhook Trigger
这里可以传值
在Jenkins这里这样配置
云效执行命令部分新增仓鼠
# input your command here
curl -X POST -H "Content-Type: application/json" -d '{"env":"_Test"}' http://114.215.184.253:28080/generic-webhook-trigger/invoke?token=ios-EICharge-app-test
最后在Jenkins传参
export FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT=10 &&
export FASTLANE_XCODEBUILD_SETTINGS_RETRIES=5 &&
export LANG=en_US.UTF-8 && export LANGUAGE=en_US.UTF-8 && export LC_ALL=en_US.UTF-8 && cd iOS-PINGALAX-alps-app && python3 modify_info_plist.py ${env} && fastlane iOS_EICharge_Test build_type:${env}
底部附python 修改项目版本号的文件代码
配置参数
这部分是为了云效,后面插入部分云效配置
URL:http://114.215.184.253:28080/generic-webhook-trigger/invoke?token=eynamics
前面部分是Jenkins地址中间固定的后面 = 后面是Token值
配置完成后再云效测试下是否通过
运行执行命令这里要写
# input your command here
curl -X POST http://114.215.184.253:28080/generic-webhook-trigger/invoke?token=#那边写的Token#
传值版本 env是前面Jenkins Variable部分配置
# input your command here env是前面Jenkins Variable部分配置
curl -X POST -H "Content-Type: application/json" -d '{"env":"_Dev"}' http://114.215.184.253:28080/generic-webhook-trigger/invoke?token=ios-EICharge-app-test
这样才能通过Jenkins的webhook执行Jenkins(忘了的话很尴尬)
安装蒲公英Jenkins插件
安装完成后
先运行一次Jenkins 生成运行空间。
在Build Steps(构建步骤)里添加 Execute shell
然后输入脚本
#这种不会递增版本号
export LANG=en_US.UTF-8 && export LANGUAGE=en_US.UTF-8 && export LC_ALL=en_US.UTF-8 && cd ios-eynamics-app && fastlane eynamics_test
#这种会递增版本号,但是Xcode记得设置初始版本号
export LANG=en_US.UTF-8 && export LANGUAGE=en_US.UTF-8 && export LC_ALL=en_US.UTF-8 && cd ios-eynamics-app && fastlane run increment_build_number && fastlane eynamics_test
#这种会使用Python代码+ env传值 自动设置版本号 可以看前面传值部分
export LANG=en_US.UTF-8 && export LANGUAGE=en_US.UTF-8 && export LC_ALL=en_US.UTF-8 && cd iOS-PINGALAX-alps-app && python3 modify_info_plist.py ${env} && fastlane iOS_EICharge_Test
#这种会使用Python代码+ env传值 自动设置版本号,通过传值确定打debug Release和ad-hoc和development包 可以看前面传值部分
export LANG=en_US.UTF-8 && export LANGUAGE=en_US.UTF-8 && export LC_ALL=en_US.UTF-8 && cd iOS-PINGALAX-alps-app && python3 modify_info_plist.py ${env} && fastlane iOS_EICharge_Test build_type:${env}
然后Build Steps(构建步骤)里添加 Upload to pgyer with apiV2
进行如下图配置
curl -X POST -H "Content-Type: application/json" \
-d '{"msg_type":"text","content":{"text":"通知 EI Charge-iOS-Test环境包进行了更新,下载地址为:https://www.pgyer.com/RNZbvm"}}' \
https://open.feishu.cn/open-apis/bot/v2/hook/6f7691f9-d6c2-4e50-be01-5996f06fce46
安卓路径配置
找到apk包的的路径
文件名这种写法就可以
这部分完成后,保存项目,然后push代码后看是否能构建成功,成功的话就完成所有构建了。
5.配置飞书机器人
首先在飞书群,配置自定义群机器人,选用webhook的方式
复制并保管好webhook,用于给群发送消息
在Build Steps再次添加脚本Execute shell(最下方)
这个脚本的text:后的字符串可以替换,是机器人发送的文案
最下方的url也可以替换,替换成刚刚飞书机器人的webhook
curl -X POST -H "Content-Type: application/json" \
-d '{"msg_type":"text","content":{"text":"通知-代码进行了更新,下载地址为:https://www.pgyer.com/YsP0D6"}}' \
https://{飞书机器人webhook地址}
#例如
#https://open.feishu.cn/open-apis/bot/v2/hook/123-456-789
保存即可。
6.补充(云效或命令行主动触发Jenkins)
在云效-流水线新建流水线
流水线源配置为Jenkins
在下图部分输入Jenkins公网地址 以及用户名 密码
连接成功后添加执行命令
新增一个执行命令如下图
# input your command here
#这下面的Url是Jenkins配置的webhook地址
curl -X POST http://{Jenkins地址}/generic-webhook-trigger/invoke?token={你的TOKEN}
#例如,地址和Token乱写的
#curl -X POST http://123.456.789:8080/generic-webhook-trigger/invoke?token=yourToken
然后添加飞书机器人通知插件(可选)
此处webhook填写的是飞书机器人的webhook,用于通知开始启动打包业务了
modify_info_plist.py 代码
import subprocess
import argparse
import plistlib
import re
def get_project_version():
try:
# project_path = "./iOS-PINGALAX-alps-app.xcworkspace"
# 构建 Info.plist 文件路径
plist_path = "./PZXSwiftProject/Info.plist"
# 使用 plistlib 加载 Info.plist 文件
with open(plist_path, 'rb') as fp:
plist = plistlib.load(fp)
# 获取版本号
version = plist.get('CFBundleShortVersionString')
match = re.match(r'^(\d+\.\d+\.\d+)', version)
if version:
print(f"项目版本号为:{ match.group(1)}")
return match.group(1)
else:
print("未找到版本号信息。")
except Exception as e:
print(f"获取版本号时出错:{e}")
def update_xcode_project_version(new_version):
# 设置项目路径,相对路径,脚本和文件放在同一目录下
project_path = "./iOS-PINGALAX-alps-app.xcworkspace"
# 更新版本号
update_version_command = [
"xcrun",
"agvtool",
"new-marketing-version",
new_version
]
subprocess.run(update_version_command)
def main():
parser = argparse.ArgumentParser(description='Update Xcode project version')
parser.add_argument('suffix', nargs='?', default='',
help='Suffix to append to current version (e.g., _Dev)')
args = parser.parse_args()
current_version = get_project_version() # 这里假设当前版本号是固定的,你可以根据实际情况修改
if args.suffix:
new_version = f"{current_version}{args.suffix}"
else:
new_version = current_version
update_xcode_project_version(new_version)
if __name__ == "__main__":
main()