iOS-Jenkins+git实现自动化打包

4,079 阅读6分钟

对于一个开发来讲,Xcode手动打包是比较耗时的,而且是没有很大技术含量的工作。自动化打包根本目的是为了节约时间,把重复且无技术含量的事情交给工具去做。下面我介绍Jenkins实现自动打包方案:

Mac 安装Jenkins

通过brew安装

  • 安装最新版本
brew install jenkins
  • 安装 LTS 版本
brew install jenkins-lts

下载 pkg 安装

打开Jenkins官网, 点击Downloads

截屏2021-12-20 下午1.38.32.png

选择下载稳定的版本LTS

截屏2021-12-20 下午1.39.55.png

截屏2021-12-20 下午1.40.40.png

截屏2021-12-20 下午1.41.20.png

然后选择要安装的版本安装即可。更多的安装方式可以参考Jenkins官网www.jenkins.io/zh/doc/book…

安装 Java 环境

因为这个Jenkins还是需要依赖 Java 环境的,根据安装的Jenkins 依赖的Java版本进行安装。首先检查电脑是否配置了Java环境

java -version

如果没有,可以去这个地址 www.oracle.com/technetwork… 下载JDK。安装完之后通过 java -version 查看安装的版本。

配置 Java 环境,在终端输入 which java ,输出安装路径(配置环境变量会用到)。打开 open ~/.bash_profile,然后输入

//jdk的安装路径
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-16.0.2.jdk/Contents/Home
export PATH=$JAVA_HOME/bin:$PATH:.
export CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:.

最后输入 source ~/.bash_profile 配置的环境变量就生效了。

Jenkins配置

安装完成之后,需要启动Jenkins

  • 启动jenkins: brew services start jenkins
  • 停止jenkins:brew services stop jenkins
  • 重启Jenkins:brew services restart jenkins

启动之后在浏览器中输入http://localhost:8080 就会进入Jenkins初始页面

Jenkins 初始化

截屏2021-11-08 上午8.38.21.png

找到Jenkins在电脑的安装目录,在 Jenkins 目录下 /Home/secrets/initialAdminPassword 这个目录,打开 initialAdminPassword 然后把密码复制出来粘贴到这里输入框

点击继续进入这个页面,点击建议安装的插件(默认左边这个选项)

截屏2021-11-07 下午2.56.02.png

然后就耐心的等待插件的安装

截屏2021-11-07 下午2.58.20.png

再然后就是创建第一个管理账户,就按着提示一步步走下来,这样就初始化配置完成了。

Jenkins配置插件

接下来就可以配置Jenkins常用到的插件了,选择系统管理->插件管理->可选插件。 然后搜索下面这些插件进行安装:

  • GitLab Plugin 和 Gitlab Hook Plugin
  • Xcode integration
  • DingTalk
  • upload-pgyer-plugin

这些插件搜索到直接点击安装就可以了,重启就会生效。但是我们一般打包还会带上 git的提交记录,这样其他人就知道包更新了什么内容,这个插件就是 changelog environment plugin,但是这个插件官方没有,需要自己编译然后添加。

安装插件 Changelog Environment Plugin

由于 Jenkins 并没有官方的插件来做这个事,只能找现成的已经有的开源代码自己编译插件。 下载插件源代码:github.com/daniel-beck…

安装 Maven

下载地址:maven.apache.org/download.cg…

解压到某个目录下

/Users/***/apache-maven-3.8.1

然后添加 Maven 相关环境,在 .bash_profile 里面添加

export M_HOME=/Users/***/apache-maven-3.8.1
export PATH=$PATH:$M_HOME/bin

然后执行 source ~/.bash_profile 让配置的环境生效

输入 mvn -v ,检查是否配置成功

编译源码生成 hpi

cd 到 changelog-environment-plugin-master 下,执行 mvn verify

经过比较长的时间,会在 changelog-environment-plugin-master/target/ 下有个changelog-environment.hpi文件这就是我们需要的插件。

然后把生成的插件上传到 Jenkins。最后可以在安装的插件里面查找到这个

截屏2021-12-17 下午5.00.28.png

Jenkins的使用

配置钉钉机器人

