持续集成:Jenkins 整合打包
文章目录
介绍
本文介绍如何配置 Jenkins 打包。
系列
安装
虚拟机
首先需要在本地测试,因此使用 Vagrant + Virtual Box 组合创建一个现成的虚拟机,如果直接在生产环境上安装可以跳过下面的安装过程,直接参考 Jenkins 官方教程进行安装。包管理器安装方式也可以参考 Jenkins 安装配置 - 狂飙。
使用 Vagrant 安装 Ubuntu 22.04 作为服务器(后续需要使用 Packer 生成镜像),使用 Docker 安装 Jenkins。
Vagrant 2.2.19
Virtual Box 6.1.32
使用 Ubuntu 20.04 镜像
虚拟化
启动 Vagrant 虚拟机时有报错:
|
|
需要禁用 HyperVisor,以管理员运行命令行提符:
|
|
然后重启,按 F2 进入 BIOS,在 BIOS 中开启 Intel 虚拟化 VMM,再次运行 Vagrant 就可以了。
Docker 安装
|
|
桥接网络
使用文档
改为桥接网络 config.vm.network "public_network"
,但是启动后依然找不到网卡。显式指定了网卡 config.vm.network "public_network", :bridge => "Realtek PCIe 2.5GbE Family Controller"
也无效。
打开 Virtual Box,选择 Vagrant 启动的虚拟机,点击 设置 | 网络 | 网卡1
,连接方式改为桥接,然后可以看到下面的 界面名称
下拉框中没有可选的网卡,这说明是缺失 Virtual Box 网卡驱动,安装即可。
安装方法:
- 打开当前网络连接属性,点击
安装
按钮 选择网络功能类型
对话框中选择服务
,点击添加
按钮选择网络服务
对话框中点击从磁盘安装
从磁盘安装
对话框的制造商文件复制来源
输入框中输入C:\Program Files\Oracle\VirtualBox\drivers\network\netlwf
选择网络服务
对话框中点击确认
按钮
相关解决方案:
- vagrant 无法启动出现Which interface should the network bridge to的问题 - fogwu - 博客园
- Vagrant not showing any available network interfaces - Stack Overflow
之前如果运行过 vagrant up 出错,使用 Ctrl+C 中断操作,那么需要打开任务管理器,结束 ruby.exe 进程。
最后确认一下是否获得了内网 IP:
|
|
Docker 配置
以 Docker 后台模式运行 Jenkins
|
|
拿到内网 IP 后在浏览器中访问 http://内网IP:8080/
Docker 数据目录映射
由于后续需要对 Jenkins 版本进行升级,因此需要将数据放到外面。Docker Volume 用起来不太直观,因此考虑将文件直接放到宿主机上。
另外由于使用的是 Vagrant,似乎可以将文件存到主机的映射目录中,但是 Jenkins Docker 文档中提到了符号链接在某些操作系统下会变成拷贝,会导致最后一次稳定构建链接问题,因此决定不放到映射目录中:
Note that some symlinks on some OSes may be converted to copies (this can confuse jenkins with lastStableBuild links etc)
使用映射目录必须修正权限问题:
|
|
Docker 设置镜像开机启动
|
|
Jenkins Agent
配置
创建节点,然后配置节点 通过Java Web启动代理
,在状态中下载 agent.jar
放到 d:\Jenkins\
,并拿到启动节点的命令,将其保存为 d:\Jenkins\JenkinsAgent.bat
,运行后提示:'java' 不是内部或外部命令,也不是可运行的程序或批处理文件。
需要下载 Java runtime 才能运行,选择 Windows Offline (64-bit) 下载。
复制出来的命令必须删除 -workDir
参数的双引号,否则运行报错:
|
|
开机自启
资源管理器打开 shell:startup
,然后右键拖放 JenkinsAgent.bat
到此目录中,在弹出的菜单中选择创建快捷方式,这样就可以将其添加到开机自启动中了。
构建
Job 类型选择
由于 Unity 项目通常比较大,内部有大量的美术资源需要大量时间导入。如果每次都重新克隆新仓库或者将上次导入的缓存完全清除掉,那么重新导入的时间过长,会导致打包耗时过长。
Jenkins 默认的集成仓库方式看起来很好,但是配置中的更新项要求必须完整地清理已忽略文件,可是缓存都在已忽略文件列表中,如果清理掉就会重新导入。
看起来非常有前景的将 Pipeline 脚本放在仓库里,然后每次克隆仓库获取打包指令这种方式也有上述的问题。可以说 Jenkins 主要是为了互联网行业设计的,并没有考虑游戏行业的特点。
最终决定使用自由风格的构建,然后将版本控制的更新放在 Python 脚本里面手动控制,而不是依赖于 Jenkins。而且使用自由风格的构建也可以使用内嵌的 Pipeline 来控制打包。
Pipeline
使用流水线对构建流程进行拆分细化。
按照上一篇文章 Python 整合打包 - 狂飙 定义的阶段来编写 Pipeline 脚本,基本上只是单纯地调用写好的 Python 脚本。
- 准备阶段
- 准备好打包需要的环境,例如终止上次未结束的 Unity 进程
- 更新仓库,清理无用文件,恢复到初始状态
- 导出阶段
- Unity 导出工程
- 打包阶段
- Gradle 打包 apk / Xcode 打包 ipa
- 部署阶段
- 部署 apk/ipa 到 FTP/CDN
- 部署 AssetBundle 等更新用的资源到 CDN
- 通知阶段
- 编写自定义的构建成功通知信息
插件
通知
使用通知扩展主要是为了实现任务失败时的通知,因为这时候只有 Jenkins 可以执行操作。
构建用户
使用 Jenkins 的 Build User Vars 插件通过环境变量获取触发构建的用户名字,环境变量 BUILD_USER
。
安装完成后需要在 配置管理
| 系统配置
| Build User Variables
中勾选 Enabled for all builds
选项,这样才能在 Pipeline 中获取此
- How to get the BUILD_USER in Jenkins when job triggered by timer? - Stack Overflow
- build user vars | Jenkins plugin
GitLab WebHooks
通过钩子可以配置自动构建,用于排查推送的提交是否有问题。
如果添加 WebHook 时提示 Url is blocked: Requests to the lcoal anetwork are not allowed
,需要在管理员面板 Admin Area
| Settings
| Network
| Outbound requests
中启用 Allow requests to the local network from web hooks and services
选项。
添加完成后可以手动触发 Push Events
,然后上方会提示 Hook executed successfully: HTTP 200
。