unity-devkit 0.1.21.dev36667980974__tar.gz → 0.1.22__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. {unity_devkit-0.1.21.dev36667980974 → unity_devkit-0.1.22}/PKG-INFO +1 -1
  2. {unity_devkit-0.1.21.dev36667980974 → unity_devkit-0.1.22}/pyproject.toml +1 -1
  3. {unity_devkit-0.1.21.dev36667980974 → unity_devkit-0.1.22}/src/unity_devkit/player_build.py +21 -2
  4. unity_devkit-0.1.22/tests/test_prepare.py +78 -0
  5. unity_devkit-0.1.21.dev36667980974/tests/test_prepare.py +0 -36
  6. {unity_devkit-0.1.21.dev36667980974 → unity_devkit-0.1.22}/.gitignore +0 -0
  7. {unity_devkit-0.1.21.dev36667980974 → unity_devkit-0.1.22}/src/unity_devkit/__init__.py +0 -0
  8. {unity_devkit-0.1.21.dev36667980974 → unity_devkit-0.1.22}/src/unity_devkit/build_unity.py +0 -0
  9. {unity_devkit-0.1.21.dev36667980974 → unity_devkit-0.1.22}/src/unity_devkit/ci_build_unity.py +0 -0
  10. {unity_devkit-0.1.21.dev36667980974 → unity_devkit-0.1.22}/src/unity_devkit/compile_check_unity.py +0 -0
  11. {unity_devkit-0.1.21.dev36667980974 → unity_devkit-0.1.22}/src/unity_devkit/install.py +0 -0
  12. {unity_devkit-0.1.21.dev36667980974 → unity_devkit-0.1.22}/src/unity_devkit/license.py +0 -0
  13. {unity_devkit-0.1.21.dev36667980974 → unity_devkit-0.1.22}/src/unity_devkit/license_restore.py +0 -0
  14. {unity_devkit-0.1.21.dev36667980974 → unity_devkit-0.1.22}/src/unity_devkit/lock_unity.py +0 -0
  15. {unity_devkit-0.1.21.dev36667980974 → unity_devkit-0.1.22}/src/unity_devkit/matrix.py +0 -0
  16. {unity_devkit-0.1.21.dev36667980974 → unity_devkit-0.1.22}/src/unity_devkit/projects.py +0 -0
  17. {unity_devkit-0.1.21.dev36667980974 → unity_devkit-0.1.22}/src/unity_devkit/py.typed +0 -0
  18. {unity_devkit-0.1.21.dev36667980974 → unity_devkit-0.1.22}/src/unity_devkit/test_unity.py +0 -0
  19. {unity_devkit-0.1.21.dev36667980974 → unity_devkit-0.1.22}/src/unity_devkit/upm_cache.py +0 -0
  20. {unity_devkit-0.1.21.dev36667980974 → unity_devkit-0.1.22}/tests/fixtures/environment-dump.json +0 -0
  21. {unity_devkit-0.1.21.dev36667980974 → unity_devkit-0.1.22}/tests/test_build_player.py +0 -0
  22. {unity_devkit-0.1.21.dev36667980974 → unity_devkit-0.1.22}/tests/test_matrix.py +0 -0
  23. {unity_devkit-0.1.21.dev36667980974 → unity_devkit-0.1.22}/tests/test_projects.py +0 -0
  24. {unity_devkit-0.1.21.dev36667980974 → unity_devkit-0.1.22}/tests/test_run_unity_batchmode.py +0 -0
  25. {unity_devkit-0.1.21.dev36667980974 → unity_devkit-0.1.22}/tests/test_upm_cache.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: unity-devkit
3
- Version: 0.1.21.dev36667980974
3
+ Version: 0.1.22
4
4
  Summary: Unity build, license, and CI tooling
5
5
  Requires-Python: >=3.13
6
6
  Requires-Dist: bashrun>=0.1.0
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "unity-devkit"
3
- version = "0.1.21.dev36667980974"
3
+ version = "0.1.22"
4
4
  description = "Unity build, license, and CI tooling"
5
5
  requires-python = ">=3.13"
