From 6de1aa978bfd356513f022f76f7c2346a1dc640b Mon Sep 17 00:00:00 2001 From: "Ryan Brandenburg (He/Him)" Date: Wed, 4 Nov 2026 10:38:13 -0800 Subject: [PATCH 1/2] net8->net10 --- .azdo/release.yaml | 2 +- .devcontainer/devcontainer.json | 2 +- .editorconfig | 29 +++++++++++++++++++ .github/copilot-instructions.md | 2 +- .github/workflows/build.yml | 4 +-- CONTRIBUTING.md | 2 +- Directory.Build.props | 3 +- Directory.Packages.props | 12 ++++---- Dockerfile | 4 +-- README.md | 2 +- global.json | 5 +++- .../LazyComponentStream.cs | 2 +- ...Microsoft.ComponentDetection.Common.csproj | 1 - ...rosoft.ComponentDetection.Contracts.csproj | 1 + ...rosoft.ComponentDetection.Detectors.csproj | 3 +- ...oft.ComponentDetection.Orchestrator.csproj | 1 - .../Microsoft.ComponentDetection.csproj | 1 - test/Directory.Build.props | 2 -- .../LazyComponentStreamTests.cs | 25 ++++++++++++++++ ...oft.ComponentDetection.Common.Tests.csproj | 1 - ....ComponentDetection.Contracts.Tests.csproj | 1 - ....ComponentDetection.Detectors.Tests.csproj | 1 - .../nuget/BinLogProcessorTests.cs | 19 +++++------- ...mponentDetection.Orchestrator.Tests.csproj | 1 - .../DetectorProcessingServiceTests.cs | 2 +- ...t.ComponentDetection.TestsUtilities.csproj | 1 - ...omponentDetection.VerificationTests.csproj | 1 - 27 files changed, 85 insertions(+), 45 deletions(-) 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..269c1dedb 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/vscode/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 @@ - From 2e7d477e7a6780b272d077833af7df9035842f65 Mon Sep 17 00:00:00 2001 From: "Ryan Brandenburg (He/Him)" Date: Wed, 4 Nov 2026 13:26:04 -0800 Subject: [PATCH 2/2] devcontainer update --- .devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 269c1dedb..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:10.0", + "image": "mcr.microsoft.com/devcontainers/dotnet:10.0", "runArgs": ["--init"], "extensions": [ "eamodio.gitlens",