Files
unity-builder/.github/workflows/build-tests-windows.yml
T
frostebite 10eeddbccf fix(ci): scope Library cache key to unityVersion/buildProfile, not just platform+targetPlatform
All StandaloneOSX matrix cells on macOS - three different Unity versions,
plus two duplicate 6000.0.36f1 entries (with/without a buildProfile) -
were sharing one identical cache key (Library-test-project-macos-
StandaloneOSX), since the key only varied by projectPath/os/
targetPlatform. Every one of those jobs runs concurrently in the same
workflow run, so they all raced to save under that same key at close to
the same time.

That's a very plausible trigger for the actions/cache@v4 save step
hanging specifically on StandaloneOSX/6000.0.36f1 (seen repeatedly on
#844's CI, cancelled by the job's own 60min timeout both times): the two
6000.0.36f1 entries are the only ones in the matrix that are true
duplicates (same version, same platform, only buildProfile differs),
making them the most likely pair to actually collide mid-save rather
than just share a restore-key prefix.

Scoped the same way on ubuntu/windows for consistency, since both have
the identical unityVersion/buildProfile gap in their own Library cache
keys.
2026-08-28 15:24:29 +01:00

189 lines
6.9 KiB
YAML

name: Builds - Windows
on:
workflow_dispatch:
push:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
buildForAllPlatformsWindows:
name: ${{ matrix.targetPlatform }} on ${{ matrix.unityVersion }}
runs-on: windows-2022
# See build-tests-mac.yml's matching comment - a per-step timeout doesn't
# bound an action's own implicit post-run cleanup step, only a job-level
# timeout does.
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
projectPath:
- test-project
unityVersion:
- 2021.3.45f2
- 2022.3.62f3
- 2023.2.22f1
targetPlatform:
- Android # Build an Android apk.
- StandaloneWindows64 # Build a Windows 64-bit standalone.
- WSAPlayer # Build a UWP App
- tvOS # Build an Apple TV XCode project
enableGpu:
- false
include:
# Additionally test enableGpu build for a standalone windows target
- projectPath: test-project
unityVersion: 2023.2.2f1
targetPlatform: StandaloneWindows64
enableGpu: true
- unityVersion: 6000.0.36f1
targetPlatform: StandaloneWindows64
- unityVersion: 6000.0.36f1
targetPlatform: StandaloneWindows64
buildProfile: 'Assets/Settings/Build Profiles/Sample Windows Build Profile.asset'
steps:
###########################
# Checkout #
###########################
- uses: actions/checkout@v4
with:
lfs: true
###########################
# Cache #
###########################
- uses: actions/cache@v4
with:
path: ${{ matrix.projectPath }}/Library
key: Library-${{ matrix.projectPath }}-windows-${{ matrix.targetPlatform }}-${{ matrix.unityVersion }}-${{ matrix.buildProfile }}
restore-keys: |
Library-${{ matrix.projectPath }}-windows-
Library-
###########################
# Set Scripting Backend #
###########################
- name: Set Scripting Backend To il2cpp
run: |
Move-Item -Path "./test-project/ProjectSettings/ProjectSettingsIl2cpp.asset" -Destination "./test-project/ProjectSettings/ProjectSettings.asset" -Force
###########################
# Docker Readiness #
###########################
- name: Ensure Docker daemon is ready
timeout-minutes: 2
shell: powershell
run: |
$maxRetries = 10
$retryDelay = 6
for ($i = 0; $i -lt $maxRetries; $i++) {
$svc = Get-Service docker -ErrorAction SilentlyContinue
if ($svc -and $svc.Status -eq 'Running') {
docker version 2>$null
if ($LASTEXITCODE -eq 0) {
Write-Host "Docker is ready."
exit 0
}
}
if ($svc -and $svc.Status -eq 'Stopped') {
Write-Host "Docker service stopped, attempting to start..."
Start-Service docker -ErrorAction SilentlyContinue
}
Write-Host "Waiting for Docker daemon (attempt $($i+1)/$maxRetries)..."
Start-Sleep -Seconds $retryDelay
}
Write-Error "Docker daemon did not start within $($maxRetries * $retryDelay) seconds"
exit 1
###########################
# Build #
###########################
- name: Build
uses: ./
id: build-1
continue-on-error: true
timeout-minutes: 30
env:
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
with:
buildName: 'GameCI Test Build'
projectPath: ${{ matrix.projectPath }}
unityVersion: ${{ matrix.unityVersion }}
targetPlatform: ${{ matrix.targetPlatform }}
buildProfile: ${{ matrix.buildProfile }}
enableGpu: ${{ matrix.enableGpu }}
customParameters: -profile SomeProfile -someBoolean -someValue exampleValue
allowDirtyBuild: true
# We use dirty build because we are replacing the default project settings file above
- name: Sleep for Retry
if: ${{ steps.build-1.outcome == 'failure' }}
run: |
Start-Sleep -s 120
- name: Build Retry 1
uses: ./
id: build-2
continue-on-error: true
timeout-minutes: 30
if: steps.build-1.outcome == 'failure'
env:
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
with:
buildName: 'GameCI Test Build'
projectPath: ${{ matrix.projectPath }}
unityVersion: ${{ matrix.unityVersion }}
targetPlatform: ${{ matrix.targetPlatform }}
enableGpu: ${{ matrix.enableGpu }}
customParameters: -profile SomeProfile -someBoolean -someValue exampleValue
allowDirtyBuild: true
# We use dirty build because we are replacing the default project settings file above
- name: Sleep for Retry
if: ${{ steps.build-1.outcome == 'failure' && steps.build-2.outcome == 'failure' }}
run: |
Start-Sleep -s 240
- name: Build Retry 2
uses: ./
id: build-3
timeout-minutes: 30
if: ${{ steps.build-1.outcome == 'failure' && steps.build-2.outcome == 'failure' }}
env:
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
with:
buildName: 'GameCI Test Build'
projectPath: ${{ matrix.projectPath }}
unityVersion: ${{ matrix.unityVersion }}
targetPlatform: ${{ matrix.targetPlatform }}
enableGpu: ${{ matrix.enableGpu }}
customParameters: -profile SomeProfile -someBoolean -someValue exampleValue
allowDirtyBuild: true
# We use dirty build because we are replacing the default project settings file above
###########################
# Upload #
###########################
- uses: actions/upload-artifact@v4
with:
name:
Build ${{ matrix.targetPlatform }} on Windows (${{ matrix.unityVersion }})${{ matrix.enableGpu && ' With
GPU' || '' }}${{ matrix.buildProfile && ' With Build Profile' || '' }}
path: build
retention-days: 14