我是一名游戏程序员,我不愿意做一些无聊的事情,从而提高了工作效率。
游戏开发有很多无聊的工作要做,因此按照乔纳森·布洛(Jonathan Blow)所说的那样优化生活的多年时间,意味着您可以花更多的时间在实际喜欢的事情上。
我喜欢玩游戏,也喜欢制作游戏,我只是不喜欢从计算机上获取游戏代码并将其打包为可以在iPhone上运行的形式所需的工作。
这个过程中特别痛苦的部分始终是有人需要将Apple Universal Device Identifier(苹果通用设备标识符)或UDID(简称为UDID)附加到游戏上以便在其设备上对其进行测试。 更新UDID通常是一个漫长而琐碎的过程,在此过程中,如果您做对了一切,那么游戏将在目标设备上正常运行,如果做错了,则可能要花一个小时来回溯并搜索隐秘的错误消息。
我们首先尝试了Unity Cloud Build,但是构建时间太不确定了,我们无法使用最新的Unity修补程序版本,但是严格来说,自动上传到HockeyApp仍然需要使用外部服务器来进行下载完成后。 由于所有游戏和应用程序的需求都不尽相同,因此很难将所有内容包装在一个系统中并整体共享,但是也许可以通过鸟瞰我为使我们的游戏《社交足球》自动生成而做的工作希望可以节省一些时间。
从轨道上核对整个站点,这是确保的唯一方法
现在,我不想只是减少或加快这项工作。 这种无意识的按钮混用浪费了时间,我想完全消除它,以便我可以继续开发有趣的部分。

我们使用Slack进行大多数团队沟通。 我在IRC上花费了超过二十年的时间,所以即使在大多数公司文化中,Slack在某些方面对我来说都是很熟悉的。
就像IRC在聊天频道上以机器人程序形式出现许多自主脚本一样,这种方法也适用于Slack。 第一步是创建一个定制的Slack集成来处理UDID,并将其传递给服务器。

当Slack自定义命令在客户端上运行时,客户端将其传递给Slack服务器,Slack服务器又将自定义的Webhook(即用户定义的HTTP回调)发送到构建服务器。 由于我们的开发团队很小,因此不必在云中设置昂贵的构建服务器,在这种情况下,该服务器只是我在家庭办公室中的台式机。 该IP是通过noip.com分配的免费动态IP。
由于iOS版本仅在Mac上可以实用,并且Apple的台式机在3D加速和VR功能方面远远落后,因此家用计算机运行Windows 10并带有OSX的VMWare虚拟机。 在虚拟机中安装OSX时有些麻烦,但是您始终可以使用Hackintosh或实际的Mac来完成这项工作。

服务器上的实际构建是通过每五分钟轮询SVN来触发的,但是与其直接启动构建,不是直接启动构建,而是首先通过在为Apache服务器配置的虚拟主机上运行的简单PHP脚本来获取Slack消息。 要接收传入的Webhook消息,必须为Apache服务器配置有效的SSL证书。 过去这很痛苦,幸运的是,现在有免费的提供程序和诸如certbot之类的工具使整个事情变得容易得多。

PHP脚本对Slack请求参数进行了一些基本验证,将新的UDID存储在device.txt文件中,该文件的格式遵循Apple的规定,即通过上传纯文本文件一次添加多个UDID号。 然后,脚本使用CURL将消息发送回Slack,以通知成功结果。 此时,脚本可以将文件保存在构建服务器可以在本地找到的文件中,但就我而言,我将devices.txt存储在由Assembla托管的SVN的项目根目录中。 我不是PHP的狂热者,但在这种情况下,它确实可以胜任工作,而其他曾经这样做过的人可以轻松地触发Slack通知。
超越无限
同时,该服务器正在运行Jenkins,这是一个用Java构建的开源持续集成系统,其中包含大量专用插件。 Jenkins配置为每5分钟检查一次SVN的更改,如果检测到更改,它将为当前五种构建类型中的每一种触发Jenkins项目。 该项目也可以设置为具有单个存储库文件夹的主要项目,而平台则作为子项目,但这目前看来是更有效的方法,因为Unity即使在更多磁盘空间上刻录内容也可以缓存内容。 该虚拟机当前可容纳80GB虚拟分区,这还不错。

每个Jenkins项目将首先收集所有必需的软件密钥和环境参数,然后将在项目的工作文件夹上执行SVN更新。 这样可以确保构建始终使用游戏中的最新数据。 在某些情况下,Unity可能无法进行增量构建,因此通常建议强制执行干净构建。
/Applications/Unity.app/Contents/MacOS/Unity -nographics -projectPath“ $ {WORKSPACE}” -buildNumber“ $ {SOCCER_BUILD_NUMBER}” -buildtarget ios -quit -batchmode -executeMethod BuildScript.PerformIOSBuild -logFile / dev / stdout
使用Unity3D Builder插件,Jenkins将在Unity中为每种构建类型调用一个构建脚本,以批处理模式启动Unity,且不启用任何图形。 这确实意味着发生故障时,视觉提示会受到限制,您可能正在对错误日志进行取证工作以找出发生的情况。

启动Unity的命令行包括一些关键位; 项目路径设置为Jenkins的WORKSPACE变量,并且使用方便的版本号插件生成内部版本号。 最后,在启动Unity批处理过程时,您需要将日志文件重定向到stdout,以便将其包含在Jenkins的其他输出中。 否则,输出将消失在空白中,从而导致一些隐秘的调试。 当时,没有记录logFile命令行参数,这给我带来了最初的困惑。 日志工作时,它们非常冗长 。

