-
Notifications
You must be signed in to change notification settings - Fork 17
288 lines (243 loc) · 9.6 KB
/
main.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
name: Build
# specify which events will trigger the workflow
on:
# run workflow on push events on the development branch
# one can tell Actions to not run the pipeline
# by including [ci skip] or [no ci] in the commit message
push:
branches:
- 'develop'
# run workflow when a review for a PR is requested
pull_request:
types: [review_requested]
# allow to run the workflow manually
workflow_dispatch:
# run daily at 6am UTC
# idea: quickly spot issues with workflow/runner
# scheduled runs do not trigger deployment to steam
schedule:
- cron: 0 6 * * *
jobs:
# pulls source code
# tries to restore the cached library folder
# fetches user id of user running the workflow (needed later on)
setup:
name: Setup
runs-on: self-hosted
# very rarely, the cache download might get stuck
# if the download is not complete after 5 minutes, abort this step
env:
SEGMENT_DOWNLOAD_TIMEOUT_MINS: 5 # default = 10m
outputs:
# tells us if we got a cache hit or a cache miss
hit: ${{ steps.restore-cache.outputs.cache-hit }}
# the key of the cache
key: ${{ steps.restore-cache.outputs.cache-primary-key }}
# the uid of the runner
uid: ${{ steps.get_uid.outputs.uid }}
steps:
# retrieve uid of runner (needed later on)
- name: Get Actions user id
id: get_uid
run: |
actions_user_id=`id -u $USER`
echo $actions_user_id
echo "uid=$actions_user_id" >> $GITHUB_OUTPUT
# check out repo
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
# try to restore Library folder from cache
# by hashing all files in Assets/ Packages/ and ProjectSettins/
# we can determine if there has been a change to the project
# if the files are unchanged: restore cache
# if there has been a change: skip this step and save the cache later on
- name: Restore Cache
id: restore-cache
uses: actions/cache/restore@v3
with:
path: unity/Library
key: Library-${{ hashFiles('unity/Assets/**', 'unity/Packages/**', 'unity/ProjectSettings/**') }}
# build project for PC, VR and WebGL
build:
name: Build for ${{ matrix.maroonBuildTarget }}
runs-on: self-hosted
# before this job can run, the setup must be complete
needs: setup
# create job matrix
# runs job once for each build target
strategy:
# if fail-fast is set to true, the job will abort if one of the builds fail
fail-fast: false
matrix:
include:
- targetPlatform: StandaloneWindows64
maroonBuildTarget: PC
- targetPlatform: StandaloneWindows64
maroonBuildTarget: VR
- targetPlatform: WebGL
maroonBuildTarget: WebGL
steps:
- name: Build
uses: game-ci/unity-builder@v4
# environment vars needed by unity-builder to activate the unity license
# defined in the Actions Secrets in the repo settings
env:
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
with:
# run the custom build script
buildMethod: Maroon.Build.BuildPlayer.ActionsBuild
# with these params:
customParameters: -maroonBuildPath ../build -maroonBuildTarget ${{ matrix.maroonBuildTarget }}
# we must specify a target platform, build path, build name and project path for unity-builder
targetPlatform: ${{ matrix.targetPlatform }}
projectPath: unity
buildName: ${{ matrix.maroonBuildTarget }}
buildsPath: build
# run as host user or default root container user, should fix most permission issues on self-hosted runners
runAsHostUser: true
# if this is set to false, the job will fail if any file has changed since checkout
# since it is set to true, it will only raise a warning
allowDirtyBuild: true
# we want the repo to be in its original state before each build
- name: Restore Build Environment
shell: bash
run: |
git reset --hard
# store the library folder in the cache
# if the library folder has been retrieved from the cache during setup, this job is skipped
# as it has not changed
save-cache:
name: Save cache
runs-on: self-hosted
needs: [setup, build]
# only save the cache if we had a cache miss during setup
if: needs.setup.outputs.hit != 'true'
steps:
- name: Save Cache
uses: actions/cache/save@v3
with:
path: unity/Library
key: ${{ needs.setup.outputs.key }}
# execute playmode and editmode tests
test:
name: Run tests
runs-on: self-hosted
needs: [setup, build]
strategy:
# if fail-fast is set to true, the job will abort if one of the tests fail
fail-fast: false
matrix:
projectPath:
- unity
testMode:
- playmode
- editmode
steps:
- name: Test
uses: game-ci/unity-test-runner@v4
id: tests
env:
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
with:
projectPath: ${{ matrix.projectPath }}
no_output_timeout: 30m
testMode: ${{ matrix.testMode }}
# run as host user or default root container user, should fix most permission issues on self-hosted runners
runAsHostUser: true
# save test results to ./test-results/
artifactsPath: ./test-results/${{ matrix.testMode }}-results
# upload build output and test results to github
# also fixes file permissions
upload-artifacts:
name: Upload artifacts
runs-on: self-hosted
# we want to upload artifacts even if the tests fail
# if both build and test fail, we don't want to upload
needs: [setup, build, test]
if: ${{ success() || (needs.build.result == 'success' || needs.test.result == 'success') }}
steps:
# chown files to the user that was identified during setup
# this is necessary because actions executed through docker have root:root permissions
- name: Restore file ownership
uses: peter-murray/reset-workspace-ownership-action@v1
with:
user_id: ${{ needs.setup.outputs.uid }}
# get rid of empty StandaloneWindows64 folder created by the build action
# compress build folder for faster up- and download
- name: Compress build folder
run: |
rmdir build/StandaloneWindows64
zip -r build.zip build
# upload build.zip and the test results
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: MaroonArtifacts
path: |
build.zip
test-results
# if no files match the supplied path, fail job with error
if-no-files-found: error
# deploy VR and PC version to steam
# requires build, test and upload-artifact jobs to pass
# do not deploy during scheduled runs
deploy:
name: Deploy to Steam
runs-on: self-hosted
needs: [setup, build, test, upload-artifacts]
# we do not want to deploy if we are doing a scheduled run
# make sure that we are on the develop branch
if: |
github.ref_name == 'develop' &&
github.event_name != 'schedule' &&
needs.build.result == 'success' &&
needs.test.result == 'success' &&
needs.upload-artifacts.result == 'success'
steps:
# remove the WebGL directory so we do not accidentally publish it to steam
- name: Prepare deployment
run: rm -rf build/WebGL
# run steam-deploy
# requires steam account that has permissions to upload builds
# for the specified appId
- name: Deploy
uses: game-ci/steam-deploy@v3
with:
# username of the steam account used to upload
username: ${{ secrets.STEAM_USERNAME }}
# needed so we do not have to complete 2FA every time we deploy
# if the login fails, even though username and password have not changed
# it may be necessary to regenerate the config.vdf,
# base64 encode it and update the STEAM_CONFIG_VDF github secret
# https://game.ci/docs/github/deployment/steam#3-add-github-secrets
configVdf: ${{ secrets.STEAM_CONFIG_VDF}}
# appId of the application we are uploading to build for
appId: ${{ secrets.STEAM_APP_ID }}
# set build description to commit hash
buildDescription: CI/CD build ${{ github.sha }}
# path where steampipe looks for the build
rootPath: build
# path for depot1, relative form rootPath
# we only have 1 depot, so . is sufficient
depot1Path: .
# deploy to the development branch of the app
releaseBranch: development
# this job is needed because in some instances, there might be some leftover files
# in the working directory, that have funky (=root:root) permissions
# this is not a problem on ephemeral runners, but on self-hosted ones it is
# thus, we ensure that the working dir is clean before our next pipeline run
# this job must **ALWAYS** run
cleanup:
name: Cleanup
runs-on: self-hosted
needs: [test, build, upload-artifacts, save-cache, deploy]
if: ${{ always() }}
steps:
- name: Cleanup
uses: AutoModality/action-clean@v1