Build #193
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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@v3 | |
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@v2 | |
# 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 | |
# 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@v2 | |
id: tests | |
env: | |
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} | |
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} | |
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} | |
with: | |
projectPath: ${{ matrix.projectPath }} | |
testMode: ${{ matrix.testMode }} | |
# 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 |