Skip to content

Commit 29da535

Browse files
Merge pull request #121 from PassivePicasso/tpk-improvements
TPK, Test, Warnings Improvements
2 parents 945db4e + 6815b57 commit 29da535

31 files changed

Lines changed: 999 additions & 124 deletions

.gitattributes

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Binary test fixtures are stored via Git LFS to keep the repo history lean.
2+
# CI checks these out with `lfs: true` (see .github/workflows/main.yml).
3+
*.tpk filter=lfs diff=lfs merge=lfs -text
4+
Tests/Editor/Fixtures/GlobalGameManagers/**/globalgamemanagers filter=lfs diff=lfs merge=lfs -text

.github/fixtures/FixtureBuilder.cs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// CI-only tooling — copied into a throwaway Unity project by
2+
// .github/workflows/generate-project-settings-fixtures.yml. NOT part of the
3+
// shipped package (it lives under .github/, outside any package assembly).
4+
//
5+
// Builds a minimal empty StandaloneLinux64 player and copies the
6+
// globalgamemanagers that the build produces into <project>/Fixture/, alongside a
7+
// fixture.json recording the exact editor version. The workflow then uploads that
8+
// folder as the per-version ProjectSettings import fixture.
9+
//
10+
// A globalgamemanagers is only ever emitted by an actual player build (no editor
11+
// API produces one at rest) and is pure engine/project settings, so an empty
12+
// project yields a clean, representative file with no game content and no
13+
// dependency on ThunderKit being present.
14+
15+
using System.IO;
16+
using System.Linq;
17+
using UnityEditor;
18+
using UnityEditor.SceneManagement;
19+
using UnityEngine;
20+
21+
public static class FixtureBuilder
22+
{
23+
// Entry point invoked via -buildMethod / -executeMethod from GameCI.
24+
public static void Build()
25+
{
26+
var exitCode = 1;
27+
try
28+
{
29+
exitCode = Run() ? 0 : 1;
30+
}
31+
catch (System.Exception e)
32+
{
33+
Debug.LogError($"[FixtureBuilder] Fixture generation threw: {e}");
34+
exitCode = 1;
35+
}
36+
EditorApplication.Exit(exitCode);
37+
}
38+
39+
static bool Run()
40+
{
41+
var version = Application.unityVersion;
42+
43+
// A build needs at least one scene; generate an empty one rather than
44+
// requiring any authored asset.
45+
var scene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
46+
const string scenePath = "Assets/_FixtureScene.unity";
47+
if (!EditorSceneManager.SaveScene(scene, scenePath))
48+
{
49+
Debug.LogError("[FixtureBuilder] Failed to save the temporary build scene.");
50+
return false;
51+
}
52+
53+
var buildDir = Path.Combine(Path.GetTempPath(), "fixturebuild");
54+
if (Directory.Exists(buildDir))
55+
Directory.Delete(buildDir, true);
56+
Directory.CreateDirectory(buildDir);
57+
58+
var options = new BuildPlayerOptions
59+
{
60+
scenes = new[] { scenePath },
61+
// The _Data folder (and thus globalgamemanagers) is named after this file.
62+
locationPathName = Path.Combine(buildDir, "fixture.x86_64"),
63+
target = BuildTarget.StandaloneLinux64,
64+
targetGroup = BuildTargetGroup.Standalone,
65+
options = BuildOptions.None,
66+
};
67+
68+
var report = BuildPipeline.BuildPlayer(options);
69+
if (report.summary.result != UnityEditor.Build.Reporting.BuildResult.Succeeded)
70+
{
71+
Debug.LogError($"[FixtureBuilder] Player build did not succeed: {report.summary.result}.");
72+
return false;
73+
}
74+
75+
var ggm = Directory
76+
.GetFiles(buildDir, "globalgamemanagers", SearchOption.AllDirectories)
77+
.FirstOrDefault();
78+
if (ggm == null)
79+
{
80+
Debug.LogError($"[FixtureBuilder] Build succeeded but no globalgamemanagers was found under {buildDir}.");
81+
return false;
82+
}
83+
84+
// Application.dataPath is <project>/Assets; the fixture goes next to the project
85+
// root so the workflow can pick it up regardless of the batchmode working dir.
86+
var outputDir = Path.GetFullPath(Path.Combine(Application.dataPath, "..", "Fixture"));
87+
if (Directory.Exists(outputDir))
88+
Directory.Delete(outputDir, true);
89+
Directory.CreateDirectory(outputDir);
90+
91+
File.Copy(ggm, Path.Combine(outputDir, "globalgamemanagers"), true);
92+
File.WriteAllText(
93+
Path.Combine(outputDir, "fixture.json"),
94+
"{\n \"unityVersion\": \"" + version + "\"\n}\n");
95+
96+
Debug.Log($"[FixtureBuilder] Wrote globalgamemanagers fixture for Unity {version} to {outputDir}.");
97+
return true;
98+
}
99+
}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
name: Generate ProjectSettings fixtures
2+
3+
# Manually-triggered, one-time (or occasional) generation of the per-Unity-version
4+
# globalgamemanagers fixtures consumed by ImportProjectSettingsTests. Each matrix
5+
# version builds a throwaway empty player, extracts the globalgamemanagers it
6+
# produced, and a final job commits them all (via Git LFS) under
7+
# Tests/Editor/Fixtures/GlobalGameManagers/<version>/.
8+
#
9+
# The regular test matrix (main.yml) never builds anything — it only consumes the
10+
# fixtures committed here.
11+
on:
12+
workflow_dispatch:
13+
14+
jobs:
15+
build:
16+
name: Build globalgamemanagers (Unity ${{ matrix.unity-version }})
17+
runs-on: ubuntu-latest
18+
strategy:
19+
fail-fast: false # one version failing must not cancel the others
20+
# Keep in sync with the test matrix in main.yml.
21+
matrix:
22+
unity-version: [
23+
"6000.5.0f1",
24+
"6000.4.5f1",
25+
"6000.3.11f1",
26+
"6000.2.15f1",
27+
"6000.1.9f1",
28+
"6000.0.53f1",
29+
"2022.1.24f1",
30+
"2020.3.48f1",
31+
"2019.4.40f1",
32+
"2018.4.36f1"
33+
]
34+
35+
steps:
36+
- name: Checkout
37+
uses: actions/checkout@v4
38+
39+
# Minimal empty project: just enough to build a player. ThunderKit is NOT
40+
# embedded — globalgamemanagers is engine/project settings, independent of any
41+
# installed package, so an empty project yields a clean, representative file
42+
# and avoids depending on ThunderKit compiling on every matrix version.
43+
- name: Scaffold empty build project
44+
run: |
45+
mkdir -p BuildProject/Assets/Editor
46+
mkdir -p BuildProject/ProjectSettings
47+
mkdir -p BuildProject/Packages
48+
49+
cp .github/fixtures/FixtureBuilder.cs BuildProject/Assets/Editor/FixtureBuilder.cs
50+
printf 'm_EditorVersion: ${{ matrix.unity-version }}\n' > BuildProject/ProjectSettings/ProjectVersion.txt
51+
printf '{\n "dependencies": {}\n}\n' > BuildProject/Packages/manifest.json
52+
53+
- name: Cache Unity Library
54+
uses: actions/cache@v4
55+
with:
56+
path: BuildProject/Library
57+
key: GenLibrary-${{ matrix.unity-version }}-${{ hashFiles('.github/fixtures/FixtureBuilder.cs') }}
58+
restore-keys: |
59+
GenLibrary-${{ matrix.unity-version }}-
60+
61+
- name: Build empty player and extract globalgamemanagers
62+
uses: game-ci/unity-builder@v4
63+
env:
64+
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
65+
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
66+
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
67+
with:
68+
unityVersion: ${{ matrix.unity-version }}
69+
targetPlatform: StandaloneLinux64
70+
projectPath: BuildProject
71+
# FixtureBuilder does its own BuildPlayer + extraction, then EditorApplication.Exit.
72+
buildMethod: FixtureBuilder.Build
73+
# The project is mutated at build time (temporary scene), so allow it.
74+
allowDirtyBuild: true
75+
76+
- name: Stage fixture for upload
77+
run: |
78+
test -f BuildProject/Fixture/globalgamemanagers || { echo "No globalgamemanagers produced"; exit 1; }
79+
mkdir -p staged
80+
cp -r BuildProject/Fixture staged/${{ matrix.unity-version }}
81+
ls -la staged/${{ matrix.unity-version }}
82+
83+
- name: Upload fixture artifact
84+
uses: actions/upload-artifact@v4
85+
with:
86+
name: fixture-${{ matrix.unity-version }}
87+
path: staged/${{ matrix.unity-version }}
88+
if-no-files-found: error
89+
retention-days: 5
90+
91+
commit:
92+
name: Commit generated fixtures
93+
needs: build
94+
runs-on: ubuntu-latest
95+
permissions:
96+
contents: write
97+
steps:
98+
- name: Checkout
99+
uses: actions/checkout@v4
100+
with:
101+
lfs: true
102+
103+
- name: Download all fixture artifacts
104+
uses: actions/download-artifact@v4
105+
with:
106+
path: incoming
107+
pattern: fixture-*
108+
109+
- name: Place fixtures
110+
run: |
111+
dest="Tests/Editor/Fixtures/GlobalGameManagers"
112+
mkdir -p "$dest"
113+
# download-artifact lays each artifact down as incoming/fixture-<version>/...
114+
for d in incoming/fixture-*; do
115+
version="${d#incoming/fixture-}"
116+
mkdir -p "$dest/$version"
117+
cp "$d/globalgamemanagers" "$dest/$version/globalgamemanagers"
118+
cp "$d/fixture.json" "$dest/$version/fixture.json"
119+
done
120+
find "$dest" -type f | sort
121+
122+
- name: Commit and push
123+
run: |
124+
git config user.name "github-actions[bot]"
125+
git config user.email "github-actions[bot]@users.noreply.github.com"
126+
git lfs install --local
127+
git add Tests/Editor/Fixtures/GlobalGameManagers
128+
if git diff --cached --quiet; then
129+
echo "No fixture changes to commit."
130+
exit 0
131+
fi
132+
git commit -m "test: regenerate ProjectSettings import fixtures (globalgamemanagers per Unity version)"
133+
git push origin HEAD:${{ github.ref_name }}