6
6
  dependencies = [
@@ -1,4 +1,5 @@
1
1
  import json
2
+ import os
2
3
  import re
3
4
  import shutil
4
5
  import sys
@@ -28,6 +29,14 @@ UNITYCI_IMAGE_REVISION = "3"
28
29
  LICENSE_IMAGE_MODULE = "linux-il2cpp"
29
30
  PLAYERBUILD_ENTRY = "Outernet.PlayerBuild.Entry"
30
31
 
32
+ # Pinned to the v2026.07.21 tag of dotnet/install-scripts (raw at the commit SHA, which
33
+ # is immutable, unlike the moving https://dot.net/v1/dotnet-install.sh redirect).
34
+ DOTNET_INSTALL_SCRIPT_COMMIT = "da3ce11ba63f3dbb0fb835d41bda2665d5c48e84"
35
+ DOTNET_INSTALL_SCRIPT_URL = (
36
+ f"https://raw.githubusercontent.com/dotnet/install-scripts/{DOTNET_INSTALL_SCRIPT_COMMIT}/src/dotnet-install.sh"
37
+ )
38
+ DOTNET_SDK_VERSION = "8.0.421"
39
+
31
40
  # Unity exits 0 while reporting fatal package-manager errors only in the editor log. Every
32
41
  # Unity invocation goes through run_unity_batchmode, which scans the captured log for these
33
42
  # signatures and fails regardless of the exit code. Extend the tuple as new silent failures
@@ -151,8 +160,18 @@ def prepare_unity_project(project_path: Path) -> None:
151
160
  # their manifest); elsewhere it would demand the dotnet SDK + tool manifest and
152
161
  # litter Assets/ with NuGet.config/packages.config/Packages.meta scaffolding.
153
162
  if (project_path / "Assets" / "packages.config").exists():
154
- bash("dotnet tool restore")
155
- bash(f"dotnet nugetforunity restore {project_path}")
163
+ # The unityci editor containers ship no dotnet CLI; provision the pinned SDK on
164
+ # demand into ~/.dotnet (persisting across runs on self-hosted runners).
165
+ env: dict[str, str] = {}
166
+ if not shutil.which("dotnet"):
167
+ install_dir = Path.home() / ".dotnet"
168
+ if not (install_dir / "dotnet").exists():
169
+ script_path = Path(tempfile.gettempdir()) / "dotnet-install.sh"
170
+ bash(f"curl -fsSL {DOTNET_INSTALL_SCRIPT_URL} -o {script_path}")
171
+ bash(f"bash {script_path} --version {DOTNET_SDK_VERSION} --install-dir {install_dir}")
172
+ env = {"PATH": f"{install_dir}{os.pathsep}{os.environ['PATH']}", "DOTNET_CLI_TELEMETRY_OPTOUT": "1"}
173
+ bash("dotnet tool restore", env=env)
174
+ bash(f"dotnet nugetforunity restore {project_path}", env=env)
156
175
 
157
176
 
158
177
  def parse_environment_fields(entries: Sequence[str]) -> dict[str, str]:
@@ -0,0 +1,78 @@
1
+ import os
2
+ import shutil
3
+ import tempfile
4
+ from functools import partial
5
+ from pathlib import Path
6
+
7
+ import pytest
8
+
9
+ from unity_devkit import player_build
10
+
11
+ Call = tuple[tuple[str, ...], dict[str, str]]
12
+
13
+
14
+ def test_prepare_skips_nuget_restore_without_packages_config(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
15
+ calls: list[Call] = []
16
+ monkeypatch.setattr(player_build, "bash", partial(record_call, calls))
17
+ (tmp_path / "Assets").mkdir()
18
+
19
+ player_build.prepare_unity_project(tmp_path)
20
+
21
+ assert calls == []
22
+
23
+
24
+ def test_prepare_runs_nuget_restore_for_nuget_consumer(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
25
+ calls: list[Call] = []
26
+ monkeypatch.setattr(player_build, "bash", partial(record_call, calls))
27
+ monkeypatch.setattr(shutil, "which", present_tool)
28
+ (tmp_path / "Assets").mkdir()
29
+ (tmp_path / "Assets" / "packages.config").write_text('<?xml version="1.0"?>\n')
30
+
31
+ player_build.prepare_unity_project(tmp_path)
32
+
33
+ assert calls == [
34
+ (("dotnet tool restore",), {}),
35
+ ((f"dotnet nugetforunity restore {tmp_path}",), {}),
36
+ ]
37
+
38
+
39
+ def test_prepare_provisions_dotnet_sdk_when_missing(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
40
+ calls: list[Call] = []
41
+ monkeypatch.setattr(player_build, "bash", partial(record_call, calls))
42
+ monkeypatch.setattr(shutil, "which", absent_tool)
43
+ monkeypatch.setattr(Path, "home", lambda: tmp_path)
44
+ (tmp_path / "Assets").mkdir()
45
+ (tmp_path / "Assets" / "packages.config").write_text('<?xml version="1.0"?>\n')
46
+
47
+ player_build.prepare_unity_project(tmp_path)
48
+
49
+ script_path = Path(tempfile.gettempdir()) / "dotnet-install.sh"
50
+ install_dir = tmp_path / ".dotnet"
51
+ assert calls[0] == ((f"curl -fsSL {player_build.DOTNET_INSTALL_SCRIPT_URL} -o {script_path}",), {})
52
+ expected_install = f"bash {script_path} --version {player_build.DOTNET_SDK_VERSION} --install-dir {install_dir}"
53
+ assert calls[1] == ((expected_install,), {})
54
+ expected_env = {"PATH": f"{install_dir}{os.pathsep}{os.environ['PATH']}", "DOTNET_CLI_TELEMETRY_OPTOUT": "1"}
55
+ assert calls[2] == (("dotnet tool restore",), expected_env)
56
+ assert calls[3] == ((f"dotnet nugetforunity restore {tmp_path}",), expected_env)
57
+
58
+
59
+ def test_prepare_clears_stale_unity_lockfile(tmp_path: Path) -> None:
60
+ lockfile = tmp_path / "Temp" / "UnityLockfile"
61
+ lockfile.parent.mkdir()
62
+ lockfile.write_text("")
63
+
64
+ player_build.prepare_unity_project(tmp_path)
65
+
66
+ assert not lockfile.exists()
67
+
68
+
69
+ def record_call(calls: list[Call], command: str, env: dict[str, str] | None = None) -> None:
70
+ calls.append(((command,), env or {}))
71
+
72
+
73
+ def absent_tool(_name: str) -> str | None:
74
+ return None
75
+
76
+
77
+ def present_tool(name: str) -> str:
78
+ return f"/usr/bin/{name}"
@@ -1,36 +0,0 @@
1
- from pathlib import Path
2
-
3
- import pytest
4
-
5
- from unity_devkit import player_build
6
-
7
-
8
- def test_prepare_skips_nuget_restore_without_packages_config(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
9
- calls: list[str] = []
10
- monkeypatch.setattr(player_build, "bash", calls.append)
11
- (tmp_path / "Assets").mkdir()
12
-
13
- player_build.prepare_unity_project(tmp_path)
14
-
15
- assert calls == []
16
-
17
-
18
- def test_prepare_runs_nuget_restore_for_nuget_consumer(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
19
- calls: list[str] = []
20
- monkeypatch.setattr(player_build, "bash", calls.append)
21
- (tmp_path / "Assets").mkdir()
22
- (tmp_path / "Assets" / "packages.config").write_text('<?xml version="1.0"?>\n')
23
-
24
- player_build.prepare_unity_project(tmp_path)
25
-
26
- assert calls == ["dotnet tool restore", f"dotnet nugetforunity restore {tmp_path}"]
27
-
28
-
29
- def test_prepare_clears_stale_unity_lockfile(tmp_path: Path) -> None:
30
- lockfile = tmp_path / "Temp" / "UnityLockfile"
31
- lockfile.parent.mkdir()
32
- lockfile.write_text("")
33
-
34
- player_build.prepare_unity_project(tmp_path)
35
-
36
- assert not lockfile.exists()