GitHub Actions × Unity3D 持续交付实践
期末考完回到家了,很庆幸这学期又没有挂科。从今以后就是不挂科的大茄子了! 在校备考这段时间,收到一条关于 Asteroid 的 issue #3,说实话挺气的。开源无可避免地会遇到伸手党或者不愿自己尝试的人,作为开发者只能被动地把软件做得尽可能简单,来减少他们提问题的机会。 每当遇到不看文档不动手直接上来问的,我都会想起下面这则笑话:
软件工程师努力设计出最大最好的连白痴都会使用的程序;而宇宙在拼命制造最大最好的白痴。到目前为止,宇宙是胜利者。
关于 Asteroid
Asteroid 是我给 Cardinal 平台搭配上的一个实时攻击态势大屏。使用 Unity3D + C# 开发,现已开源在 GitHub。在配好 GitHub Actions 之前,用户是通过 clone 代码到本地,再在本地使用 Unity 2019.1.0f2 打开,自行编译打包。然而一个 Unity 大小高达几十 Gb,对于只是想进行编译而不二次开发的用户来说是个很大的麻烦。因此 Release 发版时的自动编译打包很有必要。
本文将从 Asteroid 项目的实践经历,来讲述使用 GitHub Actions 实现 Unity3D 项目的编译打包。
申请 Unity Licnese
我们将使用 webbertakken/unity-builder
这个 Action 模块来编译 Unity 项目,其实现原理是使用了 gableroux/unity3d
这个 Docker 镜像。其去除了 Unity 的图形化界面,只含有一个 Unity 命令行,可以执行 Unity 相关命令。
但其本身还是一个 Unity 软件的客户端,因此需要使用 Unity 许可证进行激活才能使用。
我在本地电脑上进行 Unity 开发时,是通过 Unity Hub 自动获取许可证。Unity 许可证是与机器的硬件 ID 与 Unity 版本相绑定的。因此如果我们想在 GitHub Actions 上运行 Unity,则需要使用 GitHub Actions 机器硬件 ID 所对应的许可证进行激活。
而所有的 GitHub Actions 虚拟机都拥有相同的硬件 ID,因此我们只需要触发 GitHub Actions 在它的机器上生成 Unity 许可证即可。
GitHub 新建一个 Repository,随便起个名字,比如:unity-activation-file
。在仓库目录下新建文件.github/workflow/activation.yml
编写一个 GitHub Actions 用于生成许可证。
name: Acquire activation file
on: [push]
jobs:
activation:
name: Request manual activation file 🔑
runs-on: ubuntu-latest
steps:
# Request manual activation file
- name: Request manual activation file
id: getManualLicenseFile
uses: webbertakken/unity-request-manual-activation-file@v1.1
with:
unityVersion: 2019.1.0f2
# Upload artifact (Unity_v20XX.X.XXXX.alf)
- name: Expose as artifact
uses: actions/upload-artifact@v1
with:
name: ${{ steps.getManualLicenseFile.outputs.filePath }}
path: ${{ steps.getManualLicenseFile.outputs.filePath }}
push 上去后就会触发该 Actions 运行。运行结束后我们可以在 Artifacts 下载到形如Unity_v2019.1.0f2.alf
的文件。这就是我们接下来网页端手动激活需要提供的文件。
访问 https://license.unity.cn/manual 进行手动激活。
.alf
文件,Next 之后便可以下载得到Unity_v2019.x.ulf
文件,这就是我们所需要的 Unity 许可证。保存好它!编写 GitHub Actions
在你的 Unity 项目仓库下新建文件.github/workflows/build.yml
:
name: Build project
on:
release:
types: [published]
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
jobs:
buildForSomePlatforms:
name: Build for ${{ matrix.targetPlatform }} on version ${{ matrix.unityVersion }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
buildName:
- Asteroid
projectPath:
- ./
unityVersion:
- 2019.1.0f2
targetPlatform:
- StandaloneOSX # Build a macOS standalone (Intel 64-bit).
- StandaloneWindows # Build a Windows standalone.
- StandaloneWindows64 # Build a Windows 64-bit standalone.
- StandaloneLinux64 # Build a Linux 64-bit standalone.
steps:
- uses: actions/checkout@v2
with:
lfs: true
- uses: webbertakken/unity-builder@v1.1
with:
buildName: ${{ matrix.buildName }}
projectPath: ${{ matrix.projectPath }}
unityVersion: ${{ matrix.unityVersion }}
targetPlatform: ${{ matrix.targetPlatform }}
- uses: actions/upload-artifact@v1
with:
name: Build
path: build
- name: Zip Binary
run: zip -r Asteroid_${{ matrix.targetPlatform }}.zip build/${{ matrix.targetPlatform }}/*
- name: Upload Release Asset
id: upload-release-asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: ./Asteroid_${{ matrix.targetPlatform }}.zip
asset_name: Asteroid_${{ matrix.targetPlatform }}.zip
asset_content_type: application/zip
这里有几点需要注意一下:
- 在项目 Secrets 下添加
UNITY_LICENSE
,内容为Unity_v2019.x.ulf
文件的内容;添加GH_TOKEN
,内容为你的 GitHub Token。不知道 GitHub 抽了什么风,key 里面不能带 GITHUB,因此只能写成 GH - 注意
unityVersion
版本号填写正确,与你申请的 Unity 许可证时的版本相同。 - targetPlatform 为编译的目标平台,我这里只有 Windows 32/64、macOS、Linux 四种,更多平台参见: https://github.com/webbertakken/unity-builder/blob/master/src/model/platform.js#L7
- 最后我是直接将文件 zip 打包放到 Release 里了(注意修改下我的 zip 文件名),你也可以选择只上传到 Artifact。
对于 Asteroid,每个平台的编译时间大约在 6 分钟左右。这已经很不错了。
由于操作系统的特殊性,对于 Linux、macOS 系统,执行二进制文件前需要chmod +x
赋予执行权限。
macOS:chmod +x [PATH-TO-ARTIFACT]/StandaloneOSX/StandaloneOSX.app/Contents/MacOS/*
,详见unity-builder #77。
最后再说几句
Cardinal 以及其附属的项目,我到现在已经维护了大半年了。这半年来,收获了不少,也认识了很多人。 在 Cardinal README 的下方,明确写了禁止用于商业用途。但最近听说有公司因为 Cardinal 使用了 Apache 协议,因此认为可以商业使用。关于补充协议是否有效这些我也不懂。这件事说白了其实就是我开源的东西被别人反手一波几万拿去卖了恰烂钱。😒
嘛,这项目说白了也不是啥高精尖的技术,最初开源也只是想能多交朋友。这波是朋友没交几个,反而自添烦恼。😅
喜欢这篇文章?为什么不打赏一下呢?