.github/workflows/main.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ jobs:
6666
projectPath: ci-package
6767
unityVersion: ${{ matrix.unity-version }}
6868
testMode: EditMode
69+
# Integration tests (e.g. the AssetRipper tpk download) hit the network
70+
# and are run locally in the Unity Test Runner, not in CI.
71+
customParameters: -testCategory "!Integration"
6972
githubToken: ${{ secrets.GITHUB_TOKEN }}
7073
artifactsPath: artifacts-${{ matrix.unity-version }}
7174
checkName: Unity ${{ matrix.unity-version }} Test Results
@@ -133,6 +136,9 @@ jobs:
133136
testMode: EditMode
134137
unityVersion: 2018.4.36f1
135138
projectPath: UnityTestProject
139+
# Integration tests (e.g. the AssetRipper tpk download) hit the network
140+
# and are run locally in the Unity Test Runner, not in CI.
141+
customParameters: -testCategory "!Integration"
136142
githubToken: ${{ secrets.GITHUB_TOKEN }}
137143
artifactsPath: artifacts-2018.4.36f1
138144
checkName: Unity 2018.4.36f1 Test Results
@@ -214,6 +220,9 @@ jobs:
214220
testMode: EditMode
215221
unityVersion: 6000.5.0f1
216222
projectPath: UnityTestProject
223+
# Integration tests (e.g. the AssetRipper tpk download) hit the network
224+
# and are run locally in the Unity Test Runner, not in CI.
225+
customParameters: -testCategory "!Integration"
217226
githubToken: ${{ secrets.GITHUB_TOKEN }}
218227
artifactsPath: artifacts-6000.5.0f1
219228
checkName: Unity 6000.5.0f1 Test Results