Dashboard -> configuration 配置钉钉机器人。假如想自定义消息样式,可以参考官方插件说明:jenkinsci.github.io/dingtalk-pl…

截屏2021-12-17 下午5.02.10.png

创建任务

截屏2021-12-20 下午1.46.00.png

截屏2021-12-20 下午1.46.42.png

配置一下General参数

截屏2021-11-07 下午3.22.45.png

配置钉钉机器人参数

我目前设置构建成功后通知钉钉群,通知人就是填写@人的手机号码,自定义内容里面就是通知面板里面显示的内容,这些参数都是从蒲公英获取App信息接口拿到的,包含的信息可以查看官网:www.pgyer.com/doc/view/je…

截屏2021-12-17 下午5.13.59.png

配置可选参数

这里可以配置选择构建的分支、打包的环境、编译的环境等等配置项

截屏2021-12-17 下午5.15.22.png

配置源码管理

打开自己的项目,复制项目链接填入Repository URL,然后点击Credentials右边的添加,主要是为了拉取项目使用,会展示出下图所示。有两种选择,使用账户密码或者使用SSH

截屏2021-11-07 下午3.29.41.png

添加完之后会自动检查你添加的凭证是否正确,错误是会有报错信息的

截屏2021-12-17 下午5.16.02.png

截屏2021-11-07 下午3.28.27.png

提示:关于怎么配置SSH,首先检查是否配置过SSH,在终端执行命令 ls -al ~/.ssh,会存在以下两种情况:

  1. 如果配置过会输出id_rsa 和 id_rsa.pub,则证明配置过;
  2. 如果没有配置过,则执行命令ssh-keygen -t rsa -C "your_email@example.com",就会生成id_rsa 和 id_rsa.pub文件; 直接在终端输入vim ~/.ssh/id_rsa.pub,把输出的内容复制到gitLab配置SSH,在上面配置凭证那里也添加一下。

配置抓取 git 提交信息

截屏2021-12-17 下午5.17.07.png

【%3$s--%1$s--%4$s】

 MM/dd

截屏2021-12-17 下午5.17.51.png

添加构建脚本

  • 首先需要 pod install 下项目,添加脚本
#bin/bsah - l
export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8
export LC_ALL=en_US.UTF-8
//进入工程目录
cd $WORKSPACE
/usr/local/bin/pod install --verbose --no-repo-update
  • 再增加个构建的脚本
#!/bin/sh

# 工程名称(必填)
workspace_name=""

# 指定项目的scheme名称(必填)
scheme_name=""

# 指定要打包编译的方式 : Debug、Release(必填)
build_configuration=${buildType}

# method,打包的方式。方式分别为 development, ad-hoc(必填)
method=""

# 项目的bundleID,手动管理Profile(必填)
bundle_identifier=""

# 下面两个参数只是在手动指定Pofile文件的时候用到,如果使用Xcode自动管理Profile,直接留空就好
#(跟method对应的)mobileprovision文件名,需要先双击安装.mobileprovision文件.手动管理Profile时必填

mobileprovision_name=""
if [ ${buildType} == "Debug" ];then
build_configuration="Debug"
method="development"
mobileprovision_name=""
else
build_configuration="Release"
method="ad-hoc"
mobileprovision_name=""
fi

echo "--------脚本配置参数检查-----------"
echo "workspace_name = ${workspace_name}"
echo "scheme_name = ${scheme_name}"
echo "build_configuration = ${build_configuration}"
echo "method = ${method}"
echo "bundle_identifier = ${bundle_identifier}"
echo "mobileprovision_name = ${mobileprovision_name}"

# ==========脚本的一些固定参数定义(基本不需要修改)======== #

# 获取当前脚本所在目录
script_dir="$WORKSPACE/$workspace_name"

# 工程根目录
project_dir=$script_dir

# 指定输出导出文件夹路径
export_path="$project_dir/Build"
# 指定输出归档文件路径
export_archive_path="$export_path/$scheme_name.xcarchive"
# 指定输出ipa文件夹路径
export_ipa_path="$export_path/"
# 指定导出ipa包需要用到的plist配置文件的路径
export_options_plist_path="$project_dir/ExportOptions.plist"

