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
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
echo "InstallerProjectPath=./Installer" >> $GITHUB_OUTPUT
echo "InstallerFileName=ImageLoader-Installer" >> $GITHUB_OUTPUT
echo "InstallerExportMethod=com.IvanMurzak.Unity.ImageLoader.Installer.PackageExporter.ExportPackage" >> $GITHUB_OUTPUT
echo "InstallerUnityVersion=2019.4.40f1" >> $GITHUB_OUTPUT
echo "InstallerUnityVersion=2021.3.45f1" >> $GITHUB_OUTPUT

check-version-tag:
needs: setup
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test_pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
echo "InstallerProjectPath=./Installer" >> $GITHUB_OUTPUT
echo "InstallerFileName=Unity-ImageLoader-Installer" >> $GITHUB_OUTPUT
echo "InstallerExportMethod=com.IvanMurzak.Unity.ImageLoader.Installer.PackageExporter.ExportPackage" >> $GITHUB_OUTPUT
echo "InstallerUnityVersion=2019.4.40f1" >> $GITHUB_OUTPUT
echo "InstallerUnityVersion=2021.3.45f1" >> $GITHUB_OUTPUT

# --- EDIT MODE ---

Expand Down
57 changes: 57 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Repository shape: two Unity projects + one shippable package

This repo is not a single Unity project. It contains **two independent Unity projects** plus the library source that one of them ships:

- **`Unity-Package/`** — the Unity project used to develop and test the actual **Image Loader** library. The distributable package is the subfolder `Unity-Package/Assets/root/` (its own `package.json`, published to OpenUPM as `extensions.unity.imageloader`). Everything else under `Unity-Package/` (ProjectSettings, Library, .sln/.csproj) is Unity scaffolding, not shipped. **All library tests run against this project** (`projectPath: ./Unity-Package`). See `Unity-Package/CLAUDE.md` for the library's internal architecture.
- **`Installer/`** — a *separate* Unity project whose only job is to export a `.unitypackage` ("ImageLoader-Installer") that adds the OpenUPM scoped registry to a consumer's `manifest.json`. Entry point `Installer/Assets/com.IvanMurzak/Image Loader Installer/Installer.cs` runs at editor load (`[InitializeOnLoad]`) and injects the registry; `PackageExporter.ExportPackage` builds the `.unitypackage`. It carries its own `Version` constant that must match the package version.
- **`docs/`**, **`README.md`**, **`bump-version.ps1`**, **`.github/`** — repo-level assets shared by both projects.

When editing library code you almost always work in `Unity-Package/Assets/root/`; the `Installer/` project is only touched for install/registry logic.

## Versioning (must stay in sync across two files)

The package version lives in **two** places that are kept identical:

- `Unity-Package/Assets/root/package.json` → `"version"`
- `Installer/Assets/com.IvanMurzak/Image Loader Installer/Installer.cs` → `public const string Version`

Never edit these by hand independently. Use the script, which updates both atomically:

```powershell
./bump-version.ps1 -NewVersion "7.1.0" # apply
./bump-version.ps1 -NewVersion "7.1.0" -WhatIf # preview without writing
```

## Testing

Tests are Unity Test Framework (NUnit) tests inside `Unity-Package/`, split across three assemblies:

- `Tests/Base/` (`Extensions.Unity.ImageLoader.Tests`) — shared utilities, no tests
- `Tests/Editor/` (`…Tests.Editor`) — EditMode
- `Tests/Runtime/` (`…Tests.Runtime`) — PlayMode

**Run locally:** open the `Unity-Package` project → Window → General → Test Runner → *EditMode* / *PlayMode* tab. Run a single test by selecting it in that tree (there is no CLI-single-test shortcut short of Unity batch mode `-runTests -testFilter`).

### Test network is faked, not real
The library issues web requests through the injectable `IWebRequestProvider` (`ImageLoader.settings.webRequestProvider`, default `DefaultWebRequestProvider`). Tests swap in `MockWebRequestProvider`, which routes every URL to an **in-process localhost HTTP server** (`TestHttpServer`) instead of the public internet — this is what makes image-loading tests deterministic. Wiring lives in `Tests/Base/Utils/TestUtils.cs`:

- `TestUtils.BeginHold(url)` / `ReleaseHeld(url)` — park a request in-flight on the server so "cancel-while-loading" states are reproducible. Always pair them.
- Registered URLs resolve to a fast local image; unregistered URLs hit the server's slow route so client-side timeouts fire predictably.

If you add a test that loads an image, register/route it through `TestUtils` — do not point it at a real remote URL.

### Headless-CI caveat
Finalizer/GC-driven reference-cleanup tests are non-deterministic under Unity's conservative collector in `-batchmode`. `TestUtils` skips them when `Application.isBatchMode` is true (they still run in the interactive Editor Test Runner). Don't "fix" such a test by forcing it to run headless — verify it in the Editor.