CHANGELOG.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,58 @@
1+
## 9.4.1
2+
3+
### New Features
4+
5+
* The **Installed Unity Games** window now reports each game's scripting backend
6+
and Addressables catalog format so support status is clear at a glance
7+
* A **Backend** column shows `Mono`, `IL2CPP`, or `?`; IL2CPP games are flagged
8+
unsupported since ThunderKit cannot mod them
9+
* An **Addressables** column shows the catalog format (`JSON`, `Binary`, or
10+
``); binary catalogs are flagged unsupported as not yet importable
11+
* Each row's tooltip now lists every reason a game isn't fully supported rather
12+
than just the version caveat
13+
14+
### Changes
15+
16+
* `TransformHierarchyTreeView` now selects its `TreeView` and object-identifier
17+
APIs per the Unity version that deprecated each one, eliminating the obsolescence
18+
warnings on Unity 6000.2–6000.4 (previously a single `UNITY_6000_5_OR_NEWER` guard
19+
compiled the deprecated path on every 6000.2–6000.4 editor)
20+
* Lowered the `EntityId` migration guards in `SelfDestructingActionAsset`,
21+
`MarkdownStatic`, `TemplatedWindow`, `DocumentationHelpers`, `ScriptableHelper`,
22+
and `PipelineLogWindow` from `UNITY_6000_5_OR_NEWER` to `UNITY_6000_4_OR_NEWER`,
23+
matching where those APIs first exist and the older ones become obsolete
24+
* Class data (`classdata.tpk`) coverage is now decided on `major.minor` instead of
25+
`major.minor.patch`, since patch releases rarely change the type trees we use
26+
* When no tpk fully covers the running Unity version, `ClassDataManager` now keeps
27+
the latest available tpk and warns rather than deleting it and failing
28+
* `ImportProjectSettings` now builds its class database from the closest version
29+
present in the tpk — newest at or before the running version, falling back to the
30+
oldest — instead of requiring an exact match, logging the resolved version when it
31+
differs
32+
* `ImportProjectSettings` now imports each project setting independently and warns
33+
per-setting when a type cannot be exported, so one unavailable type no longer
34+
aborts the entire import
35+
36+
### Tests
37+
38+
* Added [ImportProjectSettingsTests](Tests/Editor/ImportProjectSettingsTests.cs):
39+
an offline ProjectSettings export test driving
40+
`ImportProjectSettings.ExportProjectSettings` against per-version
41+
`globalgamemanagers` fixtures and the committed `classdata.tpk`. Runs across the
42+
CI Unity matrix and asserts a full export on editors whose `major.minor` matches a
43+
fixture; fixtures are stored via Git LFS
44+
* Added the [generate-project-settings-fixtures](.github/workflows/generate-project-settings-fixtures.yml)
45+
workflow (manual `workflow_dispatch`) that builds a throwaway empty player per
46+
Unity version and commits its `globalgamemanagers` as the per-version fixture
47+
* Extracted `ImportProjectSettings.ExportProjectSettings` as an `internal` seam so
48+
tests can drive class-data resolution and export directly; production behavior is
49+
unchanged
50+
* The test assembly (`ThunderKit.Core.Tests`) now references `AssetsTools.NET.dll`
51+
directly, since the reference is not transitive through `ThunderKit.Core`
52+
* [ClassDataVersionCoverageTests](Tests/Editor/ClassDataVersionCoverageTests.cs) is
53+
no longer `[Explicit]` — it is now `[Category("Integration")]`, running by default
54+
in the local Test Runner and excluded from CI via `-testCategory "!Integration"`
55+
156
## 9.4.0
257

358
### New Features

0 commit comments

Comments
 (0)