From e38d198f2306eaa5917c4522465b9fc70b0b74f9 Mon Sep 17 00:00:00 2001 From: clockwork-labs-bot Date: Mon, 15 Jun 2026 18:41:54 -0400 Subject: [PATCH 1/9] Add LLM benchmark publish diagnostics --- .github/workflows/llm-benchmark-periodic.yml | 14 +++ .../src/bench/publishers.rs | 107 +++++++++++++++++- 2 files changed, 120 insertions(+), 1 deletion(-) diff --git a/.github/workflows/llm-benchmark-periodic.yml b/.github/workflows/llm-benchmark-periodic.yml index da3af16b609..108d9c02c61 100644 --- a/.github/workflows/llm-benchmark-periodic.yml +++ b/.github/workflows/llm-benchmark-periodic.yml @@ -72,7 +72,9 @@ jobs: DOTNET_CLI_HOME: ${{ runner.temp }}/dotnet-home DOTNET_SKIP_FIRST_TIME_EXPERIENCE: "1" run: | + dotnet --info dotnet workload install wasi-experimental --skip-manifest-update --disable-parallel + dotnet workload list - name: Pack C# runtime packages if: ${{ github.event_name != 'workflow_dispatch' || contains(inputs.languages || 'rust,csharp,typescript', 'csharp') }} @@ -121,6 +123,8 @@ jobs: MSBUILDDISABLENODEREUSE: "1" DOTNET_CLI_USE_MSBUILD_SERVER: "0" LLM_BENCH_CSHARP_CONCURRENCY: "1" + LLM_DEBUG: "1" + LLM_DEBUG_VERBOSE: "1" INPUT_LANGUAGES: ${{ inputs.languages || 'rust,csharp,typescript' }} INPUT_MODEL_SET: ${{ inputs.model_set || 'website_active' }} INPUT_MODELS: ${{ inputs.models || '' }} @@ -205,3 +209,13 @@ jobs: echo "::error::$FAILED benchmark run(s) failed" exit 1 fi + + - name: Upload LLM benchmark debug artifacts + if: failure() + uses: actions/upload-artifact@v4 + with: + name: llm-benchmark-debug-${{ github.run_id }}-${{ github.run_attempt }} + path: | + target/llm-runs + target/llm-dry-run-analysis + if-no-files-found: ignore diff --git a/tools/xtask-llm-benchmark/src/bench/publishers.rs b/tools/xtask-llm-benchmark/src/bench/publishers.rs index 92622972114..6929e27cb1d 100644 --- a/tools/xtask-llm-benchmark/src/bench/publishers.rs +++ b/tools/xtask-llm-benchmark/src/bench/publishers.rs @@ -1,8 +1,9 @@ -use crate::bench::utils::sanitize_db_name; +use crate::bench::utils::{debug_llm, debug_llm_verbose, sanitize_db_name}; use anyhow::{bail, Context, Result}; use regex::Regex; use std::borrow::Cow; use std::env; +use std::ffi::OsStr; use std::fs; use std::path::{Path, PathBuf}; use std::process::Command; @@ -238,6 +239,33 @@ fn is_transient_build_error(stderr: &str, stdout: &str) -> bool { || combined.contains("code String { + value.to_string_lossy().into_owned() +} + +fn log_command_context(cmd: &Command, label: &str) { + eprintln!("⚠️ {label}: program: {}", os_string(cmd.get_program())); + let args: Vec<_> = cmd.get_args().map(os_string).collect(); + eprintln!("⚠️ {label}: args: {:?}", args); + eprintln!( + "⚠️ {label}: cwd: {}", + cmd.get_current_dir() + .map(|path| path.display().to_string()) + .unwrap_or_else(|| env::current_dir() + .map(|path| path.display().to_string()) + .unwrap_or_default()) + ); + + let env_overrides: Vec<_> = cmd + .get_envs() + .map(|(key, value)| { + let value = value.map(os_string).unwrap_or_else(|| "".to_string()); + format!("{}={value}", os_string(key)) + }) + .collect(); + eprintln!("⚠️ {label}: env overrides: {:?}", env_overrides); +} + fn run(cmd: &mut Command, label: &str) -> Result<()> { run_with_retry(cmd, label, 3) } @@ -276,6 +304,8 @@ fn run_with_retry(cmd: &mut Command, label: &str, max_retries: u32) -> Result<() return Ok(()); } + log_command_context(cmd, label); + let code = out.status.code().unwrap_or(-1); let stderr_raw = String::from_utf8_lossy(&out.stderr); let stdout_raw = String::from_utf8_lossy(&out.stdout); @@ -330,11 +360,83 @@ impl DotnetPublisher { fn configure_dotnet_env(cmd: &mut Command) -> &mut Command { cmd.env("DOTNET_CLI_TELEMETRY_OPTOUT", "1") .env("DOTNET_NOLOGO", "1") + .env("DOTNET_CLI_CONTEXT_VERBOSE", "1") // Prevent MSBuild node reuse issues that cause "Pipe is broken" errors // when running multiple dotnet builds in parallel. .env("MSBUILDDISABLENODEREUSE", "1") .env("DOTNET_CLI_USE_MSBUILD_SERVER", "0") } + + fn log_dotnet_probe(args: &[&str], label: &str) { + let mut cmd = Command::new("dotnet"); + cmd.args(args); + Self::configure_dotnet_env(&mut cmd); + + eprintln!("==> {label}: {:?}", cmd); + match cmd.output() { + Ok(out) => { + let stdout_raw = String::from_utf8_lossy(&out.stdout); + let stderr_raw = String::from_utf8_lossy(&out.stderr); + let stdout = strip_ansi_codes(&stdout_raw); + let stderr = strip_ansi_codes(&stderr_raw); + eprintln!("--- {label} status ---\n{}", out.status); + eprintln!("--- {label} stdout ---\n{stdout}"); + eprintln!("--- {label} stderr ---\n{stderr}"); + } + Err(error) => eprintln!("--- {label} failed to start ---\n{error}"), + } + } + + fn log_csharp_source_context(source: &Path) -> Result<()> { + eprintln!("C# publish source: {}", source.display()); + + let mut entries = Vec::new(); + for ent in fs::read_dir(source).with_context(|| format!("failed to read {}", source.display()))? { + let ent = ent?; + let path = ent.path(); + let kind = if path.is_dir() { "dir" } else { "file" }; + entries.push(format!("{kind}: {}", path.display())); + } + entries.sort(); + eprintln!("C# publish source top-level entries:\n{}", entries.join("\n")); + + let mut project_files = Vec::new(); + for ent in fs::read_dir(source)? { + let ent = ent?; + let path = ent.path(); + if path.extension().is_some_and(|ext| ext == "csproj") { + project_files.push(path); + } + } + project_files.sort(); + for path in project_files { + match fs::read_to_string(&path) { + Ok(contents) => { + let contents: String = contents.chars().take(16_000).collect(); + eprintln!("--- {} ---\n{contents}", path.display()); + } + Err(error) => eprintln!("failed to read {}: {error}", path.display()), + } + } + + for file_name in ["NuGet.config", "nuget.config", "global.json"] { + let path = source.join(file_name); + if path.exists() { + match fs::read_to_string(&path) { + Ok(contents) => eprintln!("--- {} ---\n{contents}", path.display()), + Err(error) => eprintln!("failed to read {}: {error}", path.display()), + } + } + } + + if debug_llm_verbose() { + Self::log_dotnet_probe(&["--info"], "dotnet --info"); + Self::log_dotnet_probe(&["workload", "list"], "dotnet workload list"); + Self::log_dotnet_probe(&["nuget", "locals", "all", "--list"], "dotnet nuget locals all --list"); + } + + Ok(()) + } } impl Publisher for DotnetPublisher { @@ -345,6 +447,9 @@ impl Publisher for DotnetPublisher { println!("publish csharp module {}", module_name); Self::ensure_csproj(source)?; + if debug_llm() { + Self::log_csharp_source_context(source)?; + } let db = sanitize_db_name(module_name); let source = source From a76e5771fddf21d095bcd1eb8a5474ae28239cbb Mon Sep 17 00:00:00 2001 From: clockwork-labs-bot Date: Mon, 15 Jun 2026 19:03:25 -0400 Subject: [PATCH 2/9] Skip duplicate C# workload probe in benchmarks --- crates/cli/src/tasks/csharp.rs | 80 ++++++++++--------- .../src/bench/publishers.rs | 4 + 2 files changed, 45 insertions(+), 39 deletions(-) diff --git a/crates/cli/src/tasks/csharp.rs b/crates/cli/src/tasks/csharp.rs index 5df8b730448..0d070984c64 100644 --- a/crates/cli/src/tasks/csharp.rs +++ b/crates/cli/src/tasks/csharp.rs @@ -17,46 +17,48 @@ pub(crate) fn build_csharp(project_path: &Path, build_debug: bool) -> anyhow::Re }; } - // Check if the `wasi-experimental` workload is installed. Unfortunately, we - // have to do this by inspecting the human-readable output. There is a - // hidden `--machine-readable` flag but it also mixes in human-readable - // output as well as unnecessarily updates various unrelated manifests. - match dotnet!("workload", "list").read() { - Ok(workloads) if workloads.contains("wasi-experimental") => {} - Ok(_) => { - // If wasi-experimental is not found, first check if we're running - // on .NET SDK 8.0. We can't even install that workload on older - // versions, and we don't support .NET 9.0 yet, so this helps to - // provide a nicer message than "Workload ID wasi-experimental is not recognized.". - let version = dotnet!("--version").read().unwrap_or_default(); - if parse_major_version(&version) != Some(8) { - anyhow::bail!(concat!( - ".NET SDK 8.0 is required, but found {version}.\n", - "If you have multiple versions of .NET SDK installed, configure your project using https://learn.microsoft.com/en-us/dotnet/core/tools/global-json." - )); - } + if std::env::var_os("SPACETIME_SKIP_DOTNET_WORKLOAD_CHECK").is_none() { + // Check if the `wasi-experimental` workload is installed. Unfortunately, we + // have to do this by inspecting the human-readable output. There is a + // hidden `--machine-readable` flag but it also mixes in human-readable + // output as well as unnecessarily updates various unrelated manifests. + match dotnet!("workload", "list").read() { + Ok(workloads) if workloads.contains("wasi-experimental") => {} + Ok(_) => { + // If wasi-experimental is not found, first check if we're running + // on .NET SDK 8.0. We can't even install that workload on older + // versions, and we don't support .NET 9.0 yet, so this helps to + // provide a nicer message than "Workload ID wasi-experimental is not recognized.". + let version = dotnet!("--version").read().unwrap_or_default(); + if parse_major_version(&version) != Some(8) { + anyhow::bail!(concat!( + ".NET SDK 8.0 is required, but found {version}.\n", + "If you have multiple versions of .NET SDK installed, configure your project using https://learn.microsoft.com/en-us/dotnet/core/tools/global-json." + )); + } - // Finally, try to install the workload ourselves. On some systems - // this might require elevated privileges, so print a nice error - // message if it fails. - dotnet!( - "workload", - "install", - "wasi-experimental", - "--skip-manifest-update" - ) - .stderr_capture() - .run() - .context(concat!( - "Couldn't install the required wasi-experimental workload.\n", - "You might need to install it manually by running `dotnet workload install wasi-experimental` with privileged rights." - ))?; - } - Err(error) if error.kind() == std::io::ErrorKind::NotFound => { - anyhow::bail!("dotnet not found in PATH. Please install .NET SDK 8.0.") - } - Err(error) => anyhow::bail!("{error}"), - }; + // Finally, try to install the workload ourselves. On some systems + // this might require elevated privileges, so print a nice error + // message if it fails. + dotnet!( + "workload", + "install", + "wasi-experimental", + "--skip-manifest-update" + ) + .stderr_capture() + .run() + .context(concat!( + "Couldn't install the required wasi-experimental workload.\n", + "You might need to install it manually by running `dotnet workload install wasi-experimental` with privileged rights." + ))?; + } + Err(error) if error.kind() == std::io::ErrorKind::NotFound => { + anyhow::bail!("dotnet not found in PATH. Please install .NET SDK 8.0.") + } + Err(error) => anyhow::bail!("{error}"), + }; + } let config_name = if build_debug { "Debug" } else { "Release" }; diff --git a/tools/xtask-llm-benchmark/src/bench/publishers.rs b/tools/xtask-llm-benchmark/src/bench/publishers.rs index 6929e27cb1d..def8212f4a3 100644 --- a/tools/xtask-llm-benchmark/src/bench/publishers.rs +++ b/tools/xtask-llm-benchmark/src/bench/publishers.rs @@ -365,6 +365,10 @@ impl DotnetPublisher { // when running multiple dotnet builds in parallel. .env("MSBUILDDISABLENODEREUSE", "1") .env("DOTNET_CLI_USE_MSBUILD_SERVER", "0") + // The workflow has already installed and verified wasi-experimental. + // Avoid the CLI's duplicate `dotnet workload list` probe, which can + // crash in CI before we reach the actual generated module build. + .env("SPACETIME_SKIP_DOTNET_WORKLOAD_CHECK", "1") } fn log_dotnet_probe(args: &[&str], label: &str) { From cc46eae1288beacfea226cfb9f93aeb3c25614c1 Mon Sep 17 00:00:00 2001 From: clockwork-labs-bot Date: Mon, 15 Jun 2026 19:11:40 -0400 Subject: [PATCH 3/9] Improve C# benchmark publish diagnostics --- crates/cli/src/tasks/csharp.rs | 4 ++-- tools/xtask-llm-benchmark/src/bench/publishers.rs | 8 ++++++++ tools/xtask-llm-benchmark/src/bench/templates.rs | 3 +++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/crates/cli/src/tasks/csharp.rs b/crates/cli/src/tasks/csharp.rs index 0d070984c64..bf16c34b0e3 100644 --- a/crates/cli/src/tasks/csharp.rs +++ b/crates/cli/src/tasks/csharp.rs @@ -70,8 +70,8 @@ pub(crate) fn build_csharp(project_path: &Path, build_debug: bool) -> anyhow::Re ) })?; - // run dotnet publish using cmd macro - dotnet!("publish", "-c", config_name, "-v", "quiet").run()?; + let publish_verbosity = std::env::var("SPACETIME_DOTNET_PUBLISH_VERBOSITY").unwrap_or_else(|_| "quiet".to_string()); + dotnet!("publish", "-c", config_name, "-v", publish_verbosity.as_str()).run()?; // check if file exists let subdir = if std::env::var_os("EXPERIMENTAL_WASM_AOT").is_some_and(|v| v == "1") { diff --git a/tools/xtask-llm-benchmark/src/bench/publishers.rs b/tools/xtask-llm-benchmark/src/bench/publishers.rs index def8212f4a3..99b21561659 100644 --- a/tools/xtask-llm-benchmark/src/bench/publishers.rs +++ b/tools/xtask-llm-benchmark/src/bench/publishers.rs @@ -369,6 +369,7 @@ impl DotnetPublisher { // Avoid the CLI's duplicate `dotnet workload list` probe, which can // crash in CI before we reach the actual generated module build. .env("SPACETIME_SKIP_DOTNET_WORKLOAD_CHECK", "1") + .env("SPACETIME_DOTNET_PUBLISH_VERBOSITY", "normal") } fn log_dotnet_probe(args: &[&str], label: &str) { @@ -473,6 +474,13 @@ impl Publisher for DotnetPublisher { .arg(&db) .current_dir(&source); Self::configure_dotnet_env(&mut pubcmd); + pubcmd + .env("DOTNET_DbgEnableMiniDump", "1") + .env("DOTNET_DbgMiniDumpType", "4") + .env( + "DOTNET_DbgMiniDumpName", + source.join("dotnet-dump-%p").display().to_string(), + ); run(&mut pubcmd, "spacetime publish (csharp)")?; Ok(()) diff --git a/tools/xtask-llm-benchmark/src/bench/templates.rs b/tools/xtask-llm-benchmark/src/bench/templates.rs index 35176de8200..9a9519c3a99 100644 --- a/tools/xtask-llm-benchmark/src/bench/templates.rs +++ b/tools/xtask-llm-benchmark/src/bench/templates.rs @@ -213,6 +213,9 @@ fn ensure_csharp_package_source(path: &Path, package_id: &str) -> Result<()> { fn write_csharp_nuget_config(root: &Path) -> Result<()> { let workspace = workspace_root(); + let root = root + .canonicalize() + .with_context(|| format!("canonicalize {}", root.display()))?; let runtime_source = workspace.join("crates/bindings-csharp/Runtime/bin/Release"); let bsatn_source = workspace.join("crates/bindings-csharp/BSATN.Runtime/bin/Release"); From 4fca6b487b22cb5ee01ea6b1e797f64e82976e22 Mon Sep 17 00:00:00 2001 From: clockwork-labs-bot Date: Mon, 15 Jun 2026 19:21:15 -0400 Subject: [PATCH 4/9] Pin LLM benchmark .NET SDK to 8.x --- .github/workflows/llm-benchmark-periodic.yml | 2 +- .github/workflows/llm-benchmark-validate-goldens.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/llm-benchmark-periodic.yml b/.github/workflows/llm-benchmark-periodic.yml index 108d9c02c61..f10d74adaa6 100644 --- a/.github/workflows/llm-benchmark-periodic.yml +++ b/.github/workflows/llm-benchmark-periodic.yml @@ -64,7 +64,7 @@ jobs: - name: Setup .NET SDK uses: actions/setup-dotnet@v4 with: - global-json-file: global.json + dotnet-version: "8.0.x" - name: Install WASI workload env: diff --git a/.github/workflows/llm-benchmark-validate-goldens.yml b/.github/workflows/llm-benchmark-validate-goldens.yml index a2d2ef87a3e..79c9d748932 100644 --- a/.github/workflows/llm-benchmark-validate-goldens.yml +++ b/.github/workflows/llm-benchmark-validate-goldens.yml @@ -47,7 +47,7 @@ jobs: if: matrix.lang == 'csharp' uses: actions/setup-dotnet@v4 with: - global-json-file: global.json + dotnet-version: "8.0.x" - name: Install WASI workload if: matrix.lang == 'csharp' From a1e7435e87d36c2f47a7e418468b9ef0661b3216 Mon Sep 17 00:00:00 2001 From: clockwork-labs-bot Date: Mon, 15 Jun 2026 19:33:15 -0400 Subject: [PATCH 5/9] Install isolated .NET 8 for LLM benchmarks --- .github/workflows/llm-benchmark-periodic.yml | 10 +++++++--- .github/workflows/llm-benchmark-validate-goldens.yml | 10 +++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/.github/workflows/llm-benchmark-periodic.yml b/.github/workflows/llm-benchmark-periodic.yml index f10d74adaa6..b47366a8ac7 100644 --- a/.github/workflows/llm-benchmark-periodic.yml +++ b/.github/workflows/llm-benchmark-periodic.yml @@ -62,9 +62,13 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Setup .NET SDK - uses: actions/setup-dotnet@v4 - with: - dotnet-version: "8.0.x" + run: | + DOTNET_INSTALL_DIR="${RUNNER_TEMP}/dotnet-8" + curl -fsSL https://dot.net/v1/dotnet-install.sh -o dotnet-install.sh + bash dotnet-install.sh --channel 8.0 --install-dir "$DOTNET_INSTALL_DIR" --no-path + echo "DOTNET_ROOT=$DOTNET_INSTALL_DIR" >> "$GITHUB_ENV" + echo "$DOTNET_INSTALL_DIR" >> "$GITHUB_PATH" + "$DOTNET_INSTALL_DIR/dotnet" --info - name: Install WASI workload env: diff --git a/.github/workflows/llm-benchmark-validate-goldens.yml b/.github/workflows/llm-benchmark-validate-goldens.yml index 79c9d748932..ce4f1b1cf65 100644 --- a/.github/workflows/llm-benchmark-validate-goldens.yml +++ b/.github/workflows/llm-benchmark-validate-goldens.yml @@ -45,9 +45,13 @@ jobs: - name: Setup .NET SDK if: matrix.lang == 'csharp' - uses: actions/setup-dotnet@v4 - with: - dotnet-version: "8.0.x" + run: | + DOTNET_INSTALL_DIR="${RUNNER_TEMP}/dotnet-8" + curl -fsSL https://dot.net/v1/dotnet-install.sh -o dotnet-install.sh + bash dotnet-install.sh --channel 8.0 --install-dir "$DOTNET_INSTALL_DIR" --no-path + echo "DOTNET_ROOT=$DOTNET_INSTALL_DIR" >> "$GITHUB_ENV" + echo "$DOTNET_INSTALL_DIR" >> "$GITHUB_PATH" + "$DOTNET_INSTALL_DIR/dotnet" --info - name: Install WASI workload if: matrix.lang == 'csharp' From caa3e66c4c15900f402bcd79873d961a288c42b9 Mon Sep 17 00:00:00 2001 From: clockwork-labs-bot Date: Mon, 15 Jun 2026 19:45:50 -0400 Subject: [PATCH 6/9] Analyze C# publish crash dumps --- .github/workflows/llm-benchmark-periodic.yml | 35 +++++++++++++++++++ crates/cli/src/tasks/csharp.rs | 15 +++++++- .../src/bench/publishers.rs | 3 +- 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/.github/workflows/llm-benchmark-periodic.yml b/.github/workflows/llm-benchmark-periodic.yml index b47366a8ac7..e1baa3fa738 100644 --- a/.github/workflows/llm-benchmark-periodic.yml +++ b/.github/workflows/llm-benchmark-periodic.yml @@ -214,6 +214,41 @@ jobs: exit 1 fi + - name: Analyze .NET crash dumps + if: failure() + run: | + set +e + mkdir -p target/llm-dry-run-analysis/dotnet-dumps + + mapfile -t DUMPS < <(find target/llm-runs -type f -name 'dotnet-dump-*' 2>/dev/null | sort) + if [ "${#DUMPS[@]}" -eq 0 ]; then + echo "No .NET crash dumps found." + exit 0 + fi + + TOOL_DIR="${RUNNER_TEMP}/dotnet-tools" + mkdir -p "$TOOL_DIR" + if ! dotnet tool install --tool-path "$TOOL_DIR" dotnet-dump; then + echo "::warning::failed to install dotnet-dump; raw dumps will still be uploaded" + exit 0 + fi + + for DUMP in "${DUMPS[@]}"; do + SAFE_NAME="$(echo "$DUMP" | tr '/ ' '__')" + OUT="target/llm-dry-run-analysis/dotnet-dumps/${SAFE_NAME}.txt" + { + echo "Dump: $DUMP" + echo + "$TOOL_DIR/dotnet-dump" analyze "$DUMP" \ + --command "clrthreads" \ + --command "threads" \ + --command "clrstack -all" \ + --command "pe" \ + --command "exit" + } > "$OUT" 2>&1 + cat "$OUT" + done + - name: Upload LLM benchmark debug artifacts if: failure() uses: actions/upload-artifact@v4 diff --git a/crates/cli/src/tasks/csharp.rs b/crates/cli/src/tasks/csharp.rs index bf16c34b0e3..27bddd57f2d 100644 --- a/crates/cli/src/tasks/csharp.rs +++ b/crates/cli/src/tasks/csharp.rs @@ -71,7 +71,20 @@ pub(crate) fn build_csharp(project_path: &Path, build_debug: bool) -> anyhow::Re })?; let publish_verbosity = std::env::var("SPACETIME_DOTNET_PUBLISH_VERBOSITY").unwrap_or_else(|_| "quiet".to_string()); - dotnet!("publish", "-c", config_name, "-v", publish_verbosity.as_str()).run()?; + let mut publish_args = vec![ + OsString::from("publish"), + OsString::from("-c"), + OsString::from(config_name), + OsString::from("-v"), + OsString::from(publish_verbosity), + ]; + if std::env::var_os("SPACETIME_DOTNET_PUBLISH_BINLOG").is_some() { + publish_args.push(OsString::from(format!( + "/bl:{}", + project_path.join("dotnet-publish.binlog").display() + ))); + } + duct::cmd("dotnet", publish_args).dir(project_path).run()?; // check if file exists let subdir = if std::env::var_os("EXPERIMENTAL_WASM_AOT").is_some_and(|v| v == "1") { diff --git a/tools/xtask-llm-benchmark/src/bench/publishers.rs b/tools/xtask-llm-benchmark/src/bench/publishers.rs index 99b21561659..925cbc65a9d 100644 --- a/tools/xtask-llm-benchmark/src/bench/publishers.rs +++ b/tools/xtask-llm-benchmark/src/bench/publishers.rs @@ -480,7 +480,8 @@ impl Publisher for DotnetPublisher { .env( "DOTNET_DbgMiniDumpName", source.join("dotnet-dump-%p").display().to_string(), - ); + ) + .env("SPACETIME_DOTNET_PUBLISH_BINLOG", "1"); run(&mut pubcmd, "spacetime publish (csharp)")?; Ok(()) From b90bb520ffc21606a95c9e73e8a98582cbaedbc5 Mon Sep 17 00:00:00 2001 From: clockwork-labs-bot Date: Mon, 15 Jun 2026 19:55:14 -0400 Subject: [PATCH 7/9] Avoid .NET globalization crash in LLM benchmarks --- .github/workflows/llm-benchmark-periodic.yml | 6 ++++++ .github/workflows/llm-benchmark-validate-goldens.yml | 6 ++++++ tools/xtask-llm-benchmark/src/bench/publishers.rs | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/llm-benchmark-periodic.yml b/.github/workflows/llm-benchmark-periodic.yml index e1baa3fa738..62b46116382 100644 --- a/.github/workflows/llm-benchmark-periodic.yml +++ b/.github/workflows/llm-benchmark-periodic.yml @@ -62,6 +62,8 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Setup .NET SDK + env: + DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: "1" run: | DOTNET_INSTALL_DIR="${RUNNER_TEMP}/dotnet-8" curl -fsSL https://dot.net/v1/dotnet-install.sh -o dotnet-install.sh @@ -75,6 +77,7 @@ jobs: DOTNET_MULTILEVEL_LOOKUP: "0" DOTNET_CLI_HOME: ${{ runner.temp }}/dotnet-home DOTNET_SKIP_FIRST_TIME_EXPERIENCE: "1" + DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: "1" run: | dotnet --info dotnet workload install wasi-experimental --skip-manifest-update --disable-parallel @@ -82,6 +85,8 @@ jobs: - name: Pack C# runtime packages if: ${{ github.event_name != 'workflow_dispatch' || contains(inputs.languages || 'rust,csharp,typescript', 'csharp') }} + env: + DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: "1" run: | dotnet pack -c Release crates/bindings-csharp/BSATN.Runtime dotnet pack -c Release crates/bindings-csharp/Runtime @@ -124,6 +129,7 @@ jobs: DOTNET_MULTILEVEL_LOOKUP: "0" DOTNET_CLI_HOME: ${{ runner.temp }}/dotnet-home DOTNET_SKIP_FIRST_TIME_EXPERIENCE: "1" + DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: "1" MSBUILDDISABLENODEREUSE: "1" DOTNET_CLI_USE_MSBUILD_SERVER: "0" LLM_BENCH_CSHARP_CONCURRENCY: "1" diff --git a/.github/workflows/llm-benchmark-validate-goldens.yml b/.github/workflows/llm-benchmark-validate-goldens.yml index ce4f1b1cf65..26571007b6b 100644 --- a/.github/workflows/llm-benchmark-validate-goldens.yml +++ b/.github/workflows/llm-benchmark-validate-goldens.yml @@ -45,6 +45,8 @@ jobs: - name: Setup .NET SDK if: matrix.lang == 'csharp' + env: + DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: "1" run: | DOTNET_INSTALL_DIR="${RUNNER_TEMP}/dotnet-8" curl -fsSL https://dot.net/v1/dotnet-install.sh -o dotnet-install.sh @@ -59,11 +61,14 @@ jobs: DOTNET_MULTILEVEL_LOOKUP: "0" DOTNET_CLI_HOME: ${{ runner.temp }}/dotnet-home DOTNET_SKIP_FIRST_TIME_EXPERIENCE: "1" + DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: "1" run: | dotnet workload install wasi-experimental --skip-manifest-update --disable-parallel - name: Pack C# runtime packages if: matrix.lang == 'csharp' + env: + DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: "1" run: | dotnet pack -c Release crates/bindings-csharp/BSATN.Runtime dotnet pack -c Release crates/bindings-csharp/Runtime @@ -100,6 +105,7 @@ jobs: DOTNET_MULTILEVEL_LOOKUP: "0" DOTNET_CLI_HOME: ${{ runner.temp }}/dotnet-home DOTNET_SKIP_FIRST_TIME_EXPERIENCE: "1" + DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: "1" MSBUILDDISABLENODEREUSE: "1" DOTNET_CLI_USE_MSBUILD_SERVER: "0" LLM_BENCH_CSHARP_CONCURRENCY: "1" diff --git a/tools/xtask-llm-benchmark/src/bench/publishers.rs b/tools/xtask-llm-benchmark/src/bench/publishers.rs index 925cbc65a9d..32d10397018 100644 --- a/tools/xtask-llm-benchmark/src/bench/publishers.rs +++ b/tools/xtask-llm-benchmark/src/bench/publishers.rs @@ -360,7 +360,7 @@ impl DotnetPublisher { fn configure_dotnet_env(cmd: &mut Command) -> &mut Command { cmd.env("DOTNET_CLI_TELEMETRY_OPTOUT", "1") .env("DOTNET_NOLOGO", "1") - .env("DOTNET_CLI_CONTEXT_VERBOSE", "1") + .env("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT", "1") // Prevent MSBuild node reuse issues that cause "Pipe is broken" errors // when running multiple dotnet builds in parallel. .env("MSBUILDDISABLENODEREUSE", "1") From a2bb7ac3c6d437f62391aa9c0c621e7721f7b9bd Mon Sep 17 00:00:00 2001 From: clockwork-labs-bot Date: Mon, 15 Jun 2026 20:56:10 -0400 Subject: [PATCH 8/9] Slim LLM benchmark C# publish fix --- .github/workflows/llm-benchmark-periodic.yml | 59 +-------- .../llm-benchmark-validate-goldens.yml | 10 +- crates/cli/src/tasks/csharp.rs | 97 ++++++-------- .../src/bench/publishers.rs | 122 +----------------- .../src/bench/templates.rs | 3 - 5 files changed, 51 insertions(+), 240 deletions(-) diff --git a/.github/workflows/llm-benchmark-periodic.yml b/.github/workflows/llm-benchmark-periodic.yml index 62b46116382..5818d93ef33 100644 --- a/.github/workflows/llm-benchmark-periodic.yml +++ b/.github/workflows/llm-benchmark-periodic.yml @@ -64,13 +64,9 @@ jobs: - name: Setup .NET SDK env: DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: "1" - run: | - DOTNET_INSTALL_DIR="${RUNNER_TEMP}/dotnet-8" - curl -fsSL https://dot.net/v1/dotnet-install.sh -o dotnet-install.sh - bash dotnet-install.sh --channel 8.0 --install-dir "$DOTNET_INSTALL_DIR" --no-path - echo "DOTNET_ROOT=$DOTNET_INSTALL_DIR" >> "$GITHUB_ENV" - echo "$DOTNET_INSTALL_DIR" >> "$GITHUB_PATH" - "$DOTNET_INSTALL_DIR/dotnet" --info + uses: actions/setup-dotnet@v4 + with: + global-json-file: global.json - name: Install WASI workload env: @@ -79,9 +75,7 @@ jobs: DOTNET_SKIP_FIRST_TIME_EXPERIENCE: "1" DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: "1" run: | - dotnet --info dotnet workload install wasi-experimental --skip-manifest-update --disable-parallel - dotnet workload list - name: Pack C# runtime packages if: ${{ github.event_name != 'workflow_dispatch' || contains(inputs.languages || 'rust,csharp,typescript', 'csharp') }} @@ -133,8 +127,6 @@ jobs: MSBUILDDISABLENODEREUSE: "1" DOTNET_CLI_USE_MSBUILD_SERVER: "0" LLM_BENCH_CSHARP_CONCURRENCY: "1" - LLM_DEBUG: "1" - LLM_DEBUG_VERBOSE: "1" INPUT_LANGUAGES: ${{ inputs.languages || 'rust,csharp,typescript' }} INPUT_MODEL_SET: ${{ inputs.model_set || 'website_active' }} INPUT_MODELS: ${{ inputs.models || '' }} @@ -219,48 +211,3 @@ jobs: echo "::error::$FAILED benchmark run(s) failed" exit 1 fi - - - name: Analyze .NET crash dumps - if: failure() - run: | - set +e - mkdir -p target/llm-dry-run-analysis/dotnet-dumps - - mapfile -t DUMPS < <(find target/llm-runs -type f -name 'dotnet-dump-*' 2>/dev/null | sort) - if [ "${#DUMPS[@]}" -eq 0 ]; then - echo "No .NET crash dumps found." - exit 0 - fi - - TOOL_DIR="${RUNNER_TEMP}/dotnet-tools" - mkdir -p "$TOOL_DIR" - if ! dotnet tool install --tool-path "$TOOL_DIR" dotnet-dump; then - echo "::warning::failed to install dotnet-dump; raw dumps will still be uploaded" - exit 0 - fi - - for DUMP in "${DUMPS[@]}"; do - SAFE_NAME="$(echo "$DUMP" | tr '/ ' '__')" - OUT="target/llm-dry-run-analysis/dotnet-dumps/${SAFE_NAME}.txt" - { - echo "Dump: $DUMP" - echo - "$TOOL_DIR/dotnet-dump" analyze "$DUMP" \ - --command "clrthreads" \ - --command "threads" \ - --command "clrstack -all" \ - --command "pe" \ - --command "exit" - } > "$OUT" 2>&1 - cat "$OUT" - done - - - name: Upload LLM benchmark debug artifacts - if: failure() - uses: actions/upload-artifact@v4 - with: - name: llm-benchmark-debug-${{ github.run_id }}-${{ github.run_attempt }} - path: | - target/llm-runs - target/llm-dry-run-analysis - if-no-files-found: ignore diff --git a/.github/workflows/llm-benchmark-validate-goldens.yml b/.github/workflows/llm-benchmark-validate-goldens.yml index 26571007b6b..f1f9e2df103 100644 --- a/.github/workflows/llm-benchmark-validate-goldens.yml +++ b/.github/workflows/llm-benchmark-validate-goldens.yml @@ -47,13 +47,9 @@ jobs: if: matrix.lang == 'csharp' env: DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: "1" - run: | - DOTNET_INSTALL_DIR="${RUNNER_TEMP}/dotnet-8" - curl -fsSL https://dot.net/v1/dotnet-install.sh -o dotnet-install.sh - bash dotnet-install.sh --channel 8.0 --install-dir "$DOTNET_INSTALL_DIR" --no-path - echo "DOTNET_ROOT=$DOTNET_INSTALL_DIR" >> "$GITHUB_ENV" - echo "$DOTNET_INSTALL_DIR" >> "$GITHUB_PATH" - "$DOTNET_INSTALL_DIR/dotnet" --info + uses: actions/setup-dotnet@v4 + with: + global-json-file: global.json - name: Install WASI workload if: matrix.lang == 'csharp' diff --git a/crates/cli/src/tasks/csharp.rs b/crates/cli/src/tasks/csharp.rs index 27bddd57f2d..5df8b730448 100644 --- a/crates/cli/src/tasks/csharp.rs +++ b/crates/cli/src/tasks/csharp.rs @@ -17,48 +17,46 @@ pub(crate) fn build_csharp(project_path: &Path, build_debug: bool) -> anyhow::Re }; } - if std::env::var_os("SPACETIME_SKIP_DOTNET_WORKLOAD_CHECK").is_none() { - // Check if the `wasi-experimental` workload is installed. Unfortunately, we - // have to do this by inspecting the human-readable output. There is a - // hidden `--machine-readable` flag but it also mixes in human-readable - // output as well as unnecessarily updates various unrelated manifests. - match dotnet!("workload", "list").read() { - Ok(workloads) if workloads.contains("wasi-experimental") => {} - Ok(_) => { - // If wasi-experimental is not found, first check if we're running - // on .NET SDK 8.0. We can't even install that workload on older - // versions, and we don't support .NET 9.0 yet, so this helps to - // provide a nicer message than "Workload ID wasi-experimental is not recognized.". - let version = dotnet!("--version").read().unwrap_or_default(); - if parse_major_version(&version) != Some(8) { - anyhow::bail!(concat!( - ".NET SDK 8.0 is required, but found {version}.\n", - "If you have multiple versions of .NET SDK installed, configure your project using https://learn.microsoft.com/en-us/dotnet/core/tools/global-json." - )); - } - - // Finally, try to install the workload ourselves. On some systems - // this might require elevated privileges, so print a nice error - // message if it fails. - dotnet!( - "workload", - "install", - "wasi-experimental", - "--skip-manifest-update" - ) - .stderr_capture() - .run() - .context(concat!( - "Couldn't install the required wasi-experimental workload.\n", - "You might need to install it manually by running `dotnet workload install wasi-experimental` with privileged rights." - ))?; - } - Err(error) if error.kind() == std::io::ErrorKind::NotFound => { - anyhow::bail!("dotnet not found in PATH. Please install .NET SDK 8.0.") + // Check if the `wasi-experimental` workload is installed. Unfortunately, we + // have to do this by inspecting the human-readable output. There is a + // hidden `--machine-readable` flag but it also mixes in human-readable + // output as well as unnecessarily updates various unrelated manifests. + match dotnet!("workload", "list").read() { + Ok(workloads) if workloads.contains("wasi-experimental") => {} + Ok(_) => { + // If wasi-experimental is not found, first check if we're running + // on .NET SDK 8.0. We can't even install that workload on older + // versions, and we don't support .NET 9.0 yet, so this helps to + // provide a nicer message than "Workload ID wasi-experimental is not recognized.". + let version = dotnet!("--version").read().unwrap_or_default(); + if parse_major_version(&version) != Some(8) { + anyhow::bail!(concat!( + ".NET SDK 8.0 is required, but found {version}.\n", + "If you have multiple versions of .NET SDK installed, configure your project using https://learn.microsoft.com/en-us/dotnet/core/tools/global-json." + )); } - Err(error) => anyhow::bail!("{error}"), - }; - } + + // Finally, try to install the workload ourselves. On some systems + // this might require elevated privileges, so print a nice error + // message if it fails. + dotnet!( + "workload", + "install", + "wasi-experimental", + "--skip-manifest-update" + ) + .stderr_capture() + .run() + .context(concat!( + "Couldn't install the required wasi-experimental workload.\n", + "You might need to install it manually by running `dotnet workload install wasi-experimental` with privileged rights." + ))?; + } + Err(error) if error.kind() == std::io::ErrorKind::NotFound => { + anyhow::bail!("dotnet not found in PATH. Please install .NET SDK 8.0.") + } + Err(error) => anyhow::bail!("{error}"), + }; let config_name = if build_debug { "Debug" } else { "Release" }; @@ -70,21 +68,8 @@ pub(crate) fn build_csharp(project_path: &Path, build_debug: bool) -> anyhow::Re ) })?; - let publish_verbosity = std::env::var("SPACETIME_DOTNET_PUBLISH_VERBOSITY").unwrap_or_else(|_| "quiet".to_string()); - let mut publish_args = vec![ - OsString::from("publish"), - OsString::from("-c"), - OsString::from(config_name), - OsString::from("-v"), - OsString::from(publish_verbosity), - ]; - if std::env::var_os("SPACETIME_DOTNET_PUBLISH_BINLOG").is_some() { - publish_args.push(OsString::from(format!( - "/bl:{}", - project_path.join("dotnet-publish.binlog").display() - ))); - } - duct::cmd("dotnet", publish_args).dir(project_path).run()?; + // run dotnet publish using cmd macro + dotnet!("publish", "-c", config_name, "-v", "quiet").run()?; // check if file exists let subdir = if std::env::var_os("EXPERIMENTAL_WASM_AOT").is_some_and(|v| v == "1") { diff --git a/tools/xtask-llm-benchmark/src/bench/publishers.rs b/tools/xtask-llm-benchmark/src/bench/publishers.rs index 32d10397018..b7fb74c6936 100644 --- a/tools/xtask-llm-benchmark/src/bench/publishers.rs +++ b/tools/xtask-llm-benchmark/src/bench/publishers.rs @@ -1,9 +1,8 @@ -use crate::bench::utils::{debug_llm, debug_llm_verbose, sanitize_db_name}; +use crate::bench::utils::sanitize_db_name; use anyhow::{bail, Context, Result}; use regex::Regex; use std::borrow::Cow; use std::env; -use std::ffi::OsStr; use std::fs; use std::path::{Path, PathBuf}; use std::process::Command; @@ -239,33 +238,6 @@ fn is_transient_build_error(stderr: &str, stdout: &str) -> bool { || combined.contains("code String { - value.to_string_lossy().into_owned() -} - -fn log_command_context(cmd: &Command, label: &str) { - eprintln!("⚠️ {label}: program: {}", os_string(cmd.get_program())); - let args: Vec<_> = cmd.get_args().map(os_string).collect(); - eprintln!("⚠️ {label}: args: {:?}", args); - eprintln!( - "⚠️ {label}: cwd: {}", - cmd.get_current_dir() - .map(|path| path.display().to_string()) - .unwrap_or_else(|| env::current_dir() - .map(|path| path.display().to_string()) - .unwrap_or_default()) - ); - - let env_overrides: Vec<_> = cmd - .get_envs() - .map(|(key, value)| { - let value = value.map(os_string).unwrap_or_else(|| "".to_string()); - format!("{}={value}", os_string(key)) - }) - .collect(); - eprintln!("⚠️ {label}: env overrides: {:?}", env_overrides); -} - fn run(cmd: &mut Command, label: &str) -> Result<()> { run_with_retry(cmd, label, 3) } @@ -304,8 +276,6 @@ fn run_with_retry(cmd: &mut Command, label: &str, max_retries: u32) -> Result<() return Ok(()); } - log_command_context(cmd, label); - let code = out.status.code().unwrap_or(-1); let stderr_raw = String::from_utf8_lossy(&out.stderr); let stdout_raw = String::from_utf8_lossy(&out.stdout); @@ -360,87 +330,14 @@ impl DotnetPublisher { fn configure_dotnet_env(cmd: &mut Command) -> &mut Command { cmd.env("DOTNET_CLI_TELEMETRY_OPTOUT", "1") .env("DOTNET_NOLOGO", "1") + // The CI runner's .NET install can crash while formatting localized + // DateTime/TimeZoneInfo data before publish starts. Force invariant + // globalization so generated C# module publish reaches MSBuild. .env("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT", "1") // Prevent MSBuild node reuse issues that cause "Pipe is broken" errors // when running multiple dotnet builds in parallel. .env("MSBUILDDISABLENODEREUSE", "1") .env("DOTNET_CLI_USE_MSBUILD_SERVER", "0") - // The workflow has already installed and verified wasi-experimental. - // Avoid the CLI's duplicate `dotnet workload list` probe, which can - // crash in CI before we reach the actual generated module build. - .env("SPACETIME_SKIP_DOTNET_WORKLOAD_CHECK", "1") - .env("SPACETIME_DOTNET_PUBLISH_VERBOSITY", "normal") - } - - fn log_dotnet_probe(args: &[&str], label: &str) { - let mut cmd = Command::new("dotnet"); - cmd.args(args); - Self::configure_dotnet_env(&mut cmd); - - eprintln!("==> {label}: {:?}", cmd); - match cmd.output() { - Ok(out) => { - let stdout_raw = String::from_utf8_lossy(&out.stdout); - let stderr_raw = String::from_utf8_lossy(&out.stderr); - let stdout = strip_ansi_codes(&stdout_raw); - let stderr = strip_ansi_codes(&stderr_raw); - eprintln!("--- {label} status ---\n{}", out.status); - eprintln!("--- {label} stdout ---\n{stdout}"); - eprintln!("--- {label} stderr ---\n{stderr}"); - } - Err(error) => eprintln!("--- {label} failed to start ---\n{error}"), - } - } - - fn log_csharp_source_context(source: &Path) -> Result<()> { - eprintln!("C# publish source: {}", source.display()); - - let mut entries = Vec::new(); - for ent in fs::read_dir(source).with_context(|| format!("failed to read {}", source.display()))? { - let ent = ent?; - let path = ent.path(); - let kind = if path.is_dir() { "dir" } else { "file" }; - entries.push(format!("{kind}: {}", path.display())); - } - entries.sort(); - eprintln!("C# publish source top-level entries:\n{}", entries.join("\n")); - - let mut project_files = Vec::new(); - for ent in fs::read_dir(source)? { - let ent = ent?; - let path = ent.path(); - if path.extension().is_some_and(|ext| ext == "csproj") { - project_files.push(path); - } - } - project_files.sort(); - for path in project_files { - match fs::read_to_string(&path) { - Ok(contents) => { - let contents: String = contents.chars().take(16_000).collect(); - eprintln!("--- {} ---\n{contents}", path.display()); - } - Err(error) => eprintln!("failed to read {}: {error}", path.display()), - } - } - - for file_name in ["NuGet.config", "nuget.config", "global.json"] { - let path = source.join(file_name); - if path.exists() { - match fs::read_to_string(&path) { - Ok(contents) => eprintln!("--- {} ---\n{contents}", path.display()), - Err(error) => eprintln!("failed to read {}: {error}", path.display()), - } - } - } - - if debug_llm_verbose() { - Self::log_dotnet_probe(&["--info"], "dotnet --info"); - Self::log_dotnet_probe(&["workload", "list"], "dotnet workload list"); - Self::log_dotnet_probe(&["nuget", "locals", "all", "--list"], "dotnet nuget locals all --list"); - } - - Ok(()) } } @@ -452,9 +349,6 @@ impl Publisher for DotnetPublisher { println!("publish csharp module {}", module_name); Self::ensure_csproj(source)?; - if debug_llm() { - Self::log_csharp_source_context(source)?; - } let db = sanitize_db_name(module_name); let source = source @@ -474,14 +368,6 @@ impl Publisher for DotnetPublisher { .arg(&db) .current_dir(&source); Self::configure_dotnet_env(&mut pubcmd); - pubcmd - .env("DOTNET_DbgEnableMiniDump", "1") - .env("DOTNET_DbgMiniDumpType", "4") - .env( - "DOTNET_DbgMiniDumpName", - source.join("dotnet-dump-%p").display().to_string(), - ) - .env("SPACETIME_DOTNET_PUBLISH_BINLOG", "1"); run(&mut pubcmd, "spacetime publish (csharp)")?; Ok(()) diff --git a/tools/xtask-llm-benchmark/src/bench/templates.rs b/tools/xtask-llm-benchmark/src/bench/templates.rs index 9a9519c3a99..35176de8200 100644 --- a/tools/xtask-llm-benchmark/src/bench/templates.rs +++ b/tools/xtask-llm-benchmark/src/bench/templates.rs @@ -213,9 +213,6 @@ fn ensure_csharp_package_source(path: &Path, package_id: &str) -> Result<()> { fn write_csharp_nuget_config(root: &Path) -> Result<()> { let workspace = workspace_root(); - let root = root - .canonicalize() - .with_context(|| format!("canonicalize {}", root.display()))?; let runtime_source = workspace.join("crates/bindings-csharp/Runtime/bin/Release"); let bsatn_source = workspace.join("crates/bindings-csharp/BSATN.Runtime/bin/Release"); From b7fb77adde723568a3b35d569c35efb8781fb2c4 Mon Sep 17 00:00:00 2001 From: clockwork-labs-bot Date: Mon, 15 Jun 2026 20:59:30 -0400 Subject: [PATCH 9/9] Keep LLM benchmark globalization fix local --- .github/workflows/llm-benchmark-periodic.yml | 6 ------ .github/workflows/llm-benchmark-validate-goldens.yml | 6 ------ 2 files changed, 12 deletions(-) diff --git a/.github/workflows/llm-benchmark-periodic.yml b/.github/workflows/llm-benchmark-periodic.yml index 5818d93ef33..da3af16b609 100644 --- a/.github/workflows/llm-benchmark-periodic.yml +++ b/.github/workflows/llm-benchmark-periodic.yml @@ -62,8 +62,6 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Setup .NET SDK - env: - DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: "1" uses: actions/setup-dotnet@v4 with: global-json-file: global.json @@ -73,14 +71,11 @@ jobs: DOTNET_MULTILEVEL_LOOKUP: "0" DOTNET_CLI_HOME: ${{ runner.temp }}/dotnet-home DOTNET_SKIP_FIRST_TIME_EXPERIENCE: "1" - DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: "1" run: | dotnet workload install wasi-experimental --skip-manifest-update --disable-parallel - name: Pack C# runtime packages if: ${{ github.event_name != 'workflow_dispatch' || contains(inputs.languages || 'rust,csharp,typescript', 'csharp') }} - env: - DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: "1" run: | dotnet pack -c Release crates/bindings-csharp/BSATN.Runtime dotnet pack -c Release crates/bindings-csharp/Runtime @@ -123,7 +118,6 @@ jobs: DOTNET_MULTILEVEL_LOOKUP: "0" DOTNET_CLI_HOME: ${{ runner.temp }}/dotnet-home DOTNET_SKIP_FIRST_TIME_EXPERIENCE: "1" - DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: "1" MSBUILDDISABLENODEREUSE: "1" DOTNET_CLI_USE_MSBUILD_SERVER: "0" LLM_BENCH_CSHARP_CONCURRENCY: "1" diff --git a/.github/workflows/llm-benchmark-validate-goldens.yml b/.github/workflows/llm-benchmark-validate-goldens.yml index f1f9e2df103..a2d2ef87a3e 100644 --- a/.github/workflows/llm-benchmark-validate-goldens.yml +++ b/.github/workflows/llm-benchmark-validate-goldens.yml @@ -45,8 +45,6 @@ jobs: - name: Setup .NET SDK if: matrix.lang == 'csharp' - env: - DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: "1" uses: actions/setup-dotnet@v4 with: global-json-file: global.json @@ -57,14 +55,11 @@ jobs: DOTNET_MULTILEVEL_LOOKUP: "0" DOTNET_CLI_HOME: ${{ runner.temp }}/dotnet-home DOTNET_SKIP_FIRST_TIME_EXPERIENCE: "1" - DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: "1" run: | dotnet workload install wasi-experimental --skip-manifest-update --disable-parallel - name: Pack C# runtime packages if: matrix.lang == 'csharp' - env: - DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: "1" run: | dotnet pack -c Release crates/bindings-csharp/BSATN.Runtime dotnet pack -c Release crates/bindings-csharp/Runtime @@ -101,7 +96,6 @@ jobs: DOTNET_MULTILEVEL_LOOKUP: "0" DOTNET_CLI_HOME: ${{ runner.temp }}/dotnet-home DOTNET_SKIP_FIRST_TIME_EXPERIENCE: "1" - DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: "1" MSBUILDDISABLENODEREUSE: "1" DOTNET_CLI_USE_MSBUILD_SERVER: "0" LLM_BENCH_CSHARP_CONCURRENCY: "1"