echo "--------脚本参数检查-----------"
echo "project_dir = ${project_dir}"
echo "export_path = ${export_path}"
echo "export_archive_path = ${export_archive_path}"
echo "export_ipa_path = ${export_ipa_path}"
echo "export_options_plist_path = ${export_options_plist_path}"

# =======================自动打包部分(无特殊情况不用修改)====================== #

echo "------------------------------------------------------"
echo "开始构建项目"

# 进入项目工程目录
cd ${project_dir}

# 指定输出文件目录不存在则创建
if [ -d "$export_path" ];
then rm -rf "$export_path"
fi

# 编译前清理工程
xcodebuild clean -workspace ${workspace_name}.xcworkspace -scheme ${scheme_name} -configuration ${build_configuration}

#编译工程
xcodebuild archive -workspace ${workspace_name}.xcworkspace -scheme ${scheme_name} -configuration ${build_configuration} -archivePath ${export_archive_path}

# 检查是否构建成功
# xcarchive 实际是一个文件夹不是一个文件所以使用 -d 判断
if [ -d "$export_archive_path" ] ; then
    echo "项目构建成功"
else
    echo "项目构建失败"
    exit 1
fi

echo "------------------------------------------------------"
echo "开始导出ipa文件"

# 先删除ExportOptions.plist文件
if [ -f ${export_options_plist_path} ] ; then
    #echo "${export_options_plist_path}文件存在,进行删除"
    rm -f ${export_options_plist_path}
fi

//生成ExportOptions.plist文件,这个平常手动打包成功导出ipa包时就可以看到
/usr/libexec/PlistBuddy -c 'Add :provisioningProfiles:'${bundle_identifier}' string '${mobileprovision_name}'' $export_options_plist_path

/usr/libexec/PlistBuddy -c 'Add :method string '${method}'' $export_options_plist_path

/usr/libexec/PlistBuddy -c 'Add :compileBitcode bool NO' $export_options_plist_path

//导出ipa包
xcodebuild -exportArchive -archivePath ${export_archive_path} -exportPath ${export_ipa_path} -exportOptionsPlist ${export_options_plist_path} -allowProvisioningUpdates

# 检查文件是否存在
if [ -f "$export_ipa_path/$scheme_name.ipa" ] ; then
    echo "导出 ${scheme_name}.ipa 包成功"
    open $export_path
else
    echo "导出 ${scheme_name}.ipa 包失败"
    exit 1
fi

# 删除export_options_plist文件(中间文件)
if [ -f "$export_options_plist_path" ] ; then
    echo "${export_options_plist_path}文件存在,准备删除"
    rm -f $export_options_plist_path
fi

# 输出打包总用时
echo "使用AutoPackageScript打包总用时: ${SECONDS}s"

echo -e "打包成功"

配置蒲公英插件

这个scandir就是ipa所在的路径,"${SCM_CHANGELOG}" git提交信息。

截屏2021-12-20 下午3.35.19.png

Jenkins 构建项目

这就是任务里面配置的可选参数,选择后点击 build

截屏2021-12-17 下午6.22.05.png

可以登录蒲公英看到,包上传成功了

截屏2021-12-17 下午6.28.22.png

这个是通知到钉钉群的消息,这个耗时长时因为上传蒲公英时网速慢导致的。假如想自定义消息样式,可以参考官方插件说明:jenkinsci.github.io/dingtalk-pl…

截屏2021-12-17 下午6.27.18.png

假如遇到了这个问题 error: exportArchive: "TPNSExtension.appex" requires a provisioning profile.。这是缺少了推送描述文件,在创建export_options_plist文件的时候加上这个参数就能解决了。

这里讲到的是Jenkins配合脚本完成了自动打包的流程,这一过程必须依赖Xcode环境及证书的正确配置,单纯的实现打包这样还是比较方便的,这样谁想打包就打开Jenkins,然后 Build 就可以了。如果通过Jenkins配置证书,需要下载2.263.4或者更旧的版本,新版本的Jenkins是上传不了证书和描述文件的。Fastlane功能更强大,可以建很多lane做事情,但是需要输入我开发者账号和密码。所以我还是比较喜欢用Xcode配合脚本进行打包很方便。

其他的打包方式,可以参考下面的文章:

juejin.cn/post/702801…

juejin.cn/post/703096…