## CI

Reusable workflow `.github/workflows/test_unity_plugin.yml` runs the Unity Test Runner for one `(unityVersion, testMode)` across a platform matrix (`base`, `windows-mono`) on ubuntu Docker images.

- **`test_pull_request.yml`** fans that out over Unity 2019.4 → 6000.0 in both `editmode` and `playmode`.
- **`release.yml`** (on tag) runs the full matrix, then signs & packs the UPM tarball (`upm pack` from `Unity-Package/Assets/root`) and exports the Installer `.unitypackage` (Installer project pinned to Unity 2021.3.45f1).

PRs from forks run with `pull_request_target` and require the **`ci-ok`** label; the workflow aborts if a PR also edits files under `.github/workflows/` (secrets safety).
5 changes: 5 additions & 0 deletions Installer/.vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"recommendations": [
"visualstudiotoolsforunity.vstuc"
]
}
10 changes: 10 additions & 0 deletions Installer/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Attach to Unity",
"type": "vstuc",
"request": "attach"
}
]
}
108 changes: 54 additions & 54 deletions Installer/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,55 +1,55 @@
{
"files.exclude":
{
"**/.DS_Store":true,
"**/.git":true,
"**/.gitmodules":true,
"**/*.booproj":true,
"**/*.pidb":true,
"**/*.suo":true,
"**/*.user":true,
"**/*.userprefs":true,
"**/*.unityproj":true,
"**/*.dll":true,
"**/*.exe":true,
"**/*.pdf":true,
"**/*.mid":true,
"**/*.midi":true,
"**/*.wav":true,
"**/*.gif":true,
"**/*.ico":true,
"**/*.jpg":true,
"**/*.jpeg":true,
"**/*.png":true,
"**/*.psd":true,
"**/*.tga":true,
"**/*.tif":true,
"**/*.tiff":true,
"**/*.3ds":true,
"**/*.3DS":true,
"**/*.fbx":true,
"**/*.FBX":true,
"**/*.lxo":true,
"**/*.LXO":true,
"**/*.ma":true,
"**/*.MA":true,
"**/*.obj":true,
"**/*.OBJ":true,
"**/*.asset":true,
"**/*.cubemap":true,
"**/*.flare":true,
"**/*.mat":true,
"**/*.meta":true,
"**/*.prefab":true,
"**/*.unity":true,
"build/":true,
"Build/":true,
"Library/":true,
"library/":true,
"obj/":true,
"Obj/":true,
"ProjectSettings/":true,
"temp/":true,
"Temp/":true
}
{
"files.exclude": {
"**/.DS_Store": true,
"**/.git": true,
"**/.gitmodules": true,
"**/*.booproj": true,
"**/*.pidb": true,
"**/*.suo": true,
"**/*.user": true,
"**/*.userprefs": true,
"**/*.unityproj": true,
"**/*.dll": true,
"**/*.exe": true,
"**/*.pdf": true,
"**/*.mid": true,
"**/*.midi": true,
"**/*.wav": true,
"**/*.gif": true,
"**/*.ico": true,
"**/*.jpg": true,
"**/*.jpeg": true,
"**/*.png": true,
"**/*.psd": true,
"**/*.tga": true,
"**/*.tif": true,
"**/*.tiff": true,
"**/*.3ds": true,
"**/*.3DS": true,
"**/*.fbx": true,
"**/*.FBX": true,
"**/*.lxo": true,
"**/*.LXO": true,
"**/*.ma": true,
"**/*.MA": true,
"**/*.obj": true,
"**/*.OBJ": true,
"**/*.asset": true,
"**/*.cubemap": true,
"**/*.flare": true,
"**/*.mat": true,
"**/*.meta": true,
"**/*.prefab": true,
"**/*.unity": true,
"build/": true,
"Build/": true,
"Library/": true,
"library/": true,
"obj/": true,
"Obj/": true,
"ProjectSettings/": true,
"temp/": true,
"Temp/": true
},
"dotnet.defaultSolution": "Installer.sln"
}
3 changes: 2 additions & 1 deletion Installer/Packages/manifest.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"dependencies": {
"com.unity.asset-store-tools": "https://github.com/Unity-Technologies/com.unity.asset-store-tools.git?path=/com.unity.asset-store-tools",
"com.unity.test-framework": "1.1.33"
},
"scopedRegistries": [
Expand All @@ -16,4 +17,4 @@
]
}
]
}
}
35 changes: 35 additions & 0 deletions Installer/ProjectSettings/MemorySettings.asset
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!387306366 &1
MemorySettings:
m_ObjectHideFlags: 0
m_EditorMemorySettings:
m_MainAllocatorBlockSize: -1
m_ThreadAllocatorBlockSize: -1
m_MainGfxBlockSize: -1
m_ThreadGfxBlockSize: -1
m_CacheBlockSize: -1
m_TypetreeBlockSize: -1
m_ProfilerBlockSize: -1
m_ProfilerEditorBlockSize: -1
m_BucketAllocatorGranularity: -1
m_BucketAllocatorBucketsCount: -1
m_BucketAllocatorBlockSize: -1
m_BucketAllocatorBlockCount: -1
m_ProfilerBucketAllocatorGranularity: -1
m_ProfilerBucketAllocatorBucketsCount: -1
m_ProfilerBucketAllocatorBlockSize: -1
m_ProfilerBucketAllocatorBlockCount: -1
m_TempAllocatorSizeMain: -1
m_JobTempAllocatorBlockSize: -1
m_BackgroundJobTempAllocatorBlockSize: -1
m_JobTempAllocatorReducedBlockSize: -1
m_TempAllocatorSizeGIBakingWorker: -1
m_TempAllocatorSizeNavMeshWorker: -1
m_TempAllocatorSizeAudioWorker: -1
m_TempAllocatorSizeCloudWorker: -1
m_TempAllocatorSizeGfx: -1
m_TempAllocatorSizeJobWorker: -1
m_TempAllocatorSizeBackgroundWorker: -1
m_TempAllocatorSizePreloadManager: -1
m_PlatformMemorySettings: {}
39 changes: 14 additions & 25 deletions Installer/ProjectSettings/PackageManagerSettings.asset
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,21 @@ MonoBehaviour:
m_Script: {fileID: 13964, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_EnablePreReleasePackages: 0
m_EnablePackageDependencies: 0
m_AdvancedSettingsExpanded: 1
m_ScopedRegistriesSettingsExpanded: 1
m_SeeAllPackageVersions: 0
oneTimeWarningShown: 0
m_Registries:
- m_Id: main
m_Name:
m_Url: https://packages.unity.com
m_Scopes: []
m_IsDefault: 1
- m_Id: scoped:package.openupm.com
m_Capabilities: 7
m_ConfigSource: 0
- m_Id: scoped:project:package.openupm.com
m_Name: package.openupm.com
m_Url: https://package.openupm.com
m_Scopes:
Expand All @@ -31,30 +37,13 @@ MonoBehaviour:
- org.nuget.system
- org.nuget.r3
m_IsDefault: 0
m_UserSelectedRegistryName:
m_Capabilities: 0
m_ConfigSource: 4
m_UserSelectedRegistryName: package.openupm.com
m_UserAddingNewScopedRegistry: 0
m_RegistryInfoDraft:
m_ErrorMessage:
m_Original:
m_Id: scoped:package.openupm.com
m_Name: package.openupm.com
m_Url: https://package.openupm.com
m_Scopes:
- com.ivanmurzak
- extensions.unity
- org.nuget.com.ivanmurzak
- org.nuget.microsoft
- org.nuget.system
- org.nuget.r3
m_IsDefault: 0
m_Modified: 0
m_Name: package.openupm.com
m_Url: https://package.openupm.com
m_Scopes:
- com.ivanmurzak
- extensions.unity
- org.nuget.com.ivanmurzak
- org.nuget.microsoft
- org.nuget.system
- org.nuget.r3
m_SelectedScopeIndex: 0
m_ErrorMessage:
m_UserModificationsInstanceId: -826
m_OriginalInstanceId: -830
m_LoadAssets: 0
4 changes: 2 additions & 2 deletions Installer/ProjectSettings/ProjectVersion.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
m_EditorVersion: 2019.4.40f1
m_EditorVersionWithRevision: 2019.4.40f1 (ffc62b691db5)
m_EditorVersion: 2021.3.45f1
m_EditorVersionWithRevision: 2021.3.45f1 (0da89fac8e79)
8 changes: 8 additions & 0 deletions Installer/ProjectSettings/VersionControlSettings.asset
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!890905787 &1
VersionControlSettings:
m_ObjectHideFlags: 0
m_Mode: Visible Meta Files
m_CollabEditorSettings:
inProgressEnabled: 1
Empty file.
19 changes: 19 additions & 0 deletions Installer/UserSettings/EditorUserSettings.asset
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!162 &1
EditorUserSettings:
m_ObjectHideFlags: 0
serializedVersion: 4
m_ConfigSettings:
vcSharedLogLevel:
value: 0d5e400f0650
flags: 0
m_VCAutomaticAdd: 1
m_VCDebugCom: 0
m_VCDebugCmd: 0
m_VCDebugOut: 0
m_SemanticMergeMode: 2
m_VCShowFailedCheckout: 1
m_VCOverwriteFailedCheckoutAssets: 1
m_VCOverlayIcons: 1
m_VCAllowAsyncUpdate: 0
1 change: 1 addition & 0 deletions Installer/UserSettings/Search.settings
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
Loading
Loading