From c949c18039865ac20481e7b60f283b725e8996b1 Mon Sep 17 00:00:00 2001 From: Yidi Mao Date: Fri, 16 Oct 2026 02:36:48 +0300 Subject: [PATCH 01/11] chore: drop unused DotSettings and fix stale test note in CLAUDE.md --- CLAUDE.md | 2 +- UnityExtension.sln.DotSettings | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) delete mode 100644 UnityExtension.sln.DotSettings diff --git a/CLAUDE.md b/CLAUDE.md index 03fade8..2105233 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -16,7 +16,7 @@ Store identity: `YidiMao.CommandPalette-Unity` (private values in git-ignored `d - `Directory.Packages.props` = all package versions; `dotnet-tools.json` = csharpier, minver-cli; `.pre-commit-config.yaml` = hooks - No Markdown under `UnityExtension/`; contributor guidance -> `CONTRIBUTING.md`; user docs -> `docs/` - Local-only (git-ignored, do not commit): `.claude/settings.local.json`, `docs/store-identity.md`, `scripts/` (`sign.ps1`, `pfx.ps1`, Unity path helpers) -- No test project exists; verify manually in PowerToys +- `UnityExtension.Tests/` (xunit) covers `ProjectParser` only; verify UI and commands manually in PowerToys - Gallery metadata lives in `microsoft/CmdPal-Extensions` (`extensions/maoyeedy/cmdpal-unity-extension/`), not in this repo ## Docs and tooling (use before answering from memory) diff --git a/UnityExtension.sln.DotSettings b/UnityExtension.sln.DotSettings deleted file mode 100644 index f69224d..0000000 --- a/UnityExtension.sln.DotSettings +++ /dev/null @@ -1,5 +0,0 @@ - - DO_NOT_SHOW - DO_NOT_SHOW - DO_NOT_SHOW - DO_NOT_SHOW From c4f7d148e7178b7df25f0f454e53e523bed82d91 Mon Sep 17 00:00:00 2001 From: Yidi Mao Date: Fri, 16 Oct 2026 02:38:01 +0300 Subject: [PATCH 02/11] ci: add PR CI, dependabot, and pin actions by SHA --- .github/dependabot.yml | 18 ++++++++ .github/workflows/ci.yml | 67 ++++++++++++++++++++++++++++++ .github/workflows/release-msix.yml | 9 ++-- 3 files changed, 90 insertions(+), 4 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/ci.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..d001343 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,18 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + groups: + actions: + patterns: ["*"] + - package-ecosystem: nuget + directory: / + schedule: + interval: weekly + ignore: + # Date-versioned and tied to the PowerToys target; see CLAUDE.md (bump-deps skill) + - dependency-name: Microsoft.CommandPalette.Extensions + - dependency-name: Microsoft.WindowsAppSDK + - dependency-name: Microsoft.Windows.CsWinRT diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..53e4ff4 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,67 @@ +name: CI + +on: + push: + branches: [master] + pull_request: + branches: [master] + +permissions: + contents: read + +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + +jobs: + build-test: + runs-on: windows-2022 + timeout-minutes: 30 + + steps: + # .editorconfig requires CRLF for .cs; match a Windows checkout so csharpier passes + - name: Use CRLF checkout + run: git config --global core.autocrlf true + + - name: Checkout + uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 + with: + fetch-depth: 0 + fetch-tags: true + + - name: Setup .NET SDK + uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5 + with: + dotnet-version: 10.0.x + cache: true + cache-dependency-path: | + **/Directory.Packages.props + **/*.csproj + + - name: Restore tools + run: dotnet tool restore + + - name: Check formatting + run: dotnet tool run csharpier check . + + - name: Build (Release, x64) + run: dotnet build UnityExtension/UnityExtension.csproj -c Release -p:Platform=x64 -p:SuppressSdkNoise=false + + - name: Test + run: dotnet test UnityExtension.Tests/UnityExtension.Tests.csproj -c Release -p:Platform=x64 + + validate-version: + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Checkout + uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 + + - name: Check csproj and manifest versions agree + run: | + v=$(grep -oP '(?<=)[^<]+' UnityExtension/UnityExtension.csproj | head -1) + a=$(grep -oP '(?<=)[^<]+' UnityExtension/UnityExtension.csproj | head -1) + f=$(grep -oP '(?<=)[^<]+' UnityExtension/UnityExtension.csproj | head -1) + m=$(grep -oP ']*\sVersion="\K[^"]+' UnityExtension/Package.appxmanifest | head -1) + echo "csproj=$v assembly=$a file=$f manifest=$m" + test "$a" = "$v.0" && test "$f" = "$v.0" && test "$m" = "$v.0" diff --git a/.github/workflows/release-msix.yml b/.github/workflows/release-msix.yml index 0f50f40..0f0f320 100644 --- a/.github/workflows/release-msix.yml +++ b/.github/workflows/release-msix.yml @@ -15,6 +15,7 @@ concurrency: jobs: build-sign-release: runs-on: windows-2022 + timeout-minutes: 45 defaults: run: @@ -27,13 +28,13 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 with: fetch-depth: 0 fetch-tags: true - name: Cache NuGet packages - uses: actions/cache@v4 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: path: ~/.nuget/packages key: ${{ runner.os }}-nuget-${{ hashFiles('**/Directory.Packages.props', '**/Directory.Build.props', '**/*.csproj', '**/nuget.config') }} @@ -41,7 +42,7 @@ jobs: ${{ runner.os }}-nuget- - name: Setup .NET SDK - uses: actions/setup-dotnet@v5 + uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5 with: dotnet-version: ${{ env.DOTNET_VERSION }} @@ -186,7 +187,7 @@ jobs: } - name: Upload workflow artifact - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 with: name: signed-msix path: | From 1e3dd0f7d36e9817845a5e7a66e036fd5ff046f9 Mon Sep 17 00:00:00 2001 From: Yidi Mao Date: Fri, 16 Oct 2026 02:40:11 +0300 Subject: [PATCH 03/11] chore: slim .editorconfig and pin .cs line endings to LF --- .editorconfig | 116 +++++++------------------------------------------ .gitattributes | 1 + 2 files changed, 17 insertions(+), 100 deletions(-) create mode 100644 .gitattributes diff --git a/.editorconfig b/.editorconfig index 4fa6b9f..95b414a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,139 +1,55 @@ root = true [*.cs] -# Formatting indent_style = space indent_size = 4 tab_width = 4 -end_of_line = crlf +end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true -# New lines -csharp_new_line_before_open_brace = all -csharp_new_line_before_else = true -csharp_new_line_before_catch = true -csharp_new_line_before_finally = true -csharp_new_line_before_members_in_object_initializers = true -csharp_new_line_before_members_in_anonymous_types = true - -# Indentation -csharp_indent_case_contents = true -csharp_indent_switch_labels = true -csharp_indent_labels = flush_left - -# Spacing -csharp_space_after_cast = false -csharp_space_after_keywords_in_control_flow_statements = true -csharp_space_between_method_declaration_parameter_list_parentheses = false -csharp_space_between_method_call_parameter_list_parentheses = false -csharp_space_between_parentheses = false -csharp_space_before_colon_in_inheritance_clause = true -csharp_space_after_colon_in_inheritance_clause = true -csharp_space_around_binary_operators = before_and_after -csharp_space_between_method_declaration_empty_parameter_list_parentheses = false -csharp_space_between_method_call_name_and_opening_parenthesis = false -csharp_space_between_method_call_empty_parameter_list_parentheses = false -csharp_space_after_comma = true -csharp_space_before_comma = false - -# Line preservation -csharp_preserve_single_line_statements = true -csharp_preserve_single_line_blocks = true - -# Naming Symbols +# Naming symbols dotnet_naming_symbols.public_properties.applicable_kinds = property dotnet_naming_symbols.public_properties.applicable_accessibilities = public - dotnet_naming_symbols.public_fields.applicable_kinds = field dotnet_naming_symbols.public_fields.applicable_accessibilities = public - dotnet_naming_symbols.private_fields.applicable_kinds = field dotnet_naming_symbols.private_fields.applicable_accessibilities = private - dotnet_naming_symbols.private_methods.applicable_kinds = method dotnet_naming_symbols.private_methods.applicable_accessibilities = private - dotnet_naming_symbols.constants.applicable_kinds = field dotnet_naming_symbols.constants.required_modifiers = const - dotnet_naming_symbols.local_variables.applicable_kinds = local -dotnet_naming_symbols.local_variables.applicable_accessibilities = local - dotnet_naming_symbols.parameters.applicable_kinds = parameter -dotnet_naming_symbols.parameters.applicable_accessibilities = * -# Naming Styles +# Naming styles dotnet_naming_style.pascal_case.capitalization = pascal_case - +dotnet_naming_style.camel_case.capitalization = camel_case dotnet_naming_style.camel_case_underscore.required_prefix = _ dotnet_naming_style.camel_case_underscore.capitalization = camel_case -dotnet_naming_style.camel_case.capitalization = camel_case - -dotnet_naming_style.constant_style.capitalization = pascal_case - -# Naming Rules +# Naming rules (warning: visible in CLI builds, not just the IDE) dotnet_naming_rule.public_props_must_be_pascal.symbols = public_properties dotnet_naming_rule.public_props_must_be_pascal.style = pascal_case -dotnet_naming_rule.public_props_must_be_pascal.severity = suggestion - +dotnet_naming_rule.public_props_must_be_pascal.severity = warning dotnet_naming_rule.public_fields_must_be_pascal.symbols = public_fields dotnet_naming_rule.public_fields_must_be_pascal.style = pascal_case -dotnet_naming_rule.public_fields_must_be_pascal.severity = suggestion - +dotnet_naming_rule.public_fields_must_be_pascal.severity = warning dotnet_naming_rule.private_fields_must_be_camel.symbols = private_fields dotnet_naming_rule.private_fields_must_be_camel.style = camel_case_underscore -dotnet_naming_rule.private_fields_must_be_camel.severity = suggestion - +dotnet_naming_rule.private_fields_must_be_camel.severity = warning dotnet_naming_rule.private_methods_must_be_pascal.symbols = private_methods dotnet_naming_rule.private_methods_must_be_pascal.style = pascal_case -dotnet_naming_rule.private_methods_must_be_pascal.severity = suggestion - -dotnet_naming_rule.constants_must_be_pascal_with_prefix.symbols = constants -dotnet_naming_rule.constants_must_be_pascal_with_prefix.style = constant_style -dotnet_naming_rule.constants_must_be_pascal_with_prefix.severity = suggestion - +dotnet_naming_rule.private_methods_must_be_pascal.severity = warning +dotnet_naming_rule.constants_must_be_pascal.symbols = constants +dotnet_naming_rule.constants_must_be_pascal.style = pascal_case +dotnet_naming_rule.constants_must_be_pascal.severity = warning dotnet_naming_rule.locals_must_be_camel.symbols = local_variables dotnet_naming_rule.locals_must_be_camel.style = camel_case -dotnet_naming_rule.locals_must_be_camel.severity = suggestion - +dotnet_naming_rule.locals_must_be_camel.severity = warning dotnet_naming_rule.parameters_must_be_camel.symbols = parameters dotnet_naming_rule.parameters_must_be_camel.style = camel_case -dotnet_naming_rule.parameters_must_be_camel.severity = suggestion - -# var preferences -csharp_style_var_for_built_in_types = true:suggestion -csharp_style_var_when_type_is_apparent = true:suggestion -csharp_style_var_elsewhere = true:suggestion - -# Expression-bodied members -csharp_style_expression_bodied_constructors = false:none -csharp_style_expression_bodied_operators = when_on_single_line:suggestion -csharp_style_expression_bodied_properties = when_on_single_line:suggestion -csharp_style_expression_bodied_indexers = when_on_single_line:suggestion -csharp_style_expression_bodied_accessors = when_on_single_line:suggestion -csharp_style_expression_bodied_lambdas = when_on_single_line:suggestion -csharp_style_expression_bodied_local_functions = when_on_single_line:suggestion -# csharp_style_expression_bodied_methods = when_on_single_line:suggestion - -# Pattern matching preferences -csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion -csharp_style_pattern_matching_over_as_with_null_check = true:suggestion -csharp_style_prefer_switch_expression = true:suggestion - -# Null checking preferences -dotnet_style_coalesce_expression = true:suggestion -dotnet_style_null_propagation = true:suggestion -dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion -csharp_style_conditional_delegate_call = true:suggestion +dotnet_naming_rule.parameters_must_be_camel.severity = warning -# Other preferences -csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion -csharp_style_inlined_variable_declaration = true:suggestion -csharp_style_throw_expression = true:suggestion -csharp_prefer_static_local_function = true:suggestion -csharp_style_prefer_index_operator = true:suggestion -csharp_style_prefer_range_operator = true:suggestion -dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion -dotnet_style_prefer_conditional_expression_over_return = true:suggestion +# CSharpier owns whitespace and layout +dotnet_diagnostic.IDE0055.severity = none diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..a510aa7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.cs text eol=lf From ba23a412dc28fe21d01836f070f0d00a24fe2d68 Mon Sep 17 00:00:00 2001 From: Yidi Mao Date: Fri, 16 Oct 2026 02:41:35 +0300 Subject: [PATCH 04/11] chore: normalize all text files to LF via .gitattributes --- .gitattributes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitattributes b/.gitattributes index a510aa7..6313b56 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1 @@ -*.cs text eol=lf +* text=auto eol=lf From 28aae5df4560d5d27be9f25bce1da30c9677fcaa Mon Sep 17 00:00:00 2001 From: Yidi Mao Date: Fri, 16 Oct 2026 02:41:49 +0300 Subject: [PATCH 05/11] docs: record line-ending, editorconfig and locked-exe build notes in CLAUDE.md --- CLAUDE.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index 2105233..208167e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -38,6 +38,9 @@ Store identity: `YidiMao.CommandPalette-Unity` (private values in git-ignored `d - Keep code trim-safe / AOT-compatible; preserve `sealed partial` where SDK/source generators require - Central package versions only (`Directory.Packages.props`); no versions in `.csproj` - Avoid reflection-heavy patterns unless upstream API requires +- Line endings: all text is LF (`.gitattributes` `* text=auto eol=lf`, `.editorconfig` `end_of_line = lf`); csharpier reports CRLF `.cs` files as unformatted. Keep `.csharpierignore` (csharpier would otherwise also format csproj/props/config) +- `.editorconfig` holds only what tools read: csharpier uses indent/`end_of_line`; Roslyn reads the naming rules (severity `warning`); `IDE0055` is off so it does not fight csharpier. Do not re-add `csharp_space_*` / `csharp_new_line_*` keys +- `skills-lock.json` stays tracked (the skills CLI fixes it at the root and designs it to be committed); do not git-ignore it - Formatting is enforced by pre-commit (csharpier, actionlint, gitleaks), not by Claude hooks: hooks only fire on Edit/Write, not on shell bulk edits. Run `pre-commit run --all-files` after bulk changes ## Build and verify @@ -51,6 +54,7 @@ dotnet build UnityExtension/UnityExtension.csproj -c Release -p:Platform=x64 -p: - CLI `Register` deploys need `-p:WindowsPackageType=MSIX`; MSIX bundle builds need `-p:GenerateAppxPackageOnBuild=true` (see `deploy` skill) - `IL2081` / `IL2104` from CsWinRT projections are known and non-fatal - After rebuild, reload Command Palette or restart PowerToys; test in the real host +- MSB3021/MSB3027 "file is locked by: Unity Extension for Command Palette" = the extension is running inside Command Palette and holds `bin/.../UnityExtension.exe`; not a code error. For a compile-only check build to another dir: `dotnet build UnityExtension/UnityExtension.csproj -c Debug -p:Platform=x64 -p:OutDir=/out/` (`-p:UseAppHost=false` fails with NETSDK1067). Do not kill the process; for a real deploy close/unregister it first (see `deploy` skill) ## Gotchas From 86d94353a3bf5c141c5eef66a03e004a3f0c1e64 Mon Sep 17 00:00:00 2001 From: Yidi Mao Date: Fri, 16 Oct 2026 02:43:23 +0300 Subject: [PATCH 06/11] docs: trim CLAUDE.md bloat and move locked-exe note to TROUBLESHOOTING --- CLAUDE.md | 14 ++++---------- docs/TROUBLESHOOTING.md | 6 ++++++ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 208167e..e5466af 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -38,9 +38,6 @@ Store identity: `YidiMao.CommandPalette-Unity` (private values in git-ignored `d - Keep code trim-safe / AOT-compatible; preserve `sealed partial` where SDK/source generators require - Central package versions only (`Directory.Packages.props`); no versions in `.csproj` - Avoid reflection-heavy patterns unless upstream API requires -- Line endings: all text is LF (`.gitattributes` `* text=auto eol=lf`, `.editorconfig` `end_of_line = lf`); csharpier reports CRLF `.cs` files as unformatted. Keep `.csharpierignore` (csharpier would otherwise also format csproj/props/config) -- `.editorconfig` holds only what tools read: csharpier uses indent/`end_of_line`; Roslyn reads the naming rules (severity `warning`); `IDE0055` is off so it does not fight csharpier. Do not re-add `csharp_space_*` / `csharp_new_line_*` keys -- `skills-lock.json` stays tracked (the skills CLI fixes it at the root and designs it to be committed); do not git-ignore it - Formatting is enforced by pre-commit (csharpier, actionlint, gitleaks), not by Claude hooks: hooks only fire on Edit/Write, not on shell bulk edits. Run `pre-commit run --all-files` after bulk changes ## Build and verify @@ -50,20 +47,17 @@ dotnet build UnityExtension/UnityExtension.csproj -c Debug -p:Platform=x64 dotnet build UnityExtension/UnityExtension.csproj -c Release -p:Platform=x64 -p:SuppressSdkNoise=false # trim/AOT review ``` -- Debug CLI build is green (0 warnings, 0 errors) as of this refresh - CLI `Register` deploys need `-p:WindowsPackageType=MSIX`; MSIX bundle builds need `-p:GenerateAppxPackageOnBuild=true` (see `deploy` skill) - `IL2081` / `IL2104` from CsWinRT projections are known and non-fatal - After rebuild, reload Command Palette or restart PowerToys; test in the real host -- MSB3021/MSB3027 "file is locked by: Unity Extension for Command Palette" = the extension is running inside Command Palette and holds `bin/.../UnityExtension.exe`; not a code error. For a compile-only check build to another dir: `dotnet build UnityExtension/UnityExtension.csproj -c Debug -p:Platform=x64 -p:OutDir=/out/` (`-p:UseAppHost=false` fails with NETSDK1067). Do not kill the process; for a real deploy close/unregister it first (see `deploy` skill) +- Build fails with MSB3021/MSB3027 "locked by: Unity Extension for Command Palette" = extension is running, not a code error. Compile-check with `-p:OutDir=/` and never kill it (see `docs/TROUBLESHOOTING.md`) ## Gotchas - `ProjectParser` swallows exceptions and may silently return an empty list -- Extension not loading: check manifest registration and CLSID first -- Breakpoints not hit: attach VS to the extension process, not the host shell -- `Microsoft.CommandPalette.Extensions` is date-versioned (currently 0.9.260303001); bump only for a newer PowerToys target -- `Microsoft.WindowsAppSDK` (2.2.0, matches PowerToys) and `Microsoft.Windows.CsWinRT` (2.2.0) must stay mutually compatible; keep <= PowerToys' pins -- Version sync: `Package.appxmanifest` Identity Version <-> `.csproj` ``/``/`` (currently 0.1.3 / 0.1.3.0); 4th segment `.0`. CI fails the tag build on mismatch +- `Microsoft.CommandPalette.Extensions` is date-versioned; bump only for a newer PowerToys target +- `Microsoft.WindowsAppSDK` and `Microsoft.Windows.CsWinRT` must stay mutually compatible; keep <= PowerToys' pins +- Version sync: `Package.appxmanifest` Identity Version <-> `.csproj` ``/``/``; 4th segment `.0`. CI fails the tag build on mismatch - Identity `Name`/`Publisher` must match Partner Center exactly - After identity/name changes delete `bin`, `obj`, `AppPackages` before rebuilding - Debug builds get `.Debug` package suffix and `(Dev)` display name; a release package blocks debug `-Register` (0x80073CFB), remove it first diff --git a/docs/TROUBLESHOOTING.md b/docs/TROUBLESHOOTING.md index 3422368..737e2cd 100644 --- a/docs/TROUBLESHOOTING.md +++ b/docs/TROUBLESHOOTING.md @@ -41,3 +41,9 @@ If an outdated-package check suggests a newer `Microsoft.WindowsAppSDK`, treat i If Release packaging fails with `WindowsPackageType=None` + `GenerateAppxPackageOnBuild=true`, remove hard `None` for build path. If packaging fails with `IL2104` / `NETSDK1144`, check trimming enabled for packaging build path, temporarily disable if needed. + +## Build fails: file is locked + +`MSB3021` / `MSB3027` "locked by: Unity Extension for Command Palette" means the extension is running inside Command Palette and holds `UnityExtension.exe`. It is not a code error. + +Close or unregister the extension (`winapp unregister`) for a normal build, or compile-check into another folder: `dotnet build UnityExtension/UnityExtension.csproj -c Debug -p:Platform=x64 -p:OutDir=/`. `-p:UseAppHost=false` fails with `NETSDK1067`. From 8afab408b4caf2e464a366d5aa661c7635282f90 Mon Sep 17 00:00:00 2001 From: Yidi Mao Date: Fri, 16 Oct 2026 03:14:03 +0300 Subject: [PATCH 07/11] ci: add hang diagnostics to test step --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 53e4ff4..31c8235 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,7 +48,8 @@ jobs: run: dotnet build UnityExtension/UnityExtension.csproj -c Release -p:Platform=x64 -p:SuppressSdkNoise=false - name: Test - run: dotnet test UnityExtension.Tests/UnityExtension.Tests.csproj -c Release -p:Platform=x64 + timeout-minutes: 10 + run: dotnet test UnityExtension.Tests/UnityExtension.Tests.csproj -c Release -p:Platform=x64 --blame-hang --blame-hang-timeout 2m --logger "console;verbosity=detailed" validate-version: runs-on: ubuntu-latest From 01944f76b56d2c3503e6b129bf065db2e8a016ca Mon Sep 17 00:00:00 2001 From: Yidi Mao Date: Fri, 16 Oct 2026 03:19:46 +0300 Subject: [PATCH 08/11] ci: temporary per-test isolation --- .github/workflows/ci.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 31c8235..ad85645 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,7 +49,12 @@ jobs: - name: Test timeout-minutes: 10 - run: dotnet test UnityExtension.Tests/UnityExtension.Tests.csproj -c Release -p:Platform=x64 --blame-hang --blame-hang-timeout 2m --logger "console;verbosity=detailed" + run: | + foreach ($f in 'Unusable_input','Incomplete_entry','Missing_fields','Exists_reflects') { + Write-Host "=== $f" + dotnet test UnityExtension.Tests/UnityExtension.Tests.csproj -c Release -p:Platform=x64 --no-build --filter "FullyQualifiedName~$f" --blame-hang --blame-hang-timeout 40s + } + exit 0 validate-version: runs-on: ubuntu-latest From 9266ef1261c6493ac7b03830d9495a4cb8379bf3 Mon Sep 17 00:00:00 2001 From: Yidi Mao Date: Fri, 16 Oct 2026 03:22:04 +0300 Subject: [PATCH 09/11] ci: fix isolation step --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ad85645..c71e1a7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,7 +52,7 @@ jobs: run: | foreach ($f in 'Unusable_input','Incomplete_entry','Missing_fields','Exists_reflects') { Write-Host "=== $f" - dotnet test UnityExtension.Tests/UnityExtension.Tests.csproj -c Release -p:Platform=x64 --no-build --filter "FullyQualifiedName~$f" --blame-hang --blame-hang-timeout 40s + dotnet test UnityExtension.Tests/UnityExtension.Tests.csproj -c Release -p:Platform=x64 --filter "FullyQualifiedName~$f" --blame-hang --blame-hang-timeout 40s } exit 0 From 476d03fc914e78cf9871c6ea1cfb12283505b6cb Mon Sep 17 00:00:00 2001 From: Yidi Mao Date: Fri, 16 Oct 2026 03:27:23 +0300 Subject: [PATCH 10/11] ci: restore test step with hang timeout --- .github/workflows/ci.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c71e1a7..1cdf98b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,12 +49,7 @@ jobs: - name: Test timeout-minutes: 10 - run: | - foreach ($f in 'Unusable_input','Incomplete_entry','Missing_fields','Exists_reflects') { - Write-Host "=== $f" - dotnet test UnityExtension.Tests/UnityExtension.Tests.csproj -c Release -p:Platform=x64 --filter "FullyQualifiedName~$f" --blame-hang --blame-hang-timeout 40s - } - exit 0 + run: dotnet test UnityExtension.Tests/UnityExtension.Tests.csproj -c Release -p:Platform=x64 --blame-hang --blame-hang-timeout 2m validate-version: runs-on: ubuntu-latest From 7a3ad462c6c8c6a964d85e95ba50316ef372312d Mon Sep 17 00:00:00 2001 From: Yidi Mao Date: Fri, 16 Oct 2026 03:32:27 +0300 Subject: [PATCH 11/11] ci: disable WinAppSDK bootstrap auto-init for the test run --- .github/workflows/ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1cdf98b..4341742 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,9 +47,11 @@ jobs: - name: Build (Release, x64) run: dotnet build UnityExtension/UnityExtension.csproj -c Release -p:Platform=x64 -p:SuppressSdkNoise=false + # The unpackaged exe auto-initializes the Windows App SDK bootstrapper, which hangs the + # test host on runners without the Windows App Runtime; tests only need ProjectParser. - name: Test timeout-minutes: 10 - run: dotnet test UnityExtension.Tests/UnityExtension.Tests.csproj -c Release -p:Platform=x64 --blame-hang --blame-hang-timeout 2m + run: dotnet test UnityExtension.Tests/UnityExtension.Tests.csproj -c Release -p:Platform=x64 -p:WindowsAppSdkBootstrapInitialize=false --blame-hang --blame-hang-timeout 2m validate-version: runs-on: ubuntu-latest