From 4719dc82228463bf82d57f0984231fbb51f3d91e Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 12 Aug 2026 16:28:28 -0700 Subject: [PATCH 1/2] Add standalone runtime test repro skills Add focused skills for resolving runtime tests from wrapper paths or fully qualified method names, generating standalone corerun apps, and composing scenario-aware dotenv files. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 909db69e-bf77-405e-8010-9fbcea0fe9d2 --- .../skills/standalone-test-repro-cmd/SKILL.md | 66 ++++ .../standalone-test-repro-method/SKILL.md | 65 ++++ .github/skills/standalone-test-repro/SKILL.md | 311 ++++++++++++++++++ .github/skills/test-scenario-env/SKILL.md | 135 ++++++++ 4 files changed, 577 insertions(+) create mode 100644 .github/skills/standalone-test-repro-cmd/SKILL.md create mode 100644 .github/skills/standalone-test-repro-method/SKILL.md create mode 100644 .github/skills/standalone-test-repro/SKILL.md create mode 100644 .github/skills/test-scenario-env/SKILL.md diff --git a/.github/skills/standalone-test-repro-cmd/SKILL.md b/.github/skills/standalone-test-repro-cmd/SKILL.md new file mode 100644 index 00000000000000..65cba023bcb942 --- /dev/null +++ b/.github/skills/standalone-test-repro-cmd/SKILL.md @@ -0,0 +1,66 @@ +--- +name: standalone-test-repro-cmd +description: > + Resolve a CoreCLR runtime test from a generated .cmd or .sh wrapper path for + the standalone-test-repro workflow. Use when the requested test is identified + by a CI or Helix wrapper path, with or without a named test scenario. + Continue with the parent standalone-test-repro skill after resolution. +--- + +# Resolve a Runtime Test Wrapper + +This is the wrapper-path resolution sub-skill for +[`../standalone-test-repro/SKILL.md`](../standalone-test-repro/SKILL.md). +Resolve the exact source test, owning project, and effective invocation, then +continue with the parent's shared extraction steps. + +## Input + +Accept a generated `.cmd` or `.sh` path copied from a CI failure, for example: + +```text +JIT\Directed\ConvertToInt\checked\ConvertToInt.cmd +``` + +The path may be absolute, relative to a Helix work item or runtime test output +root, and may use either directory separator. The surrounding request may also +name a scenario such as `jitstress1`; preserve it separately from the path for +the parent workflow. + +## Resolution + +1. Normalize the identifier: + - Trim quotes, Markdown formatting, leading test-result labels, and trailing + punctuation. + - Remove command-line arguments while retaining the path through `.cmd` or + `.sh`. + - Convert separators only for host filesystem operations. + - Do not treat a separately supplied scenario as part of the wrapper path. +2. If the wrapper exists locally, read it and record: + - The managed assembly or executable + - `corerun` arguments, including `-p` and `-e` + - Test arguments and expected exit code + - Environment variables + - Working-directory assumptions + - Copied data or native dependencies +3. Map an artifact or Helix path back to `src/tests/`: + - Strip prefixes through the runtime test output root. + - Remove configuration-only artifact path segments. + - Search the remaining relative directory for the wrapper stem, likely + `.csproj`, source file, and matching `AssemblyName`. +4. If the wrapper is unavailable, use the path and stem to search under + `src/tests/`; derive invocation settings from the project. +5. Inspect the owning project, applicable imports, and its explicit or evaluated + `Compile` items. +6. Confirm the assembly contains only the requested runnable test. If it + contains multiple independently runnable tests, stop and ask for a fully + qualified method name. + +Do not assume a wrapper only runs `corerun Test.dll`. Its host options, +environment, arguments, setup, and working directory may be required to +reproduce the failure. When available, the generated wrapper is the ground +truth for the effective invocation. + +Resolution is complete only when the exact source method, owning project, and +effective invocation are known. Return any requested scenario unchanged for +canonicalization by the `test-scenario-env` skill. diff --git a/.github/skills/standalone-test-repro-method/SKILL.md b/.github/skills/standalone-test-repro-method/SKILL.md new file mode 100644 index 00000000000000..2bbb26fcc84852 --- /dev/null +++ b/.github/skills/standalone-test-repro-method/SKILL.md @@ -0,0 +1,65 @@ +--- +name: standalone-test-repro-method +description: > + Resolve a CoreCLR runtime test from a fully qualified method name for the + standalone-test-repro workflow. Use for xUnit display names and methods in + merged or multi-test assemblies, with or without a named test scenario. + Continue with the parent standalone-test-repro skill after resolution. +--- + +# Resolve a Runtime Test Method + +This is the method-name resolution sub-skill for +[`../standalone-test-repro/SKILL.md`](../standalone-test-repro/SKILL.md). +Resolve the exact source test, owning project, and test invocation, then +continue with the parent's shared extraction steps. + +## Input + +Accept a fully qualified method name copied from a CI failure, for example: + +```text +Namespace.TypeName.MethodName +``` + +It may include an assembly prefix, xUnit display-name arguments, quotes, +parentheses, nested-type notation, or surrounding CI log text. The surrounding +request may also name a scenario such as `jitstress1`; preserve it separately +from the method identifier for the parent workflow. + +## Resolution + +1. Normalize the identifier: + - Trim quotes, Markdown formatting, leading result labels, and trailing + punctuation. + - Preserve xUnit argument text for theory-case resolution. + - Remove an assembly prefix only after verifying it is an assembly name. + - Never reduce the identifier to only the final method segment. + - Do not treat a separately supplied scenario as part of the method name. +2. Parse the longest plausible namespace/type prefix and method name. Account + for nested types (`+` in reflection names and `.` in C# source) and generic + arity suffixes. +3. Search C# sources under `src/tests/` for the exact method declaration and + confirm its containing type and namespace. Prefer symbol information when + available; otherwise combine targeted searches for method, type, and + namespace. +4. Find the owning `.csproj` by its explicit or evaluated `Compile` items. + Account for wildcard includes and merged projects such as JIT regression + assemblies. +5. Inspect the project and source for: + - `[Fact]`, `[Theory]`, custom attributes, or `TestEntryPoint` + - Static or instance invocation and constructor requirements + - Fixtures, setup, cleanup, and disposal + - Async and generic return or argument handling + - Conditional compilation and platform guards + - Test data and the specific failing theory row +6. If display-name arguments identify a theory row, reproduce exactly that + row. If not, generate invocations for all locally resolvable rows and label + them. Use the `ask_user` tool when runtime-discovered data or ambiguity + prevents a faithful choice. +7. If multiple source methods still match, present the concrete candidates with + `ask_user`; do not guess. + +Resolution is complete only when the exact source method, owning project, and +required invocation semantics are known. Return any requested scenario +unchanged for canonicalization by the `test-scenario-env` skill. diff --git a/.github/skills/standalone-test-repro/SKILL.md b/.github/skills/standalone-test-repro/SKILL.md new file mode 100644 index 00000000000000..82bcd298d73efc --- /dev/null +++ b/.github/skills/standalone-test-repro/SKILL.md @@ -0,0 +1,311 @@ +--- +name: standalone-test-repro +description: > + Generate a standalone console application under artifacts/tmp from a managed + test under src/tests so it can be run directly with corerun. USE FOR: + "create a standalone repro for this runtime test", converting a CoreCLR test + wrapper path such as JIT/.../TestName.cmd into a console app, or extracting a + fully qualified xUnit test method from a merged test assembly, including when + a CI scenario such as jitstress1 is specified. DO NOT USE FOR: adding a + regression test to src/tests, library tests under src/libraries, + NativeAOT-only tests, or tests whose behavior fundamentally requires a + native, browser, mobile, multi-process, or external-service harness. +--- + +# Standalone Runtime Test Repro + +Generate a source-level console application for one managed test under +`src/tests/`. Put it under `artifacts/tmp/standalone-test-repro/` and make it +runnable as: + +```text +/corerun[.exe] /StandaloneTestRepro.dll +``` + +The output is an isolated repro, not a launcher that references the original +test assembly. Copy and adapt the test's source and required helpers so the +repro remains understandable and editable. + +## Scope Gate + +This skill supports managed CoreCLR tests that can meaningfully execute through +`corerun`. Before extraction, inspect the project and generated wrapper when +available. + +Stop and explain the limitation instead of producing a misleading repro if the +test fundamentally depends on any of these: + +- A native executable as the primary test process +- NativeAOT, Mono, browser, WASI, Android, iOS, tvOS, or MacCatalyst hosting +- A profiler, debugger, COM server, custom host, or externally installed tool + that cannot be represented by a console app plus local files +- A coordinated multi-process harness where invoking one managed method changes + the behavior under test +- Network services, credentials, privileged machine configuration, or other + unavailable external infrastructure + +Local native libraries, data files, child processes, and environment variables +are allowed when they can be copied into the repro directory and their use is +part of the behavior being reproduced. + +## Workflow + +### 1. Establish the Runtime Test Environment + +Read: + +- `src/tests/README.md` +- The nearest applicable `README.md` files between the resolved test directory + and `src/tests/` +- `.github/instructions/tests.instructions.md` +- `.github/instructions/csharp.instructions.md` +- Any area-specific instruction file that applies to the resolved source + +Use the `build-and-test` skill before invoking any build or test command. + +Determine the intended OS, architecture, and configuration from the supplied +path or CI context. Otherwise default to the current host, `x64`, and `Release`. +Prefer an existing matching `CORE_ROOT`. If it does not exist, generate the +matching Core_Root layout using the runtime-test instructions from the +`build-and-test` skill. + +Do not modify files under `src/tests/`. + +### 2. Resolve the Test + +Preserve the original identifier for the final report, then load exactly one +resolution sub-skill: + +- For a path ending in `.cmd` or `.sh`, read and follow + [`../standalone-test-repro-cmd/SKILL.md`](../standalone-test-repro-cmd/SKILL.md). +- For a fully qualified test method name, read and follow + [`../standalone-test-repro-method/SKILL.md`](../standalone-test-repro-method/SKILL.md). + +If the input does not clearly match either form, use the `ask_user` tool. The +sub-skill must resolve the exact source method, owning project, and effective +test invocation before continuing here. + +Capture an explicitly requested test scenario separately from the test +identifier. After resolving the owning project, read and follow +[`../test-scenario-env/SKILL.md`](../test-scenario-env/SKILL.md) when a scenario +was supplied. Pass it the canonical scenario name, owning `.csproj`, target OS, +architecture, configuration, runtime flavor, and output path +`artifacts/tmp/standalone-test-repro//.env`. + +### 3. Capture the Original Test Contract + +Before editing the repro, record everything that can affect behavior: + +- Source files and helper types used by the test +- Project properties such as `Optimize`, `AllowUnsafeBlocks`, `CheckForOverflowUnderflow`, + `DefineConstants`, `LangVersion`, `PlatformTarget`, and nullable context +- `RuntimeHostConfigurationOption` values +- Evaluated `CLRTestEnvironmentVariable` names and values from the owning + `.csproj`, including applicable imported properties and conditions +- The requested scenario and its evaluated environment from + `src/tests/Common/testenvironment.proj`, when specified +- `CLRTestExecutionArguments` +- Expected exit code, which defaults to `100` for runtime tests +- Working directory, input files, native libraries, and other copied assets +- Architecture, OS, configuration, and runtime flavor guards + +When a local wrapper exists, treat its effective command and environment as the +ground truth. Project files are the fallback when no wrapper has been generated. + +### 4. Create the Repro + +Create: + +```text +artifacts/tmp/standalone-test-repro// +``` + +Use a stable, filesystem-safe name derived from the type and method or wrapper +stem. If that directory already exists, inspect it first. Replace only files +owned by a previous run of this skill; never recursively delete an unresolved +or broad path. + +The directory must contain at least: + +```text +StandaloneTestRepro.csproj +Program.cs +``` + +If a scenario was requested or the owning project defines any effective +`CLRTestEnvironmentVariable` items, also create: + +```text +.env +``` + +Additional `.cs` files and local assets are allowed when they improve clarity +or are required for faithful behavior. + +Use this project as the starting point, adding only properties required by the +original test: + +```xml + + + Exe + $(NetCoreAppCurrent) + StandaloneTestRepro + false + true + preview + enable + true + + +``` + +Follow these extraction rules: + +- When a scenario was requested, the `test-scenario-env` skill owns `.env` + generation. Do not independently reconstruct or append scenario settings. +- Write each evaluated `CLRTestEnvironmentVariable` to `.env` as + `NAME=VALUE`, one variable per line. Resolve MSBuild properties and item + metadata for the selected OS, architecture, configuration, and runtime + flavor; do not copy unevaluated expressions such as `$(SomeProperty)`. +- Preserve empty values as `NAME=`. Use dotenv quoting or escaping when a value + contains whitespace, `#`, quotes, backslashes, newlines, or variable + expansion syntax. Follow the syntax supported by CoreRun's dotenv parser in + `src/coreclr/hosts/corerun/dotenv.cpp`. +- Include only environment variables defined by the test project and its + applicable imports. Do not copy the ambient shell environment or CI secrets + into `.env`. +- Merge scenario variables first and project `CLRTestEnvironmentVariable` + values second, matching generated wrapper order. A project value replaces a + scenario value with the same name. +- If a local generated wrapper and the evaluated project disagree, use the + wrapper's effective values and investigate why before continuing. +- Copy the relevant test logic, not the whole merged assembly. +- Preserve the code shape that may trigger the failure. Do not simplify + control flow, types, constants, inlining attributes, optimization settings, + or concurrency merely because a smaller version appears equivalent. +- Include only transitively required helper types and source files. +- Remove xUnit and runtime test-framework dependencies where practical. + Replace assertions with small local checks that throw an exception containing + expected and actual values. +- Prefer source-level local replacements for simple `TestLibrary` helpers. + Do not reference the original test project or its output assembly. +- Preserve required setup and cleanup with `try/finally` or `using`; do not + silently omit fixtures or disposal. +- Invoke instance methods on a correctly initialized instance. +- Await `Task`, `Task`, `ValueTask`, and `ValueTask` results. +- For a theory with several rows, print the row before invoking it and stop on + the first failure. +- Preserve unsafe code, P/Invoke declarations, generated code, and conditional + compilation required by the failing path. +- Copy required local data and native binaries into the build output using + project items such as `Content` with `CopyToOutputDirectory`. Keep their + relative paths consistent with the original test. +- Do not download packages, binaries, or test data from issue links. Use only + trusted repository sources and already-built repository artifacts. + +The console entry point should return the original success code, normally +`100`, and allow failures to remain visible: + +```csharp +internal static class Program +{ + private static int Main() + { + RunTest(); + + return 100; + } +} +``` + +Use `static async Task Main()` when asynchronous invocation is required. +Do not catch exceptions merely to convert them into success-shaped output. A +catch is acceptable only to add test-case context before rethrowing. + +### 5. Build + +Build with the repository's bootstrapped SDK from the repository root. Use a +dedicated output directory inside the repro: + +```text +dotnet.cmd build artifacts\tmp\standalone-test-repro\\StandaloneTestRepro.csproj -c Release -o artifacts\tmp\standalone-test-repro\\out +``` + +On Unix, use `./dotnet.sh` and Unix path separators. + +If the original test requires a different optimization or configuration, use +that configuration consistently and explain it in the final report. Fix all +compile errors in the repro; do not work around them by referencing the +original test assembly. + +### 6. Run with CoreRun + +Run from the repro output directory so relative paths behave consistently. +Apply the captured environment variables, host configuration options, and test +arguments. + +Windows: + +```powershell +Push-Location artifacts\tmp\standalone-test-repro\\out +& "$env:CORE_ROOT\corerun.exe" -e ..\.env .\StandaloneTestRepro.dll +$exitCode = $LASTEXITCODE +Pop-Location +``` + +Unix: + +```bash +( + cd artifacts/tmp/standalone-test-repro//out + "$CORE_ROOT/corerun" -e ../.env ./StandaloneTestRepro.dll +) +exit_code=$? +``` + +Include `-e ../.env` only when the file was generated. If +`RuntimeHostConfigurationOption` items were present, translate them to +`corerun -p Name=Value` arguments before `-e`. Pass test arguments after the +managed DLL. + +Success normally exits `100`; a CI failure repro may intentionally crash or +return another value. Record the actual exit code and meaningful output. Do not +claim the CI failure reproduced unless the observed behavior matches it. + +### 7. Validate Fidelity + +Before completing: + +1. Compare the repro invocation with the original wrapper or project contract. +2. Confirm the repro does not reference the original test assembly. +3. If `.env` was generated, compare every entry with the effective + scenario and `CLRTestEnvironmentVariable` items and confirm the `corerun` + command uses it. +4. Confirm all required local files exist in `out`. +5. Run the repro with the selected `corerun`. +6. If practical, run the original test with the same runtime and environment + and compare the relevant behavior. +7. Inspect `git status` and ensure only the new skill or explicitly requested + repository changes are tracked; repro files under `artifacts/` should remain + untracked or ignored. + +If the standalone app builds and runs but does not reproduce the reported +failure, keep the app and state that result plainly. Include any configuration +from CI that was unavailable locally. + +## Final Response + +Lead with the result and include: + +- The resolved source method and owning project +- The repro directory and built DLL +- The exact `corerun` command, including required environment variables and + `-p` options +- The generated `.env` path and variable names, without unnecessarily echoing + sensitive values +- The canonical scenario name, when one was requested +- The observed exit code and whether it matched the reported failure +- Any intentionally retained local native or data dependencies + +Do not paste the full generated source unless the user asks for it. diff --git a/.github/skills/test-scenario-env/SKILL.md b/.github/skills/test-scenario-env/SKILL.md new file mode 100644 index 00000000000000..9470902d0d46d7 --- /dev/null +++ b/.github/skills/test-scenario-env/SKILL.md @@ -0,0 +1,135 @@ +--- +name: test-scenario-env +description: > + Generate a CoreRun-compatible .env file for a named CoreCLR test scenario + defined by src/tests/Common/testenvironment.proj. Optionally merge the + effective CLRTestEnvironmentVariable items from a specific src/tests project. + USE FOR: "create an env file for jitstress1", "show the environment for this + test under gcstress0xc", or scenario-aware standalone test repro generation. + DO NOT USE FOR: library test scenarios, arbitrary user-defined environment + files, or mobile, browser, WASI, Mono, and NativeAOT test hosting. +--- + +# CoreCLR Test Scenario Environment + +Generate a dotenv file consumable by: + +```text +corerun[.exe] -e +``` + +Use `src/tests/Common/testenvironment.proj` as the source of truth. Do not +manually duplicate its scenario table or defaults in the skill. + +## Inputs + +Required: + +- A scenario name from a `TestEnvironment` item in + `src/tests/Common/testenvironment.proj` + +Optional: + +- A test `.csproj` under `src/tests/`; when supplied, merge its effective + `CLRTestEnvironmentVariable` items +- Target OS, architecture, configuration, and runtime flavor +- Output path; default to + `artifacts/tmp/test-scenario-env/.env` + +Default the target OS to the current host, architecture to `x64`, +configuration to `Release`, and runtime flavor to `coreclr`. Use the repro +directory's `.env` path when invoked by `standalone-test-repro`. + +## Workflow + +### 1. Resolve the Scenario + +Read `src/tests/Common/testenvironment.proj` and match the requested name +against `TestEnvironment` item identities. Use the canonical identity from the +project in output and reporting. + +If there is no exact scenario match, use `ask_user` with the closest concrete +scenario names. Do not silently emit an empty environment. If target-dependent +duplicates exist, select them by target OS using the project's conditions. + +Reject scenarios outside managed desktop CoreCLR support for this skill. + +### 2. Evaluate with MSBuild + +Use the `build-and-test` skill before running the repository SDK. Invoke the +repository's bootstrapped `dotnet` to run the `CreateTestEnvFile` target rather +than interpreting scenario metadata manually. + +Generate a temporary script under the same resolved output directory: + +Windows target: + +```text +dotnet.cmd msbuild src\tests\Common\testenvironment.proj /t:CreateTestEnvFile /p:Scenario= /p:TestEnvFileName= /p:TargetsWindows=true /p:RuntimeVariant= +``` + +Non-Windows target: + +```text +./dotnet.sh msbuild src/tests/Common/testenvironment.proj /t:CreateTestEnvFile /p:Scenario= /p:TestEnvFileName= /p:TargetsWindows=false /p:RuntimeVariant= +``` + +Omit `RuntimeVariant` when none was requested. Set `TargetsWindows` from the +target OS, not the host OS. Keep the generated value for random scenarios such +as `jitstress_random_1`; do not replace it with the literal `random`. + +### 3. Convert Scenario Output to Dotenv + +Parse only assignments generated by `testenvironment.proj`: + +- Windows: `set NAME=VALUE` +- Non-Windows: `export NAME=VALUE` + +Ignore the shell shebang and other non-assignment lines. Preserve empty values +as `NAME=` and collapse duplicate names using the last generated value. + +Write portable dotenv entries as `NAME=VALUE`, one per line. Quote or escape +whitespace, `#`, quotes, backslashes, newlines, and variable-expansion syntax +according to `src/coreclr/hosts/corerun/dotenv.cpp`. Preserve literal wildcard +and dump-path values emitted by MSBuild. + +Delete only the specifically resolved temporary script after conversion. + +### 4. Merge Test-Project Variables + +When a test `.csproj` was supplied, evaluate its effective +`CLRTestEnvironmentVariable` items for the selected target OS, architecture, +configuration, and runtime flavor, including applicable imports and +conditions. + +Merge in runtime-wrapper order: + +1. Scenario variables from `testenvironment.proj` +2. Test-project `CLRTestEnvironmentVariable` items + +Project values replace scenario values with the same name, including replacing +them with an empty value. This matches runtime wrapper behavior, which sources +`__TestEnv` before applying `CLRTestEnvironmentVariable`. + +Do not include the ambient process environment, CI credentials, or unrelated +MSBuild properties. Do not leave unevaluated expressions such as +`$(SomeProperty)` in the file. + +### 5. Validate + +Before completing: + +1. Confirm the scenario exists for the selected target. +2. Compare scenario entries with the temporary script before deleting it. +3. If a project was supplied, compare merged entries with its effective + `CLRTestEnvironmentVariable` items and verify project precedence. +4. Confirm `corerun -e ` can parse the generated file when a matching + Core_Root is available. +5. Confirm the output is under `artifacts/tmp` unless the user explicitly chose + another safe path. + +## Final Response + +Report the canonical scenario, output `.env` path, target OS and architecture, +and variable names. If a project was merged, report its path and any names whose +scenario values were overridden. Do not unnecessarily print sensitive values. From df49e5b427ca8b3523bdddd3724c7fd702845de2 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Thu, 13 Aug 2026 16:00:24 -0700 Subject: [PATCH 2/2] Address standalone repro skill feedback Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 909db69e-bf77-405e-8010-9fbcea0fe9d2 --- .github/skills/standalone-test-repro/SKILL.md | 2 +- .github/skills/test-scenario-env/SKILL.md | 23 +++++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/.github/skills/standalone-test-repro/SKILL.md b/.github/skills/standalone-test-repro/SKILL.md index 82bcd298d73efc..6a6f221fabb321 100644 --- a/.github/skills/standalone-test-repro/SKILL.md +++ b/.github/skills/standalone-test-repro/SKILL.md @@ -229,7 +229,7 @@ Build with the repository's bootstrapped SDK from the repository root. Use a dedicated output directory inside the repro: ```text -dotnet.cmd build artifacts\tmp\standalone-test-repro\\StandaloneTestRepro.csproj -c Release -o artifacts\tmp\standalone-test-repro\\out +.\dotnet.cmd build artifacts\tmp\standalone-test-repro\\StandaloneTestRepro.csproj -c Release -o artifacts\tmp\standalone-test-repro\\out ``` On Unix, use `./dotnet.sh` and Unix path separators. diff --git a/.github/skills/test-scenario-env/SKILL.md b/.github/skills/test-scenario-env/SKILL.md index 9470902d0d46d7..a1d58b46fcfac3 100644 --- a/.github/skills/test-scenario-env/SKILL.md +++ b/.github/skills/test-scenario-env/SKILL.md @@ -65,7 +65,7 @@ Generate a temporary script under the same resolved output directory: Windows target: ```text -dotnet.cmd msbuild src\tests\Common\testenvironment.proj /t:CreateTestEnvFile /p:Scenario= /p:TestEnvFileName= /p:TargetsWindows=true /p:RuntimeVariant= +.\dotnet.cmd msbuild src\tests\Common\testenvironment.proj /t:CreateTestEnvFile /p:Scenario= /p:TestEnvFileName= /p:TargetsWindows=true /p:RuntimeVariant= ``` Non-Windows target: @@ -88,10 +88,24 @@ Parse only assignments generated by `testenvironment.proj`: Ignore the shell shebang and other non-assignment lines. Preserve empty values as `NAME=` and collapse duplicate names using the last generated value. +Convert assignment values from the target shell's syntax to CoreRun dotenv +syntax; do not copy the shell text verbatim: + +- Use the value written to the generated script. MSBuild decodes escaped item + metadata before writing it, so `%2A` in `testenvironment.proj` is emitted as + the literal wildcard `*`. +- For non-Windows scripts, convert shell variable references such as `$NAME` or + `${NAME}` to CoreRun's supported `${NAME}` form. Do not expand them from the + ambient environment while generating the file. For example, convert + `$HELIX_DUMP_FOLDER/coredump.%d.dmp` to + `${HELIX_DUMP_FOLDER}/coredump.%d.dmp`. +- Preserve non-expansion format tokens such as `%d`. Protect a literal `$` with + single-quote escaping so CoreRun does not interpret it as substitution. + Write portable dotenv entries as `NAME=VALUE`, one per line. Quote or escape whitespace, `#`, quotes, backslashes, newlines, and variable-expansion syntax -according to `src/coreclr/hosts/corerun/dotenv.cpp`. Preserve literal wildcard -and dump-path values emitted by MSBuild. +according to `src/coreclr/hosts/corerun/dotenv.cpp`. Never leave an unbraced +`$NAME` reference in the generated `.env`. Delete only the specifically resolved temporary script after conversion. @@ -120,7 +134,8 @@ MSBuild properties. Do not leave unevaluated expressions such as Before completing: 1. Confirm the scenario exists for the selected target. -2. Compare scenario entries with the temporary script before deleting it. +2. Compare scenario entries with the temporary script after applying the + documented shell-to-dotenv normalization, before deleting it. 3. If a project was supplied, compare merged entries with its effective `CLRTestEnvironmentVariable` items and verify project precedence. 4. Confirm `corerun -e ` can parse the generated file when a matching