《乡村铁路》的自动化构建管线

前言

造轮子真开心hhh

我就是很享受准备工具的过程,感觉就像是在玩游戏一样233。所以说给现在在做的游戏鼓捣一套自动化流程就变得很有趣了。

那么打算做些什么呢~

首先就是Unity的打包了,这样每次提交代码后都能收到是否打包成功的反馈,并且每次打包完毕后都会把包体复制到指定的共享目录中,我在工作电脑上随时可以拿到最新的PC整包。

其次,我在项目里写了不少单元测试(Framework的每个功能基本上都写了),我想知道每当我修改了代码之后,这些测试是否还能通得过,这些信息我也需要及时收到反馈。

还有一个就是代码质量检测了。像是哪里偷偷藏了一个TODO,哪里可能有潜在的BUG了,哪里有坏味道了之类的。这些都是技术债,所以我需要随时看到检测结果,并及时修复掉。

需要的工具

硬件(可选)

首先我们需要准备一台编译机,因为是用于Unity打包,所以必须是Windows系统。如果没有闲置电脑的话也可以在自己电脑上装个虚拟机,只不过要记得每次开始干活前要把虚拟机开起来。

我的话刚好去年更新了一波装备,把之前淘汰下来的硬件利用起来,就组出了一台不错的编译机(待机功耗和冰箱差不多,不干活的时候可以关掉)。

Unity

这一项显然是必备的,只要注意BuildMachine上的版本和当前项目开发用的版本一致就好,所以尽量不要更新地太频繁,否则的话每次都要在两个地方重装Unity了。。。

TeamCity

JetBrains家出品的CI工具,主页在这里。Jenkins太常见了想搞点不一样的,另外Unity引擎团队早期使用的CI工具也是TeamCity,再加上对JB家的产品普遍有好感,于是就选的TeamCity。

不过我在用了一段之后发现有个问题,TeamCity的BuildLog里,中文字符会显示成乱码。。这个就比较影响体验了,目前只能把所有的日志信息都用英文表示。

SonarQube

主页传送门在这里

这是一个代码扫描的工具,官方的宣传语是”Continuous Code Quality”,也就是说利用这个工具我们可以对代码进行持续的代码质量跟踪,哪一天新增了大量代码,哪一天新增的代码里出现了许多潜在的BUG,通过一系列妥当的配置之后,这些东西都可以做到一目了然。

再加上可以通过折线图可以看到自己项目的代码行数随着时间慢慢变多,简直成就感爆棚!

配置

Unity配置

打包脚本

这里所说的打包脚本其实就是C#的一个静态方法,之后会通过命令行的方式来调用该方法。当然,这个方法也会在Unity编辑器上提供一个接口,方便我们在开发过程中手动打包。伪代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void DoBuild()
{
var 返回值 = 0;
设置硬编码在代码中的构建时间(); // 大概像这样:public const string BuildTime = "201906241921";
导表(); // 项目中使用的数据表在编辑器环境下都是直接读的Excel,打包时导出为专用二进制格式
打包AssetBundle();
删除旧的Build目录();
var ret = BuildPipeline.BuildPlayer(构建选项);
if (res.summary.result != BuildResult.Succeeded)
{
返回值 = 1;
}
重置构建时间(); // 把第一步修改的代码改回来
EditorApplication.Exit(返回值);
}

单元测试

通过Unity命令行运行编辑器环境下的测试用例。

1
"C:\program files\Unity\Editor\Unity.exe" -batchmode -runEditorTests -projectPath "D:\proj\xxx"

执行完毕后Unity会在项目根目录下生成一个记录了运行结果XML文件。

Unity暂时还没有通过单元测试统计代码覆盖率的功能,不过据说已经在做了。。

TeamCity配置

详细的配置流程没必要在这里废话,也就是介绍一下构建流水线:

  1. 通过执行Unity打包脚本,如果失败则终止执行
  2. 运行单元测试
  3. 复制包体到指定目录
  4. 执行SonarQube代码检测

关于构建触发时机,我的选择是手动触发和每天早上8点定时触发(无论是工作日还是休息日,早上8点我一定在睡觉233),并且如果当天没有提交任何代码,则不执行定时构建。

SonarQube配置

运行完Unity打包脚本之后,会自动生成出来sln文件,我们把这个sln交给SonarQubeScanner进行构建扫描,然后把扫描结果传到SonarQube服务器,我们就可以在网页上看到可视化的结果了。脚本如下:

1
2
3
4
5
6
@set ver="a.b.c"
@set host="http://192.168.xxx.xxx:9000"

SonarScanner.MSBuild.exe begin /v:%ver% /k:"CountryRailway" /d:sonar.host.url=%host% /d:sonar.login="LoginToken"
MsBuild.exe /t:Rebuild CountryRailway.sln
SonarScanner.MSBuild.exe end /d:sonar.login="LoginToken"

最终效果

前面TeamCity的配置里有一步是“复制包体到指定目录”,把这个目录共享到局域网,我就可以在开发机上随时访问到最新的PC包了。

改进空间

现在存在一个问题,Unity的ECS配合BurstCompiler和il2cpp,总是容易在运行时出问题(显示不正常甚至直接crash),而构建过程是完全正常的,在编辑器中的运行效果也是完全正常的。而且关键在于我一般不回去特地打出PC包来去测试,开发的时候在编辑器里面跑着挺正常就OK了。结果就是某天心血来潮想跑一下PC包,结果一进场景就闪退了。。。

所以说还需要一个运行时的自动化测试流程,每次打包完成后,除了跑静态的单元测试,还要运行一遍运行时的功能测试,可以用命令行传参数启动游戏程序,参数存在的话就自动执行一系列操作,至少得保证能跑完流程不闪退。。。