diff --git a/.azdo/release.yaml b/.azdo/release.yaml
index c2b1c3e2c..82ba1917a 100644
--- a/.azdo/release.yaml
+++ b/.azdo/release.yaml
@@ -54,7 +54,7 @@ extends:
displayName: Install .NET
inputs:
packageType: 'sdk'
- version: '8.0.x'
+ useGlobalJson: true
# https://eng.ms/docs/cloud-ai-platform/devdiv/one-engineering-system-1es/1es-docs/1es-security-configuration/configuration-guides/pat-burndown-guidance#workarounds-for-tasks-that-do-not-yet-support-wif-service-connection
- task: AzureCLI@2
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index 93eac5370..be57b26ca 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -1,7 +1,7 @@
{
"$schema": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainer.base.schema.json",
"name": "Component Detection",
- "image": "mcr.microsoft.com/vscode/devcontainers/dotnet:8.0",
+ "image": "mcr.microsoft.com/devcontainers/dotnet:10.0",
"runArgs": ["--init"],
"extensions": [
"eamodio.gitlens",
diff --git a/.editorconfig b/.editorconfig
index 66d093589..ab65929b1 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -518,6 +518,8 @@ dotnet_diagnostic.CS1591.severity = suggestion
# CA2007: Consider calling ConfigureAwait on the awaited task
dotnet_diagnostic.CA2007.severity = suggestion
+# CA1873: Avoid potentially expensive logging
+dotnet_diagnostic.CA1873.severity = suggestion
# CA1062: Validate arguments of public methods
dotnet_diagnostic.CA1062.severity = suggestion
@@ -673,6 +675,33 @@ dotnet_diagnostic.CA1311.severity = suggestion
# CA1852: Type can be sealed
dotnet_diagnostic.CA1852.severity = suggestion
+# Modernization suggestions from the newer SDK should not require unrelated rewrites.
+# IDE0040: Accessibility modifiers, now also enforced on interface members
+dotnet_diagnostic.IDE0040.severity = suggestion
+# CA1515: Consider making public types internal
+dotnet_diagnostic.CA1515.severity = suggestion
+# CA2263: Prefer a generic overload when the type is known
+dotnet_diagnostic.CA2263.severity = suggestion
+# IDE0032: Use auto property, including the C# field keyword
+dotnet_diagnostic.IDE0032.severity = suggestion
+# IDE0330: Use System.Threading.Lock
+dotnet_diagnostic.IDE0330.severity = suggestion
+# IDE0350: Simplify lambda expression
+dotnet_diagnostic.IDE0350.severity = suggestion
+# IDE0370: Remove unnecessary null-forgiving operators
+dotnet_diagnostic.IDE0370.severity = suggestion
+# IDE0028, IDE0300, IDE0306: Simplify collection initialization
+dotnet_diagnostic.IDE0028.severity = suggestion
+dotnet_diagnostic.IDE0300.severity = suggestion
+dotnet_diagnostic.IDE0306.severity = suggestion
+# CA1849, CA2024: Prefer asynchronous I/O
+dotnet_diagnostic.CA1849.severity = suggestion
+dotnet_diagnostic.CA2024.severity = suggestion
+# CA1872: Prefer Convert.ToHexStringLower
+dotnet_diagnostic.CA1872.severity = suggestion
+# CA1874: Prefer Regex.IsMatch
+dotnet_diagnostic.CA1874.severity = suggestion
+
# CA1854: Prefer the IDictionary.TryGetValue(TKey, out TValue) method
dotnet_diagnostic.CA1854.severity = suggestion
diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
index 267f6b002..5d4b3c396 100644
--- a/.github/copilot-instructions.md
+++ b/.github/copilot-instructions.md
@@ -129,7 +129,7 @@ dotnet run --project src/Microsoft.ComponentDetection/Microsoft.ComponentDetecti
dotnet test
# Run specific test project
-dotnet test test/Microsoft.ComponentDetection.Detectors.Tests/
+dotnet test --project test/Microsoft.ComponentDetection.Detectors.Tests/
```
### Debug Mode
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index d1e2a8d39..235264533 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -41,10 +41,8 @@ jobs:
run: dotnet build --no-restore --configuration Debug
- name: Run tests
- # The '--' separator forwards options to the Microsoft Testing Platform runner.
- # After upgrading to .NET 10 SDK, these can be passed directly without '--'.
# Disable the default Integration-test exclusion from test/Directory.Build.props.
- run: dotnet test --no-build --configuration Debug -p:ExcludeIntegrationTests=false -p:TestingPlatformCommandLineArguments="--coverage --coverage-output-format cobertura"
+ run: dotnet test --no-build --configuration Debug -p:ExcludeIntegrationTests=false --coverage --coverage-output-format cobertura
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 51f4c782f..eb09c143e 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -68,7 +68,7 @@ By default, `dotnet test` **excludes** Integration tests (configured in `test/Di
To run only Integration tests locally:
```bash
-dotnet test -- --filter "TestCategory=Integration"
+dotnet test -p:ExcludeIntegrationTests=false --filter "TestCategory=Integration"
```
To run everything (same as CI):
diff --git a/Directory.Build.props b/Directory.Build.props
index 2781eb498..b22770a18 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -1,7 +1,7 @@
- net8.0
+ net10.0
latest
true
true
@@ -32,7 +32,6 @@
-
diff --git a/Directory.Packages.props b/Directory.Packages.props
index d1cf38c0c..03cc7c60b 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -10,11 +10,11 @@
-
-
+
+
-
+
@@ -25,8 +25,8 @@
-
-
+
+
@@ -50,6 +50,6 @@
-
+
diff --git a/Dockerfile b/Dockerfile
index e193773be..2b9ac8410 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM mcr.microsoft.com/dotnet/sdk:8.0-cbl-mariner2.0@sha256:a26c5bf4c47186df2fd290b74a2512d9830796d98b644fb12857b57a5244507d AS build
+FROM mcr.microsoft.com/dotnet/sdk:10.0-azurelinux3.0@sha256:ffd76bb46785445d2d029809009d35b522619b97df88c0abaa05d549db697b43 AS build
WORKDIR /app
COPY . .
RUN dotnet publish -c Release -o out \
@@ -10,7 +10,7 @@ RUN dotnet publish -c Release -o out \
-p:PublishSingleFile=true \
./src/Microsoft.ComponentDetection
-FROM mcr.microsoft.com/dotnet/runtime-deps:8.0-cbl-mariner2.0@sha256:addba165ed9637fc02c63e9f66913deb7125dac90b5ca7d3f89d6d084c23f09b AS runtime
+FROM mcr.microsoft.com/dotnet/runtime-deps:10.0-azurelinux3.0@sha256:d33971c79f36e1d539de998823ae930bf085c4e9812c4cdebd9a1571e300fdb3 AS runtime
WORKDIR /app
COPY --from=build /app/out ./
diff --git a/README.md b/README.md
index e3b529899..0a5fe27fb 100644
--- a/README.md
+++ b/README.md
@@ -66,7 +66,7 @@ For a complete feature overview refer to [feature-overview.md](docs/feature-over
## Getting Started
-To clone and run this application, you'll need [Git](https://git-scm.com) and [.NET 8](https://aka.ms/download-dotnet) installed on your computer. From your command line:
+To clone and run this application, you'll need [Git](https://git-scm.com) and the [.NET SDK](https://aka.ms/download-dotnet) specified in [global.json](global.json) installed on your computer. From your command line:
```bash
# Clone this repository
diff --git a/global.json b/global.json
index e9482fd3b..22cc4bf01 100644
--- a/global.json
+++ b/global.json
@@ -1,9 +1,12 @@
{
"sdk": {
- "version": "8.0.418",
+ "version": "10.0.403",
"rollForward": "latestFeature"
},
"msbuild-sdks": {
"MSTest.Sdk": "4.1.0"
+ },
+ "test": {
+ "runner": "Microsoft.Testing.Platform"
}
}
diff --git a/src/Microsoft.ComponentDetection.Common/LazyComponentStream.cs b/src/Microsoft.ComponentDetection.Common/LazyComponentStream.cs
index 2a5f81b2b..8940eff4b 100644
--- a/src/Microsoft.ComponentDetection.Common/LazyComponentStream.cs
+++ b/src/Microsoft.ComponentDetection.Common/LazyComponentStream.cs
@@ -43,7 +43,7 @@ private byte[] SafeOpenFile()
using var fs = this.fileInfo.OpenRead();
var buffer = new byte[this.fileInfo.Length];
- fs.Read(buffer, 0, (int)this.fileInfo.Length);
+ fs.ReadExactly(buffer);
return buffer;
}
diff --git a/src/Microsoft.ComponentDetection.Common/Microsoft.ComponentDetection.Common.csproj b/src/Microsoft.ComponentDetection.Common/Microsoft.ComponentDetection.Common.csproj
index 32d1e6f96..427491728 100644
--- a/src/Microsoft.ComponentDetection.Common/Microsoft.ComponentDetection.Common.csproj
+++ b/src/Microsoft.ComponentDetection.Common/Microsoft.ComponentDetection.Common.csproj
@@ -14,7 +14,6 @@
-
diff --git a/src/Microsoft.ComponentDetection.Contracts/Microsoft.ComponentDetection.Contracts.csproj b/src/Microsoft.ComponentDetection.Contracts/Microsoft.ComponentDetection.Contracts.csproj
index 0804d03a0..ca2689c93 100644
--- a/src/Microsoft.ComponentDetection.Contracts/Microsoft.ComponentDetection.Contracts.csproj
+++ b/src/Microsoft.ComponentDetection.Contracts/Microsoft.ComponentDetection.Contracts.csproj
@@ -15,6 +15,7 @@
+
diff --git a/src/Microsoft.ComponentDetection.Detectors/Microsoft.ComponentDetection.Detectors.csproj b/src/Microsoft.ComponentDetection.Detectors/Microsoft.ComponentDetection.Detectors.csproj
index d12fe55d7..53cd9ed00 100644
--- a/src/Microsoft.ComponentDetection.Detectors/Microsoft.ComponentDetection.Detectors.csproj
+++ b/src/Microsoft.ComponentDetection.Detectors/Microsoft.ComponentDetection.Detectors.csproj
@@ -22,12 +22,11 @@
-
-
+
diff --git a/src/Microsoft.ComponentDetection.Orchestrator/Microsoft.ComponentDetection.Orchestrator.csproj b/src/Microsoft.ComponentDetection.Orchestrator/Microsoft.ComponentDetection.Orchestrator.csproj
index 33c2430a7..624a7e995 100644
--- a/src/Microsoft.ComponentDetection.Orchestrator/Microsoft.ComponentDetection.Orchestrator.csproj
+++ b/src/Microsoft.ComponentDetection.Orchestrator/Microsoft.ComponentDetection.Orchestrator.csproj
@@ -18,7 +18,6 @@
-
diff --git a/src/Microsoft.ComponentDetection/Microsoft.ComponentDetection.csproj b/src/Microsoft.ComponentDetection/Microsoft.ComponentDetection.csproj
index 300fb14ca..6cb590ebc 100644
--- a/src/Microsoft.ComponentDetection/Microsoft.ComponentDetection.csproj
+++ b/src/Microsoft.ComponentDetection/Microsoft.ComponentDetection.csproj
@@ -17,7 +17,6 @@
-
diff --git a/test/Directory.Build.props b/test/Directory.Build.props
index 6bd2742a6..c11f4bded 100644
--- a/test/Directory.Build.props
+++ b/test/Directory.Build.props
@@ -4,8 +4,6 @@
true
-
- true
true
$(TestingPlatformCommandLineArguments) --filter TestCategory!=Integration
diff --git a/test/Microsoft.ComponentDetection.Common.Tests/LazyComponentStreamTests.cs b/test/Microsoft.ComponentDetection.Common.Tests/LazyComponentStreamTests.cs
index 8e661c60e..2cec42281 100644
--- a/test/Microsoft.ComponentDetection.Common.Tests/LazyComponentStreamTests.cs
+++ b/test/Microsoft.ComponentDetection.Common.Tests/LazyComponentStreamTests.cs
@@ -12,6 +12,31 @@ namespace Microsoft.ComponentDetection.Common.Tests;
[TestCategory("Governance/ComponentDetection")]
public class LazyComponentStreamTests
{
+ [TestMethod]
+ public void LazyComponentStreamReadsEntireFile()
+ {
+ var fileContent = new byte[(128 * 1024) + 1];
+ fileContent[0] = 1;
+ fileContent[^1] = 2;
+ var tmpFile = Path.GetTempFileName();
+
+ try
+ {
+ File.WriteAllBytes(tmpFile, fileContent);
+ var lcs = new LazyComponentStream(new FileInfo(tmpFile), "test", Mock.Of());
+
+ using var stream = lcs.Stream;
+ using var actual = new MemoryStream();
+ stream.CopyTo(actual);
+
+ actual.ToArray().Should().Equal(fileContent);
+ }
+ finally
+ {
+ File.Delete(tmpFile);
+ }
+ }
+
[TestMethod]
public void LazyComponentStreamWorks()
{
diff --git a/test/Microsoft.ComponentDetection.Common.Tests/Microsoft.ComponentDetection.Common.Tests.csproj b/test/Microsoft.ComponentDetection.Common.Tests/Microsoft.ComponentDetection.Common.Tests.csproj
index 496f5be8c..506c23692 100644
--- a/test/Microsoft.ComponentDetection.Common.Tests/Microsoft.ComponentDetection.Common.Tests.csproj
+++ b/test/Microsoft.ComponentDetection.Common.Tests/Microsoft.ComponentDetection.Common.Tests.csproj
@@ -8,7 +8,6 @@
-
diff --git a/test/Microsoft.ComponentDetection.Contracts.Tests/Microsoft.ComponentDetection.Contracts.Tests.csproj b/test/Microsoft.ComponentDetection.Contracts.Tests/Microsoft.ComponentDetection.Contracts.Tests.csproj
index 680fd7d91..d1aeb33b3 100644
--- a/test/Microsoft.ComponentDetection.Contracts.Tests/Microsoft.ComponentDetection.Contracts.Tests.csproj
+++ b/test/Microsoft.ComponentDetection.Contracts.Tests/Microsoft.ComponentDetection.Contracts.Tests.csproj
@@ -7,7 +7,6 @@
-
diff --git a/test/Microsoft.ComponentDetection.Detectors.Tests/Microsoft.ComponentDetection.Detectors.Tests.csproj b/test/Microsoft.ComponentDetection.Detectors.Tests/Microsoft.ComponentDetection.Detectors.Tests.csproj
index 45a66cfd5..2d2ae5452 100644
--- a/test/Microsoft.ComponentDetection.Detectors.Tests/Microsoft.ComponentDetection.Detectors.Tests.csproj
+++ b/test/Microsoft.ComponentDetection.Detectors.Tests/Microsoft.ComponentDetection.Detectors.Tests.csproj
@@ -13,7 +13,6 @@
-
diff --git a/test/Microsoft.ComponentDetection.Detectors.Tests/nuget/BinLogProcessorTests.cs b/test/Microsoft.ComponentDetection.Detectors.Tests/nuget/BinLogProcessorTests.cs
index d595b2cbd..d114efc3a 100644
--- a/test/Microsoft.ComponentDetection.Detectors.Tests/nuget/BinLogProcessorTests.cs
+++ b/test/Microsoft.ComponentDetection.Detectors.Tests/nuget/BinLogProcessorTests.cs
@@ -300,7 +300,7 @@ public async Task MultipleProjectsInSameBuild_ExtractsAll()
WriteFile(projectBDir, "ProjectB.csproj", projectBContent);
// Create a solution to build both projects in a single binlog
- await RunDotNetAsync(solutionDir, "new sln --name MultiProject");
+ await RunDotNetAsync(solutionDir, "new sln --format sln --name MultiProject");
await RunDotNetAsync(solutionDir, $"sln add \"{Path.Combine(projectADir, "ProjectA.csproj")}\"");
await RunDotNetAsync(solutionDir, $"sln add \"{Path.Combine(projectBDir, "ProjectB.csproj")}\"");
var binlogPath = Path.Combine(solutionDir, "build.binlog");
@@ -1219,10 +1219,9 @@ public async Task TargetItemUpdateLimitation_UpdateNotVisibleInBinlog()
}
[TestMethod]
- public async Task TargetAddsItemButPropertyInvisible_ItemCapturedPropertyNot()
+ public async Task TargetAddsItemAndChangesProperty_BothCaptured()
{
- // A single target modifies both a property and adds an item.
- // Property changes in targets are invisible, but item additions are visible.
+ // MSBuild 18 reports target-level property changes as well as item additions.
var projectDir = Path.Combine(this.testDir, "ComboPropsItems");
Directory.CreateDirectory(projectDir);
@@ -1254,10 +1253,9 @@ public async Task TargetAddsItemButPropertyInvisible_ItemCapturedPropertyNot()
p.ProjectPath != null &&
p.ProjectPath.EndsWith("ComboPropsItems.csproj", StringComparison.OrdinalIgnoreCase));
- // Property change in target is invisible (stays at evaluation value)
projectInfo.IsTestProject.Should().Be(
- false,
- "target-level property changes are not visible in binlog events");
+ true,
+ "target-level property changes are visible in MSBuild 18 binlog events");
projectInfo.PackageReference.Should().ContainKey("Newtonsoft.Json");
// Item addition in target IS captured via TaskParameter events
@@ -1347,11 +1345,10 @@ public async Task GlobalPropertyAndTargetOverride_TargetWins()
p.ProjectPath != null &&
p.ProjectPath.EndsWith("GlobalAndTarget.csproj", StringComparison.OrdinalIgnoreCase));
- // Note: Global properties cannot be overridden by targets in MSBuild.
- // The global property wins. This tests that we correctly capture this MSBuild behavior.
+ // MSBuild 18 reports the target's reassignment of the initially global property.
projectInfo.SelfContained.Should().Be(
- false,
- "global properties cannot be overridden by targets in MSBuild");
+ true,
+ "target-level property reassignments are captured from MSBuild 18 binlogs");
}
[TestMethod]
diff --git a/test/Microsoft.ComponentDetection.Orchestrator.Tests/Microsoft.ComponentDetection.Orchestrator.Tests.csproj b/test/Microsoft.ComponentDetection.Orchestrator.Tests/Microsoft.ComponentDetection.Orchestrator.Tests.csproj
index 72d0de8c7..1691c337a 100644
--- a/test/Microsoft.ComponentDetection.Orchestrator.Tests/Microsoft.ComponentDetection.Orchestrator.Tests.csproj
+++ b/test/Microsoft.ComponentDetection.Orchestrator.Tests/Microsoft.ComponentDetection.Orchestrator.Tests.csproj
@@ -10,7 +10,6 @@
-
diff --git a/test/Microsoft.ComponentDetection.Orchestrator.Tests/Services/DetectorProcessingServiceTests.cs b/test/Microsoft.ComponentDetection.Orchestrator.Tests/Services/DetectorProcessingServiceTests.cs
index 9f4bd62ea..64ce7f2b0 100644
--- a/test/Microsoft.ComponentDetection.Orchestrator.Tests/Services/DetectorProcessingServiceTests.cs
+++ b/test/Microsoft.ComponentDetection.Orchestrator.Tests/Services/DetectorProcessingServiceTests.cs
@@ -235,7 +235,7 @@ public async Task ProcessDetectorsAsync_ExperimentalDetectorsDoNotReturnComponen
experimentalDetectorRecord.IsExperimental.Should().BeTrue();
// We should have all components except the ones that came from our experimental detector
- this.GetDiscoveredComponentsFromDetectorProcessingResult(results).Should().HaveCount(records.Sum(x => x.DetectedComponentCount ?? 0) - experimentalDetectorRecord.DetectedComponentCount ?? 0);
+ this.GetDiscoveredComponentsFromDetectorProcessingResult(results).Should().HaveCount((records.Sum(x => x.DetectedComponentCount ?? 0) - experimentalDetectorRecord.DetectedComponentCount) ?? 0);
this.GetDiscoveredComponentsFromDetectorProcessingResult(results)
.Select(x => x.Component as NuGetComponent)
.Where(x => x != null)
diff --git a/test/Microsoft.ComponentDetection.TestsUtilities/Microsoft.ComponentDetection.TestsUtilities.csproj b/test/Microsoft.ComponentDetection.TestsUtilities/Microsoft.ComponentDetection.TestsUtilities.csproj
index d9958a555..1c67bc8f2 100644
--- a/test/Microsoft.ComponentDetection.TestsUtilities/Microsoft.ComponentDetection.TestsUtilities.csproj
+++ b/test/Microsoft.ComponentDetection.TestsUtilities/Microsoft.ComponentDetection.TestsUtilities.csproj
@@ -12,7 +12,6 @@
-
diff --git a/test/Microsoft.ComponentDetection.VerificationTests/Microsoft.ComponentDetection.VerificationTests.csproj b/test/Microsoft.ComponentDetection.VerificationTests/Microsoft.ComponentDetection.VerificationTests.csproj
index e5406c78d..0cf376d02 100644
--- a/test/Microsoft.ComponentDetection.VerificationTests/Microsoft.ComponentDetection.VerificationTests.csproj
+++ b/test/Microsoft.ComponentDetection.VerificationTests/Microsoft.ComponentDetection.VerificationTests.csproj
@@ -13,7 +13,6 @@
-