build: adopt Central Package Management + lockfiles + transitive audit#321
Open
TalZaccai wants to merge 4 commits into
Open
build: adopt Central Package Management + lockfiles + transitive audit#321TalZaccai wants to merge 4 commits into
TalZaccai wants to merge 4 commits into
Conversation
Modernizes the .NET package management stack for the whole repo: 1. Central Package Management (CPM) - introduces root Directory.Packages.props as the single source of truth for every package version. All <PackageReference> entries across the 20 SDK-style csproj files become version-less; the previously per-project version sprawl (e.g. 3 different Microsoft.NET.Test.Sdk versions) collapses to a single declaration. 2. Central Transitive Pinning (CentralPackageTransitivePinningEnabled) - lets a <PackageVersion> entry in Directory.Packages.props force a transitive dependency to a specific version across every project, without having to add per-project top-level <PackageReference> entries. This becomes the override mechanism for fixing transitive security advisories. 3. Lockfile mode (RestorePackagesWithLockFile=true) - generates packages.lock.json next to each csproj on every restore, committed to source control. Enables deterministic CI restores via dotnet restore --locked-mode (opt-in) and gives Dependabot accurate transitive vulnerability detection. 4. NuGetAudit transitive mode (NuGetAuditMode=all) - surfaces known advisories for both direct and transitive dependencies as NU1901-NU1904 warnings at restore time. On by default in SDK 8.0+; this just enables transitive scanning. Side effects (vulnerabilities discovered by the new audit and fixed in this PR): - Microsoft.SemanticKernel 1.68.0 -> 1.71.0 (CVE-2026-25592 / GHSA-2ww3-72rp-wpp4, critical: arbitrary file write via AI agent function calling. Pulled in transitively as Microsoft.SemanticKernel.Core.) - Microsoft.Bcl.Memory pinned to 10.0.4 via transitive pinning (CVE-2026-26127 / GHSA-73j8-2gch-69rq, high: DoS via Base64Url out-of-bounds read. Was being pulled in at 10.0.2 transitively via System.Text.Json 10.x.) Other version reconciliations (chose the higher of conflicting versions): - Microsoft.NET.Test.Sdk: tests on net8.0 use 18.0.1; the orphan net470 project uses VersionOverride=17.5.0 - xunit: net8.0 tests use 2.9.3; orphan net470 project uses VersionOverride=2.4.2 - xunit.runner.visualstudio: net8.0 tests use 3.1.5; orphan net470 project uses VersionOverride=2.4.5 - System.Text.Json 10.0.0 -> 10.0.2 (required by SK 1.71 transitive graph) - Microsoft.Extensions.AI 9.10.2 -> 10.2.0 (required by SK 1.71) - System.Numerics.Tensors 10.0.1 -> 10.0.2 (required by SK 1.71) Verified locally: - dotnet restore TypeChat.sln: clean, zero NU190x audit warnings - dotnet restore tests/EmojiApp/Emoji.sln: clean - dotnet build TypeChat.sln -c Release /warnaserror: 0 warnings, 0 errors - dotnet test tests/TypeChat.UnitTests: 154 passed, 0 failed Note: tests/TypeChat.Tests.Pre6 (net470) is an orphan project not included in TypeChat.sln and not built by CI; it does not generate a lockfile because TypeChat.TestLib only targets net8.0. This is a pre-existing condition unrelated to this change. This PR is preparation for the upcoming fix-dependabot-alerts workflow port - with CPM + transitive pinning + lockfiles in place, automated transitive vulnerability remediation becomes a one-line edit to Directory.Packages.props per fix instead of editing many csproj files. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Per review feedback: NuGet lockfiles are an opt-in feature (not the .NET community default; the dotnet/runtime repo does not commit them either) and without CI enforcement (dotnet restore --locked-mode) they are write-only churn that adds noise to PRs without providing determinism. This commit removes them; CPM + transitive pinning still gives us a single source of truth for versions, and NuGetAudit (mode=all) still catches transitive CVEs at restore time. The 19 deleted files were introduced by the previous commit on this branch and never enforced. - Delete 19 packages.lock.json files - .gitignore: add packages.lock.json so opportunistic local lockfile restores don't get committed again - Directory.Build.props: drop RestorePackagesWithLockFile (audit kept) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
With RestorePackagesWithLockFile removed from Directory.Build.props the default `dotnet restore` no longer produces lockfiles, so the ignore pattern was paranoid. A developer who explicitly runs `dotnet restore --use-lock-file` presumably wants the output visible. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adopts .NET Central Package Management (CPM) repository-wide, introduces a new Directory.Build.props enabling transitive NuGet audit, and uses the resulting audit signal to bump two vulnerable packages (Microsoft.SemanticKernel → 1.71.0 and a pinned transitive Microsoft.Bcl.Memory 10.0.4). All 20 SDK-style csproj files become version-less <PackageReference> entries, with the legacy tests/TypeChat.Tests.Pre6 net470 project using VersionOverride to retain its older xunit/test SDK pins.
Changes:
- Add root
Directory.Packages.props(CPM + transitive pinning) andDirectory.Build.props(NuGetAudit=true,NuGetAuditMode=all); existingsrc/andexamples/Directory.Build.propsexplicitly<Import>the root so MSBuild's first-hit walk-up isn't truncated. - Strip
Version=attributes from every<PackageReference>acrosssrc/,examples/,tests/, andsrc/package/nuget.props; reconcile previously-conflicting versions to the highest (e.g.Microsoft.NET.Test.Sdk18.0.1,xunit2.9.3) and applyVersionOverridein the net470Pre6test project. - Bump versions surfaced by the new transitive audit:
Microsoft.SemanticKernel1.68.0 → 1.71.0, transitiveMicrosoft.Bcl.Memorypinned to 10.0.4,System.Text.Json10.0.0 → 10.0.2,Microsoft.Extensions.AI9.10.2 → 10.2.0,System.Numerics.Tensors10.0.1 → 10.0.2.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
Directory.Packages.props |
New CPM manifest; single source of truth for all package versions, enables transitive pinning, pins vulnerable transitive Microsoft.Bcl.Memory 10.0.4. |
Directory.Build.props |
New repo-root props enabling NuGetAudit in all (transitive) mode. |
src/Directory.Build.props |
Explicitly imports root Directory.Build.props so MSBuild walk-up isn't stopped here. |
examples/Directory.Build.props |
Same explicit root import as src/. |
src/package/nuget.props |
Removes Version from Microsoft.SourceLink.GitHub reference. |
src/typechat/TypeChat.csproj |
Drops versions on System.ComponentModel.Annotations, System.Text.Json, Microsoft.CodeAnalysis.CSharp. |
src/typechat.schema/TypeChat.Schema.csproj |
Drops versions on Microsoft.CodeAnalysis.CSharp, System.ComponentModel.Annotations, System.Text.Json. |
src/typechat.program/TypeChat.Program.csproj |
Drops versions on Microsoft.CodeAnalysis.CSharp, Microsoft.CSharp. |
src/typechat.sk/TypeChat.SemanticKernel.csproj |
Drops versions on Azure.Identity, Microsoft.CSharp, Microsoft.Extensions.Configuration.Binder, Microsoft.SemanticKernel, System.Numerics.Tensors (effective SK bump to 1.71.0 via CPM). |
src/typechat.meai/TypeChat.Extensions.AI.csproj |
Drops versions on Azure.Identity, Microsoft.CSharp, Microsoft.Extensions.AI, Microsoft.Extensions.Configuration.Binder. |
examples/typechat.examplesLib/TypeChat.ExamplesLib.csproj |
Drops versions on Azure.Identity, Microsoft.Extensions.Configuration.*, System.CommandLine. |
tests/EmojiApp/Emoji.csproj |
Drops versions on the three published Microsoft.TypeChat* packages. |
tests/TypeChat.TestLib/TypeChat.TestLib.csproj |
Drops versions on Microsoft.CSharp, Microsoft.Extensions.Configuration.Json, Microsoft.NET.Test.Sdk, xunit, xunit.runner.visualstudio. |
tests/TypeChat.UnitTests/TypeChat.UnitTests.csproj |
Drops versions on Microsoft.NET.Test.Sdk, xunit, xunit.runner.visualstudio. |
tests/TypeChat.IntegrationTests/TypeChat.IntegrationTests.csproj |
Drops versions on Microsoft.NET.Test.Sdk, xunit, xunit.runner.visualstudio, Xunit.SkippableFact. |
tests/TypeChat.Tests.Pre6/TypeChat.Tests.Pre6.csproj |
Uses VersionOverride for net470-compatible older Microsoft.NET.Test.Sdk 17.5.0, xunit 2.4.2, xunit.runner.visualstudio 2.4.5; drops versions on System.Linq and coverlet.collector. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
robgruen
approved these changes
Jun 2, 2026
Resolves conflicts from main commits #314 (Microsoft.Extensions.Configuration.Binder 10.0.1 -> 10.0.2) and #319 (Dependabot grouping config). Conflict resolution: - 3 csproj files (examples/typechat.examplesLib, src/typechat.meai, src/typechat.sk): kept ours (version-less PackageReferences, as required by CPM). - Directory.Packages.props: bumped Microsoft.Extensions.Configuration.Binder PackageVersion from 10.0.1 to 10.0.2 to absorb the #314 change centrally so all consumers pick it up via CPM. - .github/dependabot.yml, OpenAIConfig.cs, integration_tests.yml: merged in cleanly from main without conflict. Validation: - dotnet restore: clean, 0 NU190x warnings - dotnet build /warnaserror: 0 warnings, 0 errors - dotnet test tests/TypeChat.UnitTests: 154/154 passed Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
robgruen
approved these changes
Jun 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Modernizes the .NET package management stack across the whole repo as preparation for an upcoming
fix-dependabot-alertsworkflow port (microsoft/TypeAgent / microsoft/TypeChat equivalent). With CPM + transitive pinning in place, automated transitive vulnerability remediation becomes a one-line edit toDirectory.Packages.propsper fix instead of editing many csproj files.Pairs naturally with #319 (Dependabot grouping config) but can merge independently.
What changes
Directory.Packages.props<PackageVersion>forces a transitive across all projectsDirectory.Build.propsAll 20 SDK-style csproj files become version-less
<PackageReference>entries. Per-project version sprawl collapses (e.g.Microsoft.NET.Test.Sdkpreviously had 2 versions across the repo).Vulnerabilities discovered and fixed by the new audit
The transitive-mode audit immediately surfaced two existing advisories that Dependabot had been blind to (transitive scope wasn't being audited):
Microsoft.SemanticKernelMicrosoft.Bcl.Memory(transitive)Other version reconciliations
Conflicting versions across projects were collapsed to the highest. The orphan
tests/TypeChat.Tests.Pre6net470 project usesVersionOverrideto keep its older xunit / Microsoft.NET.Test.Sdk pins (newer versions dropped net470):Microsoft.NET.Test.Sdk: 18.0.1 (was 17.5.0 + 18.0.1); Pre6 VersionOverride=17.5.0xunit: 2.9.3 (was 2.4.2 + 2.9.3); Pre6 VersionOverride=2.4.2xunit.runner.visualstudio: 3.1.5 (was 2.4.5 + 3.1.5); Pre6 VersionOverride=2.4.5Other bumps required by the SK 1.71 transitive graph:
System.Text.Json10.0.0 → 10.0.2Microsoft.Extensions.AI9.10.2 → 10.2.0System.Numerics.Tensors10.0.1 → 10.0.2On lockfiles (intentionally not adopted)
An earlier revision of this PR committed
packages.lock.jsonfiles for every project. Per reviewer feedback that was reverted in commit b57d385:dotnet/runtime) does not commit them by default.dotnet restore --locked-modeenforced in CI, committed lockfiles are write-only churn that adds noise to every dependency PR without providing determinism.RestorePackagesWithLockFile+ add--locked-modeto CI) without needing this scaffolding to land first.packages.lock.jsonis now in.gitignoreso opportunistic local restores with--use-lock-filedon't get committed back.Local validation
dotnet restore TypeChat.sln: ✅ clean, zero NU190x audit warningsdotnet restore tests/EmojiApp/Emoji.sln: ✅ cleandotnet build TypeChat.sln -c Release /warnaserror(CI's exact build line): ✅ 0 warnings, 0 errorsdotnet test tests/TypeChat.UnitTests: ✅ 154 passed, 0 failedNotes for reviewers
Directory.Build.props+Directory.Packages.props) carry the policy; each existingsrc/Directory.Build.propsandexamples/Directory.Build.propsnow explicitly<Import>the root so the MSBuild auto-discovery chain isn't truncated.tests/TypeChat.Tests.Pre6(net470) is an orphan — not inTypeChat.slnand not built by CI. Pre-existing; unrelated to this PR.Followup PR
A separate PR will add the
fix-dependabot-alertsworkflow (modeled on the microsoft/TypeAgent equivalent) that takes advantage of this scaffold.Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com