top of page

每月一千次构建,而且一次都不花钱 ⚙️

作家相片: Marcel Dütscher
Marcel Dütscher
7月26日
讀畢需時 3 分鐘

先更正一件事。这篇文章的第一版声称,我们的 GitHub 构建分钟数用完了,被迫升级到 Pro 账号。这是错的,而且只要看一眼文档就能弄清楚:对公开仓库来说,GitHub 的构建分钟数是免费的。产物和缓存也一样。我们的仓库从五月底起就是公开的,所以我们从来没有为任何一分钟付过钱,以后也不会。与其悄悄改掉文字,我们宁愿重写一遍,告诉你们测量到底显示了什么。结果比错误的版本有趣得多。


先猜测,后查看。起因是一个晚上,一个写好的拉取请求摆在浏览器里,却没有触发任何检查。没有绿色对勾,只有沉默。我们想到了最显而易见的解释:“额度用完了”,于是开了一个 Pro 账号。之后一切又跑起来了,似乎证实了这个理论。其实并没有:沉默另有原因(GitHub 在那一刻没法和主分支干净地合并的拉取请求,不会启动任何检查)。后来我们查询了每一次运行的计费数据。对每一次运行、每一种操作系统,答案都是:计费时间 = 0 毫秒。用订阅来支持一个平台完全没问题,但作为对这个仓库的解释,它站不住脚。


真实的是:这套机器变大了。每个拉取请求都会启动一个小工厂:整个服务器被构建并运行它的测试套件,代码检查和代码分析把它过一遍,CodeQL 搜寻安全漏洞,还会生成游戏服务器、门户、WorldHost 和 AI 后端的 Docker 镜像。一次发布还会加上客户端的 Windows、Linux 和 macOS 版本,以及给浏览器游戏用的 WebGL 版本。从五月底到现在,这加起来是 1,723 次构建运行,仅七月就有 1,092 次,四周里合并了 131 个拉取请求。没错,最近的激增确实和 AI 有关 😉:这个项目是 100% 在 AI 协助下开发的,订阅升级后,同时发生的事情就是更多。只不过这里的货币不是钱,而是等待时间。


等待时间花在哪里。八天内的测量结果:普通的检查运行(CI)379 分钟,CodeQL 安全分析 230 分钟,发布构建 126 分钟,剩下的是零头。一次发布大约要花 110 分钟的计算时间,分布在 WebGL(31.6)、Docker 镜像(19.4)、macOS(13.7)、Linux(13.7)、大型测试关卡(12.1)、Windows(10.9)和打包(7.2)上。这就是“做完了”到“你能安装了”之间的时间。


现在说说真正稀缺的东西:缓存。为了让构建不用每次都从零开始,GitHub 会保存中间结果,而这方面每个仓库只有 10 GB,不管你有多公开。我们的目前有 5.3 GB,共 63 个条目。问题出在分布上:大约三分之二是 Docker 的中间层,每次运行都会重新上传,它们挤掉了本来最有帮助的东西。这才是真正的瓶颈,世界上没有哪种订阅能帮你绕过去。


最棒的发现是一个真正的 bug。构建时,Unity 会创建一个巨大的中间文件夹(Library),重复利用它能省下好几分钟。测量发现:对 Windows、Linux 和 macOS 来说,这个文件夹从来没有被保存过,构建任务老老实实地尝试恢复它,可从来没有人写入过它。而且 Windows 构建是唯一一个缓存键里没有平台标记的。结果是:它下载了 1.7 GB 的 WebGL 中间状态,Unity 又尽职地把它们全扔掉,再重新导入一切。日志里白纸黑字:资源导入花了 257 秒,而缓存命中时是 85 秒。每次发布白白浪费近九分钟,只因为键里少了一个词。


还发现了什么。我们的测试套件在每个发出去的提交上会运行三次(在拉取请求里、合并后,以及发布时再跑一次)。CodeQL 在每个拉取请求上检查三种语言,尽管它甚至不是必需的检查。.NET 软件包的缓存完全没有。明明只为一种处理器架构构建,却还设置了模拟其他处理器架构的模拟器。还有 7.4 GB 的旧构建产物按默认的 90 天保留期堆在那里。没有哪一项很严重,加在一起却是相当可观的一块生命。


教训和我们的服务器当年教给我们的一样。当时我们测量发现,被占用的内存有一半根本不是给游戏用的,而是给了 Docker 和监控。这次更尴尬:我们假设了一张根本不存在的账单,还没查看就付了钱。测量,不要猜测,这句话看来要到你真正把它内化了才算数。清理工作已经计划好了,但还没做;等做完了,我们会告诉你们换来了什么。🚀

最新文章

查看全部
为什么新版本叫 2026.7.19,而不是 0.9.2 🗓️

今天更新的人,会从 0.9.1 版本一下跳到 2026.7.19。这看起来像是笔误,其实是一个刻意的决定:我们改变了版本号方案,从“语义化”版本改成了基于日期的版本(年.月.序号)。原因如下。 旧方案回答的是没人问的问题。语义化版本(0.9.1、1.2.3 ……)来自软件库的世界。在那里它很棒:第一个数字承诺“不会破坏任何东西”,第二个承诺“只有新增”,第三个承诺“只有修复”。而游戏不对任何人做这

 
 
大扫除:我们终于把 GitHub 的缓存用对了 🧹

在上一篇技术文章里,我们测量了构建和检查流水线到底花了什么:不是钱,而是等待时间和存储空间。那篇文章的结尾是“清理工作已经计划好,但还没完成”。结果比预想的快:从今天中午起,它已经进入主分支了。下面是数字。 先看结果。我们仓库的缓存用量,从 63 个条目共 5.32 GB,降到了 13 个条目共 2.46 GB。以前每个拉取请求都要跑的 C# 安全分析,现在在那里只需要 4 秒,而不是 4 分半,

 
 
SignPath 说了不:我们的 Windows 版本暂时还是未签名

几天前,我们在博客里告诉过你们,我们向 SignPath Foundation 的免费开源计划申请了给 Windows 安装程序用的代码签名证书。现在答复来了,是拒绝。这个开发日志不只是用来庆祝胜利的,也是用来诚实地讲述这样一个项目真实的样子,所以这个消息也该写在这里。 简单回顾一下:这是怎么回事?没有签名的 Windows 程序在第一次启动时会触发 SmartScreen 警告“Windows

 
 

留言


這篇文章不開放留言。請連絡網站負責人了解更多。
bottom of page