在Unity内部,构建过程由自定义构建脚本处理,以确保持续集成。 构建脚本(BuildScript.cs)也是SVN项目的一部分,因此我们可以将条件参数和变量注入到构建本身中,包括版本号,如果遇到Unity问题,则使用Android SDK和NDK根文件夹目录。 由于像SDK和NDK路径这样的首选项是在Unity中为每个用户存储和定义的,并且进程在Jenkins下运行,因此在以批处理模式运行时,这些路径将显示为空,并且该项目将无法构建。

此时,Unity还将通过BeeByte的便捷混淆器传递代码。 尽管混淆永远不能代替安全性,但是在运行Mono后端的平台上从Unity项目中提取代码确实不那么容易。 Unity将在内部使用其专有的IL2CPP将Unity字节码转换为大多数平台上的C ++,但Windows不可用,对于Android,您必须从项目设置中专门选择它。
包装好交付
Unity将处理该构建,并使用先前注入的路径直接生成一个调用Android SDK和NDK工具的APK,或者在iOS中生成一个Xcode项目文件,该文件使用egoXproject插件进行了少许自定义。
在为iOS构建时,不是直接调用Xcode,而是将Jenkins配置为启动Fastlane脚本,从而简化了与Apple系统的协作。 Fastlane是一个用Ruby编写的出色的开源工具。 我以前从未使用过Ruby语言,但是我在Fastlane方面的经验非常出色 。 Fastlane配置为执行诸如更新和下载证书以及驱动构建过程之类的操作。
Fastlane register_devices首先用于将devices.txt上传到服务器,以便UDID可以包括在配置概要文件中。 虽然Fastlane现在包括用于管理和分发UDID的创新性Fastlane匹配系统,但我现在不想设置Git存储库,因此我使用了一个小的Fastlane太空飞船脚本来自动更新配置文件,以仅包括UDID。刚刚添加。

Fastlane然后将适当的配置文件注入Xcode项目,并使用Fastlane Gym启动构建。 这样,内部版本就已经包括了刚添加的设备的UDID。
Gym会使用适当的参数触发Xcode命令行生成,打包项目并使用Apple的CodeSign工具对您的证书进行签名。 在我们的案例中,CodeSign使用jenkins_keys.keychain中的证书以及Fastlane从Apple开发人员站点下载的配置文件。 如果您在Apple的开发站点上拥有企业帐户,则可以为Jenkins添加单独的用户,或者可以让Jenkins和Fastlane使用自己的开发人员证书。 无论哪种情况,您都可能想要更改适当的钥匙串中的超时值,以使其在整个构建和打包过程中始终保持活动状态,因为Unity有时可能会花费比分配的默认时间(五分钟)更长的时间。 如果钥匙串锁或CodeSign不能访问它,您将得到一个相当隐秘的错误,“不允许用户交互”,实际上只是说詹金斯会要求您使用密码来解锁钥匙串,但不能,因为它正在运行不允许交互的批处理过程。
就我个人而言,这是难题中最艰难的部分之一。 如果我更熟悉OS X,可能会有所帮助,而我不是。

在Gym生成有效的IPA后,Fastlane曲棍球会将文件上传到我们的HockeyApp帐户。 HockeyApp将根据通过构建脚本通过较早版本注入的版本号来更新分布式构建,从而允许集成的HockeySDK提醒用户可用的新版本,或通过电子邮件或Slack发送可选通知。 除了HockeyApp,Fastlane还支持与Testflight集成,而Testflight现在是Apple的一部分。

只要构建完成并上载,构建服务器上的Jenkins Slack插件就会配置为将消息发送回Slack,然后将其转发到我们的团队Slack渠道之一。

所需步骤摘要
- 创建自定义Slack集成以重定向到动态IP
- 配置Apache虚拟主机以运行PHP和Jenkins,使用certbot设置有效的SSL证书
- 创建自定义脚本以响应松弛消息并存储UDID
- 创建用于iOS和Android构建的Jenkins项目(Jenkins GUI)
- 为iOS构建创建Fastlane项目(“ fastfile”)以简化配置
- 配置Jenkins使用Fastlane轮询SVN并更新证书
- 为Unity创建自定义BuildScript.cs以注入变量
- 配置Fastlane以使用Gym / Xcode构建项目
- 配置Fastlane以使用HockeyApp上传IPA

虽然很难说不必为游戏手动创建和配置iOS版本可以节省总时间,但您无需知道如何按一下按钮就可以知道该过程将可以正常工作 ,从而让您高枕无忧巨大的 。 除了虚拟机和硬件本身之外,所使用的工具都是免费和开放源代码的,而我大部分时间都是第一次使用它们。 如果我能弄清楚,可以。 如果不能的话,总会有Google和Stack Overflow。
另外,能够通过在iPhone的Slack客户端中输入UDID编号来共享预配置的版本,并在不到15分钟的时间内在HockeyApp上自动使用该版本,这是一件很巧妙的事情。
詹金斯(Jenkins)还有很多我可以做的事情,但我真的只想继续做更重要的事情,例如为《明智足球》(Sensible Soccer)建立精神上的续集。 🙂
搞定了? 我是否错过了一些显而易见的事情,或者没有足够详细地描述其中的一部分? 让我知道,因为不断发展的构建系统始终是一个移动的目标,并且每个新平台都有其自己的怪癖。