diff --git a/.github/workflows/test-csharp.yml b/.github/workflows/test-csharp.yml
index a52db59..e3b3487 100644
--- a/.github/workflows/test-csharp.yml
+++ b/.github/workflows/test-csharp.yml
@@ -109,8 +109,8 @@ jobs:
with:
name: regorus-nuget
path: |
- bindings/csharp/Regorus/bin/Release/Regorus*.nupkg
- bindings/csharp/Regorus/bin/Release/Regorus*.snupkg
+ bindings/csharp/Regorus/bin/Release/Microsoft.Regorus*.nupkg
+ bindings/csharp/Regorus/bin/Release/Microsoft.Regorus*.snupkg
if-no-files-found: error
retention-days: 1
diff --git a/bindings/csharp/.gitignore b/bindings/csharp/.gitignore
new file mode 100644
index 0000000..67d91e9
--- /dev/null
+++ b/bindings/csharp/.gitignore
@@ -0,0 +1 @@
+local-packages/
diff --git a/bindings/csharp/Benchmarks/Benchmarks.csproj b/bindings/csharp/Benchmarks/Benchmarks.csproj
index 621743d..2f238ba 100644
--- a/bindings/csharp/Benchmarks/Benchmarks.csproj
+++ b/bindings/csharp/Benchmarks/Benchmarks.csproj
@@ -8,15 +8,15 @@
-$(VersionSuffix)
+ false
-
-
- -$(VersionSuffix)
-
+
+
+
-
-
+
+
diff --git a/bindings/csharp/Directory.Packages.props b/bindings/csharp/Directory.Packages.props
index 879957c..806dfbd 100644
--- a/bindings/csharp/Directory.Packages.props
+++ b/bindings/csharp/Directory.Packages.props
@@ -7,7 +7,7 @@
-
+
diff --git a/bindings/csharp/Regorus.Tests/Regorus.Tests.csproj b/bindings/csharp/Regorus.Tests/Regorus.Tests.csproj
index b243902..c8719fe 100644
--- a/bindings/csharp/Regorus.Tests/Regorus.Tests.csproj
+++ b/bindings/csharp/Regorus.Tests/Regorus.Tests.csproj
@@ -12,6 +12,7 @@
-$(VersionSuffix)
+ false
@@ -23,8 +24,12 @@
-
-
+
+
+
+
+
+
diff --git a/bindings/csharp/Regorus/Regorus.csproj b/bindings/csharp/Regorus/Regorus.csproj
index 5385f70..bf26dde 100644
--- a/bindings/csharp/Regorus/Regorus.csproj
+++ b/bindings/csharp/Regorus/Regorus.csproj
@@ -2,6 +2,7 @@
Library
+ Microsoft.Regorus
Microsoft.Regorus
netstandard2.0;netstandard2.1
true
diff --git a/bindings/csharp/TargetExampleApp/TargetExampleApp.csproj b/bindings/csharp/TargetExampleApp/TargetExampleApp.csproj
index 7ff3262..16e80e6 100644
--- a/bindings/csharp/TargetExampleApp/TargetExampleApp.csproj
+++ b/bindings/csharp/TargetExampleApp/TargetExampleApp.csproj
@@ -11,15 +11,15 @@
-$(VersionSuffix)
- false
+ false
-
+
-
-
+
+
diff --git a/bindings/csharp/TestApp/TestApp.csproj b/bindings/csharp/TestApp/TestApp.csproj
index c8fbcf9..f4faa60 100644
--- a/bindings/csharp/TestApp/TestApp.csproj
+++ b/bindings/csharp/TestApp/TestApp.csproj
@@ -13,14 +13,14 @@
-$(VersionSuffix)
- false
+ false
-
+
-
-
+
+
diff --git a/bindings/csharp/nuget.config b/bindings/csharp/nuget.config
new file mode 100644
index 0000000..019cadf
--- /dev/null
+++ b/bindings/csharp/nuget.config
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/xtask/src/tasks/bindings/csharp.rs b/xtask/src/tasks/bindings/csharp.rs
index dfe6f74..a0d31ad 100644
--- a/xtask/src/tasks/bindings/csharp.rs
+++ b/xtask/src/tasks/bindings/csharp.rs
@@ -400,14 +400,14 @@ impl TestCsharpCommand {
if let Some(version) = package
.file_stem()
.and_then(|stem| stem.to_str())
- .and_then(|stem| stem.strip_prefix("Regorus."))
+ .and_then(|stem| stem.strip_prefix("Microsoft.Regorus."))
{
package_versions.insert(version.to_owned());
}
}
for version in &package_versions {
- let cache_entry = package_cache.join("regorus").join(version);
+ let cache_entry = package_cache.join("microsoft.regorus").join(version);
if cache_entry.exists() {
fs::remove_dir_all(&cache_entry).with_context(|| {
format!(
@@ -443,15 +443,104 @@ fn run_regorus_tests(
skip_apps: bool,
console_logger: bool,
) -> Result<()> {
- let nuget_source = package_dir
- .to_str()
- .ok_or_else(|| anyhow!("NuGet directory path contains invalid UTF-8"))?;
+ // Copy .nupkg files into the local-packages directory declared in nuget.config
+ // so that Microsoft.Regorus resolves from the mapped "local" source.
+ let local_packages = workspace.join("bindings/csharp/local-packages");
+ if local_packages.exists() {
+ fs::remove_dir_all(&local_packages).with_context(|| {
+ format!(
+ "failed to clean local-packages directory at {}",
+ local_packages.display()
+ )
+ })?;
+ }
+ fs::create_dir_all(&local_packages).with_context(|| {
+ format!(
+ "failed to create local-packages directory at {}",
+ local_packages.display()
+ )
+ })?;
+
+ let nuget_config = workspace.join("bindings/csharp/nuget.config");
+
+ // Verify that package source mapping blocks Microsoft.Regorus from resolving
+ // via nuget.org. With local-packages empty, restore must fail with NU1101.
+ println!("Verifying package source mapping blocks external resolution...");
+ {
+ let verify_cache = package_cache.join("_verify");
+ let _ = fs::remove_dir_all(&verify_cache);
+ fs::create_dir_all(&verify_cache)?;
+ let verify_cache_str = verify_cache
+ .to_str()
+ .ok_or_else(|| anyhow!("verify cache path contains invalid UTF-8"))?;
+
+ let regorus_tests = workspace.join("bindings/csharp/Regorus.Tests");
+ let mut verify = Command::new("dotnet");
+ verify.current_dir(®orus_tests);
+ verify.arg("restore");
+ verify.arg("--configfile");
+ verify.arg(&nuget_config);
+ verify.arg("--arch");
+ verify.arg(dotnet_host_arch());
+ verify.arg(format!("/p:RestorePackagesPath={}", verify_cache_str));
+ verify.arg("/p:UsePackageReference=true");
+ verify.env("NUGET_PACKAGES", &verify_cache);
+
+ let output = verify
+ .output()
+ .context("failed to run dotnet restore for source mapping verification")?;
+ let _ = fs::remove_dir_all(&verify_cache);
+
+ let stdout = String::from_utf8_lossy(&output.stdout);
+ let stderr = String::from_utf8_lossy(&output.stderr);
+ let combined = format!("{stdout}\n{stderr}");
+
+ if output.status.success() {
+ return Err(anyhow!(
+ "Source mapping verification failed: dotnet restore succeeded when it should \
+ have failed. Microsoft.Regorus must not be resolvable from nuget.org. \
+ Check that bindings/csharp/nuget.config has correct packageSourceMapping."
+ ));
+ }
+
+ // Ensure the failure is specifically NU1101 for Microsoft.Regorus, not an
+ // unrelated error (e.g. network outage).
+ if !combined.contains("NU1101") || !combined.contains("Microsoft.Regorus") {
+ return Err(anyhow!(
+ "Source mapping verification failed: dotnet restore failed, but not for the \
+ expected reason. Expected NU1101 for Microsoft.Regorus to confirm external \
+ resolution is blocked.\nstdout:\n{stdout}\nstderr:\n{stderr}"
+ ));
+ }
+
+ println!("Verified: Microsoft.Regorus is not resolvable from external sources.");
+ }
+
+ for entry in fs::read_dir(package_dir)? {
+ let entry = entry?;
+ let path = entry.path();
+ if path
+ .extension()
+ .and_then(|ext| ext.to_str())
+ .map_or(false, |ext| ext.eq_ignore_ascii_case("nupkg"))
+ {
+ let dest = local_packages.join(entry.file_name());
+ fs::copy(&path, &dest).with_context(|| {
+ format!("failed to copy {} to {}", path.display(), dest.display())
+ })?;
+ println!(
+ "Copied {} to local-packages/",
+ entry.file_name().to_string_lossy()
+ );
+ }
+ }
+
let cache_path = package_cache
.to_str()
.ok_or_else(|| anyhow!("NuGet cache path contains invalid UTF-8"))?;
let properties = vec![
- format!("/p:RestoreAdditionalProjectSources={}", nuget_source),
format!("/p:RestorePackagesPath={}", cache_path),
+ "/p:UsePackageReference=true".to_string(),
];
let property_args: Vec<&str> = properties.iter().map(|value| value.as_str()).collect();
@@ -465,6 +554,7 @@ fn run_regorus_tests(
&property_args,
"Regorus.Tests",
package_cache,
+ &nuget_config,
)?;
let mut test = Command::new("dotnet");
@@ -475,6 +565,9 @@ fn run_regorus_tests(
test.arg(configuration);
test.arg("--arch");
test.arg(dotnet_host_arch());
+ for p in &property_args {
+ test.arg(p);
+ }
if console_logger {
test.arg("--logger");
test.arg("console;verbosity=detailed");
@@ -495,7 +588,13 @@ fn run_regorus_tests(
if clean {
clean_msbuild_project(&test_app)?;
}
- restore_with_source(&test_app, &property_args, "TestApp", package_cache)?;
+ restore_with_source(
+ &test_app,
+ &property_args,
+ "TestApp",
+ package_cache,
+ &nuget_config,
+ )?;
let mut build = Command::new("dotnet");
build.current_dir(&test_app);
build.arg("build");
@@ -504,6 +603,9 @@ fn run_regorus_tests(
build.arg(configuration);
build.arg("--arch");
build.arg(dotnet_host_arch());
+ for p in &property_args {
+ build.arg(p);
+ }
build.env("NUGET_PACKAGES", package_cache);
run_command(build, "dotnet build (TestApp)")?;
@@ -517,6 +619,9 @@ fn run_regorus_tests(
run.arg(configuration);
run.arg("--arch");
run.arg(dotnet_host_arch());
+ for p in &property_args {
+ run.arg(p);
+ }
run.env("NUGET_PACKAGES", package_cache);
run_command(run, "dotnet run (TestApp)")?;
@@ -529,6 +634,7 @@ fn run_regorus_tests(
&property_args,
"TargetExampleApp",
package_cache,
+ &nuget_config,
)?;
let mut build_example = Command::new("dotnet");
build_example.current_dir(&target_example);
@@ -538,6 +644,9 @@ fn run_regorus_tests(
build_example.arg(configuration);
build_example.arg("--arch");
build_example.arg(dotnet_host_arch());
+ for p in &property_args {
+ build_example.arg(p);
+ }
build_example.env("NUGET_PACKAGES", package_cache);
run_command(build_example, "dotnet build (TargetExampleApp)")?;
@@ -551,6 +660,9 @@ fn run_regorus_tests(
run_example.arg(configuration);
run_example.arg("--arch");
run_example.arg(dotnet_host_arch());
+ for p in &property_args {
+ run_example.arg(p);
+ }
run_example.env("NUGET_PACKAGES", package_cache);
run_command(run_example, "dotnet run (TargetExampleApp)")?;
@@ -562,10 +674,13 @@ fn restore_with_source(
properties: &[&str],
label: &str,
package_cache: &Path,
+ nuget_config: &Path,
) -> Result<()> {
let mut restore = Command::new("dotnet");
restore.current_dir(project_dir);
restore.arg("restore");
+ restore.arg("--configfile");
+ restore.arg(nuget_config);
restore.arg("--arch");
restore.arg(dotnet_host_arch());
for property in properties {
diff --git a/xtask/src/tasks/bindings/version.rs b/xtask/src/tasks/bindings/version.rs
index fd13ade..fd736be 100644
--- a/xtask/src/tasks/bindings/version.rs
+++ b/xtask/src/tasks/bindings/version.rs
@@ -186,6 +186,7 @@ const BINDINGS: &[Binding] = &[
pom_xml: None,
csharp_project: Some("bindings/csharp/Regorus/Regorus.csproj"),
csharp_dependents: &[
+ "bindings/csharp/Directory.Packages.props",
"bindings/csharp/Regorus.Tests/Regorus.Tests.csproj",
"bindings/csharp/Benchmarks/Benchmarks.csproj",
"bindings/csharp/TargetExampleApp/TargetExampleApp.csproj",
@@ -513,7 +514,7 @@ fn update_csharp_projects(
r#"(?s)(?P)(?P[^<]+)(?P)"#,
)?;
let pkg_ref = Regex::new(
- r#"(?i)(?P]*Include="regorus"[^>]*Version=")(?P\d+\.\d+\.\d+)(?P[^\"]*")"#,
+ r#"(?i)(?P]*Include="microsoft\.regorus"[^>]*Version=")(?P\d+\.\d+\.\d+)(?P[^\"]*")"#,
)?;
let package_path = root.join(package_project);