持续集成:Python 整合打包
文章目录
介绍
本文介绍如何使用 Python 整合打包流程。
系列
为什么用 Python?
如果只是单纯的打包,看起来 Unity 自己就可以做好。但现实往往是需求在一点一点增多,例如:
- 刚开始只需要打包 apk
- 后来需要支持引入第三方 SDK,刚开始只需要放到 Plugins/Android 中就可以了
- 随着需要支持的第三方 SDK 越来越多,第三方 SDK 要求修改的东西也越来越多,Unity 打包不能满足需求
- Unity 内部的 Gradle 版本是固定的,如果想要使用其他版本的 Gradle 就需要 Unity 导出 Gradle 工程
- 打包完成后还有部署,需要将生成的 apk 传到指定的 FTP/CDN 等服务器上
- 打包出来的 AssetBundle 需要部署到 CDN 上,可能会使用云厂商提供的 COS OSS 之类的命令行工具
- 需要自定义构建成功的通知消息,增加版本控制日志并发送到 企业微信/钉钉/飞书/Slack 等等
- 。。。
因为这是一整套持续集成的工作,因此才需要使用 Python 来支持。
优点
- 启动速度快(如果使用 Unity 运行 C# 脚本,Unity 本身启动要数十秒)
- 跨平台,同时支持 Windows、macOS、Linux
- 简单易上手,易于编写与修改,入门难度很低
- 社区支持强大,有大量的各种功能的第三方库
- 文档完善,支持中文1,现在翻译进度大概 70%+2
环境
- Python 3.10
- Windows 10 21H2
准备
版本选择
确定要支持的操作系统版本,例如支持 Windows 7 的 Python 版本是 3.8.x。确定好版本后不要轻易改动,否则所有脚本与功能都需要重新测试。
推荐下载时使用离线包,而不是包管理器 Homebrew、Scoop 之类的进行安装,因为包管理器只有最新版本,软件版本升级后无法使用包管理器安装旧版本,导致无法维持环境一致性。
IDE 支持
工欲善其事,必先利其器
如果需要写 Python,推荐不要折腾各种编辑器了,什么 Visual Studio Code + Python 扩展之类的都是邪路,不如选择一个完全整合好的 IDE:PyCharm。PyCharm Community 版本完全可以满足需求,而且还是免费的。
PyCharm 现在支持中文,有完整的中文语言包,使用上非常方便。支持跨平台,每年都会发布三个版本,增加大量功能,适配各种中间件等等。
库整合方式
这里直接说结论,推荐使用修改 sys.path
方式修改搜索路径,以支持第三方库。
|
|
由于涉及到的内容较多,推荐前往另一篇文章了解详情:
注意:很多第三方库使用 Native 库实现某些功能,Python 相关的样板 .gitignore 往往会忽略库文件,因此需要手动添加 so dll 等文件到 Git 版本控制中。
流程
- 准备阶段
- 准备好打包需要的环境,例如终止上次未结束的 Unity 进程
- 更新仓库,清理无用文件,恢复到初始状态
- 导出阶段
- Unity 导出工程
- 打包阶段
- Gradle 打包 apk / Xcode 打包 ipa
- 部署阶段
- 部署 apk/ipa 到 FTP/CDN
- 部署 AssetBundle 等更新用的资源到 CDN
- 通知阶段
- 编写自定义的构建成功通知信息
可以根据自己的实际情况划分阶段,这里依然强烈推荐将导出工程与打包工程分开,因为这两步基本上是最耗时的且输出最多的,分开有助于查找问题。
编写
逻辑
基本上编写逻辑不复杂,只需要简单直白地写。大部分时间是使用 Google 搜索想要做的事情,例如:Python run program。这里可以参考一些现成的代码:
- floatinghotpot/UnityBatchBuild: Batch build toolset for Unity
- 基于python脚本,实现Unity全平台的自动打包 - zblade - 博客园
环境变量
灵活使用环境变量作为传递数据的方法,始终记住环境变量只能由父进程传给子进程。维基百科英文版对这个概念讲得比较多:
命令行参数
使用 Python 调用外部程序,并且通过不同的参数控制外部程序的行为。这里特别需要注意的是:外部程序提供的命令行参数有长版本和短版本,推荐在编写 Python 代码时,尽可能使用长版本参数,这样便于他人阅读代码了解程序做了什么,而不是强迫他人翻阅外部程序的帮助文档。
- bash - Short/long options with option argument - is this some sort of convention? - Stack Overflow
- What is the general syntax of a Unix shell command? - Stack Overflow
工作目录
在调用外部程序时,需要显式地指定工作目录,而不是通过修改当前程序的工作目录,然后让子进程外部程序继承修改后的工作目录。因为程序都会假定当前的工作目录是程序运行后不会发生变化的,如果中途改变了会导致后续的代码出错。
Git 就有 [-C <path>]
参数指定工作目录,因此在调用时需要这样编写:
|
|
构建成功通知
这里通过一个构建结果通知的实例介绍 Python 编写时大概用到哪些东西。从下面的示例中可以看到,Python 擅长的是调用其他程序获得输出来达到想要的效果,因此建议灵活使用 Python 调用第三方程序。
消息截断
使用 data = data[:75]
这种形式直接截断,Python 3 里面使用的是 Unicode,所以这里的截断的是字符,而不是字节。
获取当前提交 SHA-1
git rev-parse --verify HEAD
获取提交历史
git log HEAD..remote/branch
|
|
获取版本号
|
|
- How to Read a Text file In Python Effectively
- Python Regular Expressions | Python Education | Google Developers
获取可读的文件大小
获取人类易读的文件大小实际使用的是一个现成的实现,回答中提到了大部分答案在接近下一档大小时有问题,只有这个实现是无 Bug 版本。
cURL 转换
cURL 转换为 requests 使用网页工具直接转换,可以将机器人消息 cURL 请求转换为 Python requests 代码。
书籍
这里引用之前写的另一篇文章 Unity 持续集成 - 狂飙 中的内容:
《Python编程快速上手 让繁琐工作自动化》这本书非常实用,可以说把实际中执行的操作都写了,因此在编写构建脚本时可以当作工具书参考,要比去网上查找快。
另外,作者还将此书英文版开源放在网上。
其实这本书最大的意义在于将所有自动化相关的内容整合到了一起,推荐做持续集成的人可以先通读一遍书籍,然后再着手编写代码,这样会事半功倍。