Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
167 changes: 13 additions & 154 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
name: Continuous integration

# The Unity lane: Edit and Play Mode tests and player builds. The pure assemblies run in fast-lane.yml on every push.
# The Unity lane of unity.yml, behind a gate that skips it on main when the same files already passed. The pure
# assemblies run in fast-lane.yml on every push.
on:
pull_request:
paths-ignore:
Expand Down Expand Up @@ -28,19 +29,12 @@ permissions:
# The gate looks for the marker an earlier run left on the same files.
actions: read

# A Personal license needs UNITY_LICENSE, UNITY_EMAIL and UNITY_PASSWORD; a Pro license UNITY_SERIAL instead of the first.
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}

jobs:
# A squash merge makes a new commit, but its files are exactly the ones the pull request's last run tested, as long as
# main didn't move in between. A push whose file tree already passed skips the jobs below, and the run still succeeds;
# any other push, such as one combining two pull requests, runs them all.
# main didn't move in between. A push whose file tree already passed skips the Unity lane, and the run still succeeds;
# any other push, such as one combining two pull requests, runs it all.
gate:
name: Look for a run that passed on the same files
name: Check for an earlier pass
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
Expand All @@ -64,154 +58,19 @@ jobs:
echo "is-verified=true" >> "$GITHUB_OUTPUT"
fi

tests:
name: Tests on ${{ matrix.unityVersion }}
# The jobs live in their own workflow, so a skipped lane shows as one named check; a skipped matrix job would show
# its name unexpanded, since GitHub evaluates a job's if before its matrix.
unity:
name: Unity
needs: gate
if: needs.gate.outputs.is-verified != 'true'
runs-on: ubuntu-latest
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
unityVersion:
- 2022.3.62f3
- 6000.5.11f1
steps:
- name: Free disk space for the Unity image
uses: jlumbroso/free-disk-space@ceedf095f4ec1a097402bc6bd80831f2e1a6fde6 # v2.0.0
with:
large-packages: false

- name: Check out the repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

# Without it, Unity takes the project for a new one and adds its template packages to the manifest. Unity 6 also
# refuses to open a project without an Assets folder, which git doesn't keep while it's empty.
- name: Set the Unity version of the project
env:
UNITY_VERSION: ${{ matrix.unityVersion }}
run: |
mkdir -p UnityProject/ProjectSettings UnityProject/Assets
printf 'm_EditorVersion: %s\n' "$UNITY_VERSION" > UnityProject/ProjectSettings/ProjectVersion.txt

- name: Restore the Library folder
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: UnityProject/Library
key: Library-tests-${{ matrix.unityVersion }}-${{ hashFiles('UnityPackage/**', 'UnityProject/**') }}
restore-keys: Library-tests-${{ matrix.unityVersion }}-

- name: Run the edit and play mode tests
uses: game-ci/unity-test-runner@32e57712352b500e17974b245a6dce9e11a73213 # v4.4.0
env:
# Code coverage crashes play mode tests on Unity 6, see game-ci/unity-test-runner#301. The action's
# coverageEnabled input passes --no-coverageEnabled, which the CLI rejects, so it's turned off here instead.
GAME_CI_COVERAGE_ENABLED: false
with:
unityVersion: ${{ matrix.unityVersion }}
cliVersion: v0.1.69
projectPath: UnityProject
testMode: all
githubToken: ${{ github.token }}
checkName: Test results on ${{ matrix.unityVersion }}

- name: Check that the package compiles without warnings
if: always()
run: |
warnings=$(grep -hs "warning CS" artifacts/*.log | grep -e "com.reromanlee.reactivelocalizer" -e "UnityPackage" | sort -u || true)
if [ -n "$warnings" ]; then
echo "$warnings"
echo "::error::The package compiled with warnings."
exit 1
fi

- name: Upload the test results and timings
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: Test results on ${{ matrix.unityVersion }}
path: artifacts

builds:
name: ${{ matrix.targetPlatform }} build on ${{ matrix.unityVersion }}
needs: gate
if: needs.gate.outputs.is-verified != 'true'
runs-on: ubuntu-latest
timeout-minutes: 90
strategy:
fail-fast: false
matrix:
include:
# Tier 1 platforms on the oldest and the newest supported Unity. TextMeshPro is its own package on 2022.3
# and part of uGUI on Unity 6; with it, the TextMeshPro sample compiles into every build.
- unityVersion: 2022.3.62f3
targetPlatform: WebGL
samplePackages: '{"com.unity.textmeshpro": "3.0.9", "com.unity.ugui": "1.0.0"}'
- unityVersion: 2022.3.62f3
targetPlatform: Android
samplePackages: '{"com.unity.textmeshpro": "3.0.9", "com.unity.ugui": "1.0.0"}'
- unityVersion: 6000.5.11f1
targetPlatform: WebGL
samplePackages: '{"com.unity.ugui": "2.0.0"}'
- unityVersion: 6000.5.11f1
targetPlatform: Android
samplePackages: '{"com.unity.ugui": "2.0.0"}'
# Tier 2 platforms, checked to build on the newest Unity.
- unityVersion: 6000.5.11f1
targetPlatform: iOS
samplePackages: '{"com.unity.ugui": "2.0.0"}'
- unityVersion: 6000.5.11f1
targetPlatform: StandaloneOSX
samplePackages: '{"com.unity.ugui": "2.0.0"}'
# This build also compiles the samples for Addressables, Unity Localization and VContainer. R3 stays out, since
# it needs DLLs from NuGet in Assets.
- unityVersion: 6000.5.11f1
targetPlatform: StandaloneLinux64
samplePackages: '{"com.unity.ugui": "2.0.0", "com.unity.addressables": "2.9.1", "com.unity.localization": "1.5.13", "jp.hadashikick.vcontainer": "https://github.com/hadashiA/VContainer.git?path=VContainer/Assets/VContainer#1.18.0"}'
steps:
- name: Free disk space for the Unity image
uses: jlumbroso/free-disk-space@ceedf095f4ec1a097402bc6bd80831f2e1a6fde6 # v2.0.0
with:
large-packages: false

- name: Check out the repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

# Without it, Unity takes the project for a new one and adds its template packages to the manifest.
- name: Set the Unity version of the project
env:
UNITY_VERSION: ${{ matrix.unityVersion }}
run: |
mkdir -p UnityProject/ProjectSettings UnityProject/Assets
printf 'm_EditorVersion: %s\n' "$UNITY_VERSION" > UnityProject/ProjectSettings/ProjectVersion.txt

# Leaves only built-in modules, the local package and what the samples need, so a build never waits on the
# registry for test-only packages.
- name: Swap the test-only packages for the samples' ones
env:
SAMPLE_PACKAGES: ${{ matrix.samplePackages }}
run: |
manifest=UnityProject/Packages/manifest.json
jq --argjson packages "$SAMPLE_PACKAGES" 'del(.dependencies["com.unity.test-framework.performance"]) | del(.testables) | .dependencies += $packages' "$manifest" > manifest.tmp
mv manifest.tmp "$manifest"

- name: Add the package samples to the project
run: cp -r UnityPackage/Samples~ UnityProject/Assets/Samples

# Only checks that the player builds; nothing is uploaded or released.
- name: Build the Quick Start sample
uses: game-ci/unity-builder@adaf7cd8f42fd48fbbf2d4f5f67ca30d87f819f1 # v5.0.1
with:
unityVersion: ${{ matrix.unityVersion }}
targetPlatform: ${{ matrix.targetPlatform }}
projectPath: UnityProject
buildMethod: reromanlee.ReactiveLocalizer.ContinuousIntegration.PlayerBuild.Build
versioning: None
uses: ./.github/workflows/unity.yml
secrets: inherit

# Leaves the marker the gate looks for, named after the tested file tree, once every job passed.
passed:
name: Mark the files as passed
needs: [tests, builds]
name: Record this pass
needs: unity
runs-on: ubuntu-latest
timeout-minutes: 5
# A missing marker only means main runs everything again, so it never fails the run.
Expand Down
153 changes: 153 additions & 0 deletions .github/workflows/unity.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
name: Unity

# Edit and Play Mode tests and player builds on every supported Unity, called by continuous-integration.yml.
on:
workflow_call:

# A Personal license needs UNITY_LICENSE, UNITY_EMAIL and UNITY_PASSWORD; a Pro license UNITY_SERIAL instead of the first.
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}

jobs:
tests:
name: Tests on ${{ matrix.unityVersion }}
runs-on: ubuntu-latest
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
unityVersion:
- 2022.3.62f3
- 6000.5.11f1
steps:
- name: Free disk space for the Unity image
uses: jlumbroso/free-disk-space@ceedf095f4ec1a097402bc6bd80831f2e1a6fde6 # v2.0.0
with:
large-packages: false

- name: Check out the repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

# Without it, Unity takes the project for a new one and adds its template packages to the manifest. Unity 6 also
# refuses to open a project without an Assets folder, which git doesn't keep while it's empty.
- name: Set the Unity version of the project
env:
UNITY_VERSION: ${{ matrix.unityVersion }}
run: |
mkdir -p UnityProject/ProjectSettings UnityProject/Assets
printf 'm_EditorVersion: %s\n' "$UNITY_VERSION" > UnityProject/ProjectSettings/ProjectVersion.txt

- name: Restore the Library folder
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: UnityProject/Library
key: Library-tests-${{ matrix.unityVersion }}-${{ hashFiles('UnityPackage/**', 'UnityProject/**') }}
restore-keys: Library-tests-${{ matrix.unityVersion }}-

- name: Run the edit and play mode tests
uses: game-ci/unity-test-runner@32e57712352b500e17974b245a6dce9e11a73213 # v4.4.0
env:
# Code coverage crashes play mode tests on Unity 6, see game-ci/unity-test-runner#301. The action's
# coverageEnabled input passes --no-coverageEnabled, which the CLI rejects, so it's turned off here instead.
GAME_CI_COVERAGE_ENABLED: false
with:
unityVersion: ${{ matrix.unityVersion }}
cliVersion: v0.1.69
projectPath: UnityProject
testMode: all
githubToken: ${{ github.token }}
checkName: Test results on ${{ matrix.unityVersion }}

- name: Check that the package compiles without warnings
if: always()
run: |
warnings=$(grep -hs "warning CS" artifacts/*.log | grep -e "com.reromanlee.reactivelocalizer" -e "UnityPackage" | sort -u || true)
if [ -n "$warnings" ]; then
echo "$warnings"
echo "::error::The package compiled with warnings."
exit 1
fi

- name: Upload the test results and timings
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: Test results on ${{ matrix.unityVersion }}
path: artifacts

builds:
name: ${{ matrix.targetPlatform }} build on ${{ matrix.unityVersion }}
runs-on: ubuntu-latest
timeout-minutes: 90
strategy:
fail-fast: false
matrix:
include:
# Tier 1 platforms on the oldest and the newest supported Unity. TextMeshPro is its own package on 2022.3
# and part of uGUI on Unity 6; with it, the TextMeshPro sample compiles into every build.
- unityVersion: 2022.3.62f3
targetPlatform: WebGL
samplePackages: '{"com.unity.textmeshpro": "3.0.9", "com.unity.ugui": "1.0.0"}'
- unityVersion: 2022.3.62f3
targetPlatform: Android
samplePackages: '{"com.unity.textmeshpro": "3.0.9", "com.unity.ugui": "1.0.0"}'
- unityVersion: 6000.5.11f1
targetPlatform: WebGL
samplePackages: '{"com.unity.ugui": "2.0.0"}'
- unityVersion: 6000.5.11f1
targetPlatform: Android
samplePackages: '{"com.unity.ugui": "2.0.0"}'
# Tier 2 platforms, checked to build on the newest Unity.
- unityVersion: 6000.5.11f1
targetPlatform: iOS
samplePackages: '{"com.unity.ugui": "2.0.0"}'
- unityVersion: 6000.5.11f1
targetPlatform: StandaloneOSX
samplePackages: '{"com.unity.ugui": "2.0.0"}'
# This build also compiles the samples for Addressables, Unity Localization and VContainer. R3 stays out, since
# it needs DLLs from NuGet in Assets.
- unityVersion: 6000.5.11f1
targetPlatform: StandaloneLinux64
samplePackages: '{"com.unity.ugui": "2.0.0", "com.unity.addressables": "2.9.1", "com.unity.localization": "1.5.13", "jp.hadashikick.vcontainer": "https://github.com/hadashiA/VContainer.git?path=VContainer/Assets/VContainer#1.18.0"}'
steps:
- name: Free disk space for the Unity image
uses: jlumbroso/free-disk-space@ceedf095f4ec1a097402bc6bd80831f2e1a6fde6 # v2.0.0
with:
large-packages: false

- name: Check out the repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

# Without it, Unity takes the project for a new one and adds its template packages to the manifest.
- name: Set the Unity version of the project
env:
UNITY_VERSION: ${{ matrix.unityVersion }}
run: |
mkdir -p UnityProject/ProjectSettings UnityProject/Assets
printf 'm_EditorVersion: %s\n' "$UNITY_VERSION" > UnityProject/ProjectSettings/ProjectVersion.txt

# Leaves only built-in modules, the local package and what the samples need, so a build never waits on the
# registry for test-only packages.
- name: Swap the test-only packages for the samples' ones
env:
SAMPLE_PACKAGES: ${{ matrix.samplePackages }}
run: |
manifest=UnityProject/Packages/manifest.json
jq --argjson packages "$SAMPLE_PACKAGES" 'del(.dependencies["com.unity.test-framework.performance"]) | del(.testables) | .dependencies += $packages' "$manifest" > manifest.tmp
mv manifest.tmp "$manifest"

- name: Add the package samples to the project
run: cp -r UnityPackage/Samples~ UnityProject/Assets/Samples

# Only checks that the player builds; nothing is uploaded or released.
- name: Build the Quick Start sample
uses: game-ci/unity-builder@adaf7cd8f42fd48fbbf2d4f5f67ca30d87f819f1 # v5.0.1
with:
unityVersion: ${{ matrix.unityVersion }}
targetPlatform: ${{ matrix.targetPlatform }}
projectPath: UnityProject
buildMethod: reromanlee.ReactiveLocalizer.ContinuousIntegration.PlayerBuild.Build
versioning: None
Loading