diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 19a4712c00..51d5ff43ff 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -24,6 +24,11 @@ "source": "./plugins/dotnet-msbuild", "description": "Comprehensive MSBuild and .NET build skills: failure diagnosis, performance optimization, code quality, and modernization." }, + { + "name": "dotnet-nuget", + "source": "./plugins/dotnet-nuget", + "description": "NuGet and .NET package management: dependency management and modernization." + }, { "name": "dotnet-upgrade", "source": "./plugins/dotnet-upgrade", diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 29e6ee6d48..c4509b004a 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -76,3 +76,7 @@ # dotnet-maui /plugins/dotnet-maui/ @Redth @jfversluis /tests/dotnet-maui/ @Redth @jfversluis + +# dotnet-nuget (package and dependency management) +/plugins/dotnet-nuget/ @dotnet/area-infrastructure-libraries @kartheekp-ms +/tests/dotnet-nuget/ @dotnet/area-infrastructure-libraries @kartheekp-ms diff --git a/.github/plugin/marketplace.json b/.github/plugin/marketplace.json index 19a4712c00..51d5ff43ff 100644 --- a/.github/plugin/marketplace.json +++ b/.github/plugin/marketplace.json @@ -24,6 +24,11 @@ "source": "./plugins/dotnet-msbuild", "description": "Comprehensive MSBuild and .NET build skills: failure diagnosis, performance optimization, code quality, and modernization." }, + { + "name": "dotnet-nuget", + "source": "./plugins/dotnet-nuget", + "description": "NuGet and .NET package management: dependency management and modernization." + }, { "name": "dotnet-upgrade", "source": "./plugins/dotnet-upgrade", diff --git a/README.md b/README.md index 239c08b570..1273af3708 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ This repository contains the .NET team's curated set of core skills and custom a | [dotnet-data](plugins/dotnet-data/) | Skills for .NET data access and Entity Framework related tasks. | | [dotnet-diag](plugins/dotnet-diag/) | Skills for .NET performance investigations, debugging, and incident analysis. | | [dotnet-msbuild](plugins/dotnet-msbuild/) | Comprehensive MSBuild and .NET build skills: failure diagnosis, performance optimization, code quality, and modernization. | +| [dotnet-nuget](plugins/dotnet-nuget/) | NuGet and .NET package management: dependency management and modernization. | | [dotnet-upgrade](plugins/dotnet-upgrade/) | Skills for migrating and upgrading .NET projects across framework versions, language features, and compatibility targets. | | [dotnet-maui](plugins/dotnet-maui/) | Skills for .NET MAUI development: environment setup, diagnostics, and troubleshooting. | | [dotnet-ai](plugins/dotnet-ai/) | AI and ML skills for .NET: technology selection, LLM integration, agentic workflows, RAG pipelines, MCP, and classic ML with ML.NET. | diff --git a/eng/reference-scanner/known-domains.txt b/eng/reference-scanner/known-domains.txt index 1488da3a46..41646d350e 100644 --- a/eng/reference-scanner/known-domains.txt +++ b/eng/reference-scanner/known-domains.txt @@ -37,6 +37,7 @@ github.com/dotnet/dotnet-api-docs github.com/dotnet/dotnet-docker github.com/dotnet/efcore github.com/dotnet/maui +github.com/dotnet/msbuild github.com/dotnet/roslyn github.com/dotnet/runtime github.com/dotnet/sdk @@ -50,6 +51,7 @@ github.com/microsoft/openjdk github.com/microsoft/perfview github.com/microsoftdocs/visualstudio-docs github.com/modelcontextprotocol/csharp-sdk +github.com/NuGet/docs.microsoft.com-nuget # Community ollama.com diff --git a/plugins/dotnet-nuget/plugin.json b/plugins/dotnet-nuget/plugin.json new file mode 100644 index 0000000000..1d83c7b0fb --- /dev/null +++ b/plugins/dotnet-nuget/plugin.json @@ -0,0 +1,6 @@ +{ + "name": "dotnet-nuget", + "version": "0.1.0", + "description": "NuGet and .NET package management skills: dependency management and modernization.", + "skills": "./skills/" +} diff --git a/plugins/dotnet-nuget/skills/convert-to-cpm/SKILL.md b/plugins/dotnet-nuget/skills/convert-to-cpm/SKILL.md new file mode 100644 index 0000000000..c0c1abcdb8 --- /dev/null +++ b/plugins/dotnet-nuget/skills/convert-to-cpm/SKILL.md @@ -0,0 +1,168 @@ +--- +name: convert-to-cpm +description: > + Convert .NET projects and solutions (.sln, .slnx) to NuGet Central Package Management + (CPM) using Directory.Packages.props. USE FOR: converting to CPM, centralizing or + aligning NuGet package versions across multiple projects, inlining MSBuild version + properties from Directory.Build.props into Directory.Packages.props, resolving version + conflicts or mismatches across a solution or repository, updating or bumping or syncing + package versions across projects. Also activate when packages are out of sync, drifting, + or inconsistent — even without the user mentioning CPM. Provides baseline build capture, + version conflict resolution, build validation with binlog comparison, and a structured + post-conversion report. DO NOT USE FOR: packages.config projects (must migrate to + PackageReference first) or repositories that already have CPM fully enabled. +--- + +# Convert to Central Package Management + +Migrate .NET projects from per-project package versioning to NuGet Central Package Management (CPM). CPM centralizes all package versions into a single `Directory.Packages.props` file, making version governance and upgrades easier across multi-project repositories. + +## When to Use + +- The user wants to adopt Central Package Management for a .NET repository, solution, or project +- Package versions are scattered across many `.csproj`, `.fsproj`, or `.vbproj` files and the user wants a single source of truth +- The user mentions `Directory.Packages.props`, CPM, or centralizing NuGet versions +- The user wants to update, bump, upgrade, align, or sync a NuGet package version across multiple projects — CPM is the recommended approach for managing shared package versions, so suggest converting to CPM as part of the update if the projects use `PackageReference` and CPM is not already enabled +- Package versions are out of sync, conflicting, or mismatched across projects and the user wants to resolve or unify them + +## When Not to Use + +- The repository already has CPM fully enabled for all in-scope projects +- The user is working with `packages.config`-based projects (must first migrate to `PackageReference`) +- The user wants to manage versions via a custom MSBuild property file without using CPM + +## Inputs + +| Input | Required | Description | +|-------|----------|-------------| +| Scope | Yes | A project file, solution file, or directory containing .NET projects to convert | +| Version conflict strategy | No | How to resolve cases where the same package has different versions across projects. When conflicts are detected, do not assume a default strategy — ask the user which strategy to use or explicitly confirm a proposed strategy before proceeding. | + +## Workflow + +### Step 1: Determine scope + +- **Single project**: User specifies a `.csproj`, `.fsproj`, or `.vbproj`. +- **Solution**: User specifies a `.sln` or `.slnx`. List projects with `dotnet sln list`. +- **Repository/directory**: No specific file given. Find all project files recursively from the first common ancestor directory of all .NET projects in scope. + +If the scope is unclear, ask the user. + +**Guard: Check for packages.config projects.** Before proceeding, check whether any project in scope uses `packages.config` instead of `PackageReference`. Look for `packages.config` files alongside project files. If any `packages.config` usage is detected, **stop and do not proceed with the conversion**. Inform the user that CPM requires projects with `PackageReference` format and that they must first migrate from `packages.config` to `PackageReference` (e.g., using Visual Studio's built-in migration or the `dotnet migrate` tooling). This skill cannot perform that migration. + +### Step 2: Establish baseline build + +Before making any changes, verify the scope builds successfully and capture a baseline binlog and package list. Run `dotnet clean`, then `dotnet build -bl:baseline.binlog`, then `dotnet package list --format json > baseline-packages.json`. Read [baseline-comparison.md](references/baseline-comparison.md) for the full procedure and fallback options. If the baseline build fails, stop and inform the user — the scope must build cleanly before conversion. Do not delete `baseline.binlog` or `baseline-packages.json` — they are needed for the post-conversion comparison and report. + +### Step 3: Check for existing CPM + +Search for any existing `Directory.Packages.props` in scope or ancestor directories. If CPM is already fully enabled, inform the user and stop. If a `Directory.Packages.props` exists without CPM enabled, ask whether to add the property to the existing file or create a new one. + +### Step 4: Audit package references + +Run `dotnet package list --format json` to get the resolved package references across all in-scope projects. Also scan `` elements to discover shared `.props`/`.targets` files containing package references. + +Check for complexities: version conflicts, MSBuild property-based versions, conditional references, security advisories, and existing `VersionOverride` usage. Read [audit-complexities.md](references/audit-complexities.md) for the full checklist. + +Present audit results to the user before proceeding, including: +- A table of each package, its version(s), and which projects use it +- Any version conflicts, security advisories, or complexities requiring decisions + +When version conflicts exist, present each one individually with the affected projects, the distinct versions found, and the resolution options (align to highest, use `VersionOverride`, etc.) with their trade-offs. Do not upgrade any package beyond the highest version already in use across the scope — this avoids introducing version incompatibilities or breaking changes that are unrelated to the CPM conversion itself. Note any known security advisories or other upgrade opportunities as follow-up items for the user to address after the conversion is complete. Ask the user to decide on each conflict before proceeding. Read [audit-complexities.md § Same package with different versions](references/audit-complexities.md) for the resolution workflow and presentation format. + +### Step 5: Create or update Directory.Packages.props + +Create the file with `dotnet new packagesprops` (.NET 8+) or manually. Add a `` entry for each unique package sorted alphabetically. For conditional versions or `VersionOverride` patterns, read [directory-packages-props.md](references/directory-packages-props.md). + +### Step 6: Update project files + +Remove the `Version` attribute from every `` that now has a corresponding ``. Also update any shared `.props`/`.targets` files identified in step 4. + +- Preserve all other attributes (`PrivateAssets`, `IncludeAssets`, `ExcludeAssets`, `GeneratePathProperty`, `Aliases`) +- Preserve conditional `` elements — only remove the `Version` attribute within them +- Retain each file's existing indentation style (spaces vs. tabs, indentation depth) and blank lines — do not reformat or reorganize unchanged lines +- Use `VersionOverride` (with user confirmation) when a project needs a different version than the central one + +### Step 7: Handle MSBuild version properties + +For `PackageReference` items that used MSBuild properties for versions, determine whether to inline the resolved value or keep the property reference in `Directory.Packages.props`. After validation succeeds in step 8, remove inlined version properties from `Directory.Build.props` or other files, verifying they have no remaining references. Read [msbuild-property-handling.md](references/msbuild-property-handling.md) for the decision workflow, import order requirements, and cleanup procedure. + +### Step 8: Restore and validate + +Run a clean restore and build, capturing a post-conversion binlog and package list. Run `dotnet clean`, then `dotnet build -bl:after-cpm.binlog`, then `dotnet package list --format json > after-cpm-packages.json`. Read [baseline-comparison.md](references/baseline-comparison.md) for the full procedure. If errors occur, read [validation-and-errors.md](references/validation-and-errors.md) for NuGet error codes and multi-TFM guidance. + +**Do not delete or clean up any artifacts** (`baseline.binlog`, `after-cpm.binlog`, `baseline-packages.json`, `after-cpm-packages.json`). These files must be preserved for the user to inspect after the conversion. They are deliverables, not temporary files. + +### Step 9: Post-conversion report + +**You must create a `convert-to-cpm.md` file** alongside the binlog and JSON artifacts. Do not skip this step or substitute inline chat output for the file — the user needs a persistent, shareable document. This file should be self-contained and shareable — suitable for a pull request description, a team review, or a record of what was done. Structure the report with the following sections: + +#### Section 1: Conversion overview + +Summarize what was converted: the scope (project, solution, or repository), number of projects converted, total packages centralized, any projects or packages that were skipped, and any MSBuild properties that were inlined or removed. This gives the reader immediate context. + +#### Section 2: Version conflict resolutions + +If any version conflicts were encountered, list each one with: + +- The package name and all versions that were found across projects +- Which projects used each version +- What the user decided (aligned to highest, used `VersionOverride`, etc.) +- The practical impact: which projects now resolve a different version than before, and which are unchanged + +If no conflicts were found, state that all packages had consistent versions across projects — this is a positive signal worth noting. + +#### Section 3: Package comparison — baseline vs. result + +Compare `baseline-packages.json` and `after-cpm-packages.json` per project. See [baseline-comparison.md](references/baseline-comparison.md) for the comparison procedure. Present two tables: + +- **Changes table**: Packages where the resolved version changed, a `VersionOverride` was introduced, or a package was added/removed. Include a status column explaining what changed and why (e.g., "VersionOverride — project retains pinned version", "Aligned to highest version"). +- **Unchanged table**: All other packages, confirming they resolve identically to baseline. + +If there are no changes at all, state that the conversion is fully version-neutral — this is the ideal outcome and provides reassurance. + +#### Section 4: Risk assessment + +Provide a clear confidence statement: + +- **✅ Low risk** — Conversion is version-neutral; all packages resolve to the same versions as baseline. The build and restore succeeded. Recommend running `dotnet test` as a final check. +- **⚠️ Moderate risk** — Some packages changed versions (e.g., minor/patch alignment). List the affected packages and projects. Recommend reviewing the changes table and running `dotnet test` to verify no regressions. +- **🔴 High risk** — Major version changes were applied, or packages were added/removed unexpectedly. Recommend careful review, running `dotnet test`, and comparing binlogs before merging. + +Call out any specific warnings: `VersionOverride` usage that partially undermines centralization, or MSBuild property removal that could affect other build logic. + +#### Section 5: Follow-up items + +List any items identified during the conversion that the user should address separately after the CPM conversion is complete. These are intentionally out of scope for the conversion itself but important for the user to act on. Common follow-up items include: + +- **Security advisories**: If any package versions are known to have security vulnerabilities (detected via `dotnet package list --vulnerable` or noted during the audit), list each advisory with the package name, current version, affected projects, and the minimum patched version. These upgrades are out of scope for the CPM conversion to avoid introducing version incompatibilities or breaking changes. +- **Deprecated packages**: If any packages are deprecated, note the recommended replacement. +- **Version alignment opportunities**: If `VersionOverride` was used to preserve differing versions, note that the user may want to align these in the future once the affected projects can be validated against the central version. +- **Test validation**: Recommend running `dotnet test` to validate runtime behavior beyond build success, especially if any version conflicts were resolved by aligning to the highest version. + +Present follow-up items as a numbered checklist so the user can track them. + +#### Section 6: Artifacts and how to use them + +List the artifacts produced during conversion and explain how to use them: + +- **`baseline.binlog`** and **`after-cpm.binlog`** — MSBuild binary logs captured before and after conversion. These are available for manual validation and troubleshooting if needed. +- **`baseline-packages.json`** and **`after-cpm-packages.json`** — Machine-readable snapshots of resolved package versions per project, used to produce the comparison tables above. +- **`convert-to-cpm.md`** — This report file, suitable for use as a pull request description or team review artifact. + +Recommend the user run `dotnet test` to validate runtime behavior beyond build success. If any version conflicts were resolved by aligning to the highest version, recommend reviewing the release notes for the affected packages. + +## Validation + +- [ ] Baseline build succeeded before any changes were made +- [ ] `Directory.Packages.props` exists with `ManagePackageVersionsCentrally` set to `true` +- [ ] Every in-scope `PackageReference` either has no `Version` attribute or uses `VersionOverride` +- [ ] Every referenced package has a corresponding `PackageVersion` entry +- [ ] `dotnet restore` and `dotnet build` complete without errors from a clean state +- [ ] Package list comparison shows no unexpected version changes +- [ ] No orphaned version properties remain (unless intentionally kept) + +## More Info + +- [Central Package Management documentation](https://github.com/NuGet/docs.microsoft.com-nuget/blob/main/docs/consume-packages/Central-Package-Management.md) +- [Validation and common errors](references/validation-and-errors.md) diff --git a/plugins/dotnet-nuget/skills/convert-to-cpm/references/audit-complexities.md b/plugins/dotnet-nuget/skills/convert-to-cpm/references/audit-complexities.md new file mode 100644 index 0000000000..6faac988ff --- /dev/null +++ b/plugins/dotnet-nuget/skills/convert-to-cpm/references/audit-complexities.md @@ -0,0 +1,54 @@ +# Audit Complexities + +When auditing `PackageReference` items across in-scope project files, watch for these complexities and flag them to the user: + +## 1. Version set via MSBuild property + +If a `PackageReference` uses a property for its version (e.g., `Version="$(SomePackageVersion)"`), trace the property definition. If the property is defined in a `Directory.Build.props`, `.props` import, or the project file itself, note it for the user. These require manual decisions about whether to replace the property with a literal version in `Directory.Packages.props` or to keep the property and use it within `Directory.Packages.props`. + +See [msbuild-property-handling.md](msbuild-property-handling.md) for decision workflow. + +## 2. Conditional PackageReference items + +If a `PackageReference` is inside a conditional `` (e.g., `Condition="'$(TargetFramework)' == 'net8.0'"`), the version must still be centralized. The `PackageVersion` entry in `Directory.Packages.props` can use the same condition, or the project can use `VersionOverride` if the condition is project-specific. + +## 3. Same package with different versions + +If the same package ID appears with different versions across projects, this is a **version conflict** that requires a user decision before proceeding. CPM requires a single `` per package (unless `VersionOverride` is used), so conflicts must be resolved. + +For each conflict, present a focused summary showing: + +- The package name and all distinct versions found +- Which projects use each version, so the user can see the scope of the disagreement +- Whether the difference is major, minor, or patch — this signals the level of risk +- Any known security advisories on the lower versions (cross-reference with `dotnet package list --vulnerable` if available) + +Then present the resolution options with their trade-offs: + +1. **Align to the highest version** — simplest path; all projects get the latest. Risk: a major version bump may introduce breaking API changes in projects that were on an older version. +2. **Align to the lowest version** — conservative; avoids pulling in untested changes. Risk: projects already on higher versions would be downgraded, which may break them or regress security fixes. +3. **Use `VersionOverride`** — projects that need a different version keep it via `VersionOverride` in their project file. The central `` holds the default. This preserves the status quo but partially undermines centralization for that package. + +Do not upgrade any package beyond the highest version already in use across the scope — this avoids introducing version incompatibilities or breaking changes that are unrelated to the CPM conversion itself. Instead, note any known advisories or upgrade opportunities as follow-up items in the post-conversion report for the user to address after the conversion is complete. + +Ask the user to choose for **each** conflict individually. Do not silently pick a strategy. After each decision, briefly restate what will happen: which projects will see a version change, and which will stay the same. + +- **Major version difference**: Emphasize the risk of breaking API changes. Recommend `VersionOverride` unless the user is prepared to validate all affected projects. +- **Minor or patch difference**: Prefer the highest version but highlight any security advisories. Note that patch-level alignment is usually safe. +- **One version is vulnerable**: Note the advisory in the post-conversion report as a follow-up item. Do not upgrade the version as part of the CPM conversion. + +## 4. Known security advisories + +If a package version is known to have security vulnerabilities (e.g., from nuget.org advisory data or `dotnet package list --vulnerable` output), flag the vulnerable version to the user during the audit. However, do not upgrade any package beyond the highest version already in use across the scope — this avoids introducing version incompatibilities or breaking changes unrelated to the CPM conversion. Instead, record each advisory as a follow-up item in the post-conversion report, including the package name, current version, affected projects, and the minimum patched version. + +## 5. Packages without a Version attribute + +These may already be managed by CPM from a parent directory or may be using a default version. Verify whether a `Directory.Packages.props` in an ancestor directory already provides the version. + +## 6. PackageReference in imported .props/.targets files + +Scan for `` elements in project files and `Directory.Build.props` to discover shared `.props` or `.targets` files that may contain `PackageReference` items. Search those imported files for package references — they need the same treatment but modifying shared build files has broader impact. Flag these to the user. + +## 7. VersionOverride already in use + +If any project already uses `VersionOverride`, note it — this suggests partial CPM adoption may already be in progress. diff --git a/plugins/dotnet-nuget/skills/convert-to-cpm/references/baseline-comparison.md b/plugins/dotnet-nuget/skills/convert-to-cpm/references/baseline-comparison.md new file mode 100644 index 0000000000..e1f9d0cf95 --- /dev/null +++ b/plugins/dotnet-nuget/skills/convert-to-cpm/references/baseline-comparison.md @@ -0,0 +1,92 @@ +# Baseline Comparison + +Verify the CPM conversion is version-neutral by comparing resolved package versions before and after conversion using `dotnet package list`. Binlogs are also captured as artifacts for manual inspection or troubleshooting. + +## Capturing package lists + +Use `dotnet package list` to snapshot resolved versions. Always build from a clean state first to ensure accurate resolution. + +### Baseline (before conversion) + +```bash +dotnet clean +dotnet build -bl:baseline.binlog +dotnet package list --format json > baseline-packages.json +``` + +### Post-conversion (after all changes) + +```bash +dotnet clean +dotnet build -bl:after-cpm.binlog +dotnet package list --format json > after-cpm-packages.json +``` + +If `--format json` is not available (requires .NET 8 SDK+), use the default tabular output: + +```bash +dotnet package list > baseline-packages.txt +``` + +For solution-scoped conversions, pass the solution file to all commands. + +## Producing the comparison + +Compare `baseline-packages.json` and `after-cpm-packages.json` per project. For each project, identify: + +1. **Version changes**: Packages whose resolved version differs. +2. **Added packages**: Packages present after conversion but not in the baseline. +3. **Removed packages**: Packages present in the baseline but not after conversion. +4. **VersionOverride entries**: Packages that use `VersionOverride` (their version matches baseline but the mechanism changed). +5. **Transitive changes**: If `CentralPackageTransitivePinningEnabled` was set, note any transitive packages that are now pinned. + +### Example comparison tables + +Present changes and unchanged packages in separate tables. The **Changes** table highlights anything that differs from baseline — version alignment from conflict resolution, `VersionOverride` entries, and added/removed packages. The **Unchanged** table lists everything else for reference and confidence. + +**Changes:** + +``` +| Project | Package | Before | After | Status | +|---------|---------|--------|-------|--------| +| Legacy.csproj | System.Text.Json | 8.0.4 | 9.0.0 | Aligned to highest version | +| Core.csproj | System.Text.Json | 9.0.0 | 9.0.0 | VersionOverride | +| Shared.csproj | Azure.Identity | 1.10.0 | 1.10.0 | VersionOverride | +``` + +**Unchanged:** + +``` +| Project | Package | Version | +|---------|---------|---------| +| Api.csproj | System.Text.Json | 10.0.1 | +| Api.csproj | Azure.Storage.Blobs | 12.24.0 | +| Web.csproj | OpenTelemetry.Extensions.Hosting | 1.15.0 | +| Tests.csproj | xunit | 2.9.3 | +``` + +If there are no changes at all, state that the conversion is fully version-neutral and present only the unchanged table. + +## Binlog artifacts + +MSBuild binary logs (binlogs) are captured alongside the package list snapshots as supplementary artifacts. Inform the user they are available for manual validation and troubleshooting if needed: + +- `baseline.binlog` — Build state before CPM conversion +- `after-cpm.binlog` — Build state after CPM conversion + +The user can learn more about MSBuild binary logs from: +- [Troubleshoot and create logs for MSBuild problems](https://learn.microsoft.com/visualstudio/ide/msbuild-logs?view=visualstudio#provide-msbuild-binary-logs-for-investigation) +- [Obtaining Build Logs with MSBuild](https://learn.microsoft.com/visualstudio/msbuild/obtaining-build-logs-with-msbuild?view=visualstudio#save-a-binary-log) +- https://github.com/dotnet/msbuild/blob/main/documentation/wiki/Binary-Log.md + +## When comparison reveals unexpected differences + +If the post-conversion package list resolves different versions than expected (beyond intentional changes like version conflict alignment or `VersionOverride`), investigate: + +- Missing `` entries causing fallback behavior +- Conditional `` entries not matching the project's target framework +- Import order issues where a property referenced in `Directory.Packages.props` is not yet defined +- Transitive dependency resolution differences from version alignment +- Packages unexpectedly added or removed due to conditional ItemGroup changes + +The binlogs can help diagnose these issues by showing the full MSBuild evaluation and package resolution. Flag any unexpected differences to the user before considering the conversion complete. diff --git a/plugins/dotnet-nuget/skills/convert-to-cpm/references/directory-packages-props.md b/plugins/dotnet-nuget/skills/convert-to-cpm/references/directory-packages-props.md new file mode 100644 index 0000000000..85cc87e781 --- /dev/null +++ b/plugins/dotnet-nuget/skills/convert-to-cpm/references/directory-packages-props.md @@ -0,0 +1,60 @@ +# Directory.Packages.props Creation + +## Placement + +- **Repository scope**: Place at the first common ancestor directory of all in-scope .NET projects. This may not be the repository root — many repos nest source code under `src/` or similar directories. +- **Solution scope**: Place in the solution directory. +- **Single project scope**: Default to the project directory. If the project is inside a repository with other projects that may be converted later, ask the user where to place it. + +Only the nearest `Directory.Packages.props` is evaluated per project. CPM also supports `Directory.Packages.props` in sub-folders — for example, test projects may have different dependencies than source code and can use a separate `Directory.Packages.props` in their sub-folder. A `Directory.Packages.props` in a sub-folder does not implicitly override or extend a parent file; it is independent and replaces the parent for projects in that folder. To share settings, explicitly chain files using MSBuild `` elements. See [Central Package Management rules](https://github.com/NuGet/docs.microsoft.com-nuget/blob/main/docs/consume-packages/Central-Package-Management.md#central-package-management-rules) for how NuGet resolves which file applies. When in doubt about placement, ask the user. + +## Creating the file + +Use the .NET CLI (available in .NET 8+): + +```bash +dotnet new packagesprops +``` + +This generates a `Directory.Packages.props` with `ManagePackageVersionsCentrally` set to `true`. If the CLI template is not available, create the file manually: + +```xml + + + true + + + + + +``` + +## Adding PackageVersion entries + +Add a `` entry for each unique package, using the resolved version from the audit. Sort entries alphabetically by package ID: + +```xml + + +``` + +## Conditional versions + +If the same package needs different versions for different target frameworks, use MSBuild conditions: + +```xml + + +``` + +Ask the user before using conditional versions — it may be preferable to standardize on a single version. + +## VersionOverride + +If a project intentionally needs a different version than the centrally defined one, use `VersionOverride` in the project file instead of removing the `Version` attribute: + +```xml + +``` + +Ask the user before applying `VersionOverride` — in most cases, version alignment is preferred. diff --git a/plugins/dotnet-nuget/skills/convert-to-cpm/references/msbuild-property-handling.md b/plugins/dotnet-nuget/skills/convert-to-cpm/references/msbuild-property-handling.md new file mode 100644 index 0000000000..4a92bf1b8b --- /dev/null +++ b/plugins/dotnet-nuget/skills/convert-to-cpm/references/msbuild-property-handling.md @@ -0,0 +1,58 @@ +# MSBuild Property Handling + +This covers how to handle MSBuild properties that define package versions (e.g., `Version="$(DIVersion)"` or `Version="$(BlobsVersion)"`) during CPM conversion. + +## Import order guidance + +If keeping a property reference in `Directory.Packages.props` (e.g., `Version="$(PackageAVersion)"`), the property must be defined in a file that MSBuild evaluates before `Directory.Packages.props`. Properties in `Directory.Build.props` satisfy this requirement because MSBuild imports `Directory.Build.props` before `Directory.Packages.props`. + +## Part 1: Make property decisions + +For each `PackageReference` that used an MSBuild property for its version: + +### 1.1. Check if the property is used elsewhere + +Search all project files, `.props`, and `.targets` files in scope for references to the property name: + +```bash +# Unix/macOS +grep -r '$(PropertyName)' --include='*.csproj' --include='*.props' --include='*.targets' . + +# Windows (PowerShell) +Get-ChildItem -Recurse -Include *.csproj,*.props,*.targets | Select-String '$(PropertyName)' +``` + +If it appears only in `PackageReference` version attributes, it is safe to remove after inlining. + +### 1.2. Property only used for versioning (in scope) + +If the property is defined in a file within scope (e.g., `Directory.Build.props`), ask the user whether to: + +- **Inline**: Replace the property usage with a literal version in `Directory.Packages.props` and remove the property definition (deferred to step 9) +- **Keep**: Reference the property from `Directory.Packages.props` (e.g., ``) + +### 1.3. Property used for other purposes + +If the property is used beyond package versioning, do not remove it. Use the property's resolved value in `Directory.Packages.props` and inform the user. + +### 1.4. Property defined outside scope + +If the property is defined outside the conversion scope (e.g., in parent repository build infrastructure), flag it to the user and skip that package. Add a comment in `Directory.Packages.props`: + +```xml + +``` + +## Part 2: Clean up obsolete properties + +After restore and build succeed (step 8), remove property definitions that the user chose to inline. Before removing any property, verify it has zero remaining references outside its own definition: + +```bash +# Unix/macOS +grep -r '$(PropertyName)' --include='*.csproj' --include='*.props' --include='*.targets' . + +# Windows (PowerShell) +Get-ChildItem -Recurse -Include *.csproj,*.props,*.targets | Select-String '$(PropertyName)' +``` + +Only remove a property if it has zero remaining references outside its own definition. Preserve all non-versioning properties in the same file (e.g., `OutputPath`, `LangVersion`). diff --git a/plugins/dotnet-nuget/skills/convert-to-cpm/references/validation-and-errors.md b/plugins/dotnet-nuget/skills/convert-to-cpm/references/validation-and-errors.md new file mode 100644 index 0000000000..29e6943f22 --- /dev/null +++ b/plugins/dotnet-nuget/skills/convert-to-cpm/references/validation-and-errors.md @@ -0,0 +1,39 @@ +# Validation and Common Errors + +## Restore validation + +Always validate from a clean state to ensure full package resolution, not incremental cache: + +```bash +dotnet clean +dotnet restore +``` + +For multi-target framework projects (those with `` containing multiple TFMs), verify restore works for each framework. If restoration errors are framework-specific, the solution may require conditional `` entries or `VersionOverride` for specific projects. + +## NuGet error codes + +| Error | Meaning | Fix | +|-------|---------|-----| +| **NU1008** | A `PackageReference` still has a `Version` attribute when CPM is enabled | Remove the `Version` attribute or convert to `VersionOverride` | +| **NU1010** | A `PackageReference` has no corresponding `PackageVersion` entry | Add the missing `` entry to `Directory.Packages.props` | +| **NU1507** | Multiple package sources without package source mapping | Configure [package source mapping](https://learn.microsoft.com/nuget/consume-packages/package-source-mapping) | + +## Build validation + +If `dotnet restore` succeeds, also run `dotnet build` to verify: + +```bash +dotnet build +``` + +## Common pitfalls + +| Pitfall | Solution | +|---------|----------| +| `Directory.Packages.props` not picked up | Ensure it is in the project directory or an ancestor directory. Only the closest one is evaluated | +| Multiple `Directory.Packages.props` files conflict | Use `Import` to chain files, or consolidate into one. Only the nearest file is evaluated per project | +| Version properties in `.props` files cause build errors | Decide whether to inline the version or keep the property. See [msbuild-property-handling.md](msbuild-property-handling.md) | +| Conditional PackageReference loses its condition | Move the condition to the `PackageVersion` entry in `Directory.Packages.props`, or use `VersionOverride` in the project | +| `packages.config` projects are in scope | These must first be [migrated to PackageReference](https://learn.microsoft.com/nuget/consume-packages/migrate-packages-config-to-package-reference) before CPM conversion | +| Global tools or CLI tool references affected | `DotNetCliToolReference` items are deprecated and not managed by CPM. They can be ignored | diff --git a/tests/dotnet-nuget/convert-to-cpm/advanced-multi-complexity/Api/Api.csproj b/tests/dotnet-nuget/convert-to-cpm/advanced-multi-complexity/Api/Api.csproj new file mode 100644 index 0000000000..031504fa0b --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/advanced-multi-complexity/Api/Api.csproj @@ -0,0 +1,15 @@ + + + net8.0;net6.0 + + + + + + + + + + + + diff --git a/tests/dotnet-nuget/convert-to-cpm/advanced-multi-complexity/Api/Program.cs b/tests/dotnet-nuget/convert-to-cpm/advanced-multi-complexity/Api/Program.cs new file mode 100644 index 0000000000..e3b5f129cf --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/advanced-multi-complexity/Api/Program.cs @@ -0,0 +1,4 @@ +using Microsoft.AspNetCore.Builder; + +var builder = WebApplication.CreateBuilder(args); +builder.Build().Run(); diff --git a/tests/dotnet-nuget/convert-to-cpm/advanced-multi-complexity/Common.props b/tests/dotnet-nuget/convert-to-cpm/advanced-multi-complexity/Common.props new file mode 100644 index 0000000000..da46ccfd90 --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/advanced-multi-complexity/Common.props @@ -0,0 +1,5 @@ + + + + + diff --git a/tests/dotnet-nuget/convert-to-cpm/advanced-multi-complexity/Core/Core.csproj b/tests/dotnet-nuget/convert-to-cpm/advanced-multi-complexity/Core/Core.csproj new file mode 100644 index 0000000000..eb9cd67897 --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/advanced-multi-complexity/Core/Core.csproj @@ -0,0 +1,9 @@ + + + net8.0 + + + + + + diff --git a/tests/dotnet-nuget/convert-to-cpm/advanced-multi-complexity/Directory.Build.props b/tests/dotnet-nuget/convert-to-cpm/advanced-multi-complexity/Directory.Build.props new file mode 100644 index 0000000000..edaa89a442 --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/advanced-multi-complexity/Directory.Build.props @@ -0,0 +1,9 @@ + + + latest + enable + 12.24.0 + 8.0.1 + + + diff --git a/tests/dotnet-nuget/convert-to-cpm/advanced-multi-complexity/Enterprise.slnx b/tests/dotnet-nuget/convert-to-cpm/advanced-multi-complexity/Enterprise.slnx new file mode 100644 index 0000000000..175c12419b --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/advanced-multi-complexity/Enterprise.slnx @@ -0,0 +1,7 @@ + + + + + + + diff --git a/tests/dotnet-nuget/convert-to-cpm/advanced-multi-complexity/Legacy/Legacy.csproj b/tests/dotnet-nuget/convert-to-cpm/advanced-multi-complexity/Legacy/Legacy.csproj new file mode 100644 index 0000000000..b2e621bc27 --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/advanced-multi-complexity/Legacy/Legacy.csproj @@ -0,0 +1,9 @@ + + + net6.0 + + + + + + diff --git a/tests/dotnet-nuget/convert-to-cpm/advanced-multi-complexity/Tests/Tests.csproj b/tests/dotnet-nuget/convert-to-cpm/advanced-multi-complexity/Tests/Tests.csproj new file mode 100644 index 0000000000..fb3a889a3e --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/advanced-multi-complexity/Tests/Tests.csproj @@ -0,0 +1,9 @@ + + + net8.0 + + + + + + diff --git a/tests/dotnet-nuget/convert-to-cpm/advanced-multi-complexity/Web/Program.cs b/tests/dotnet-nuget/convert-to-cpm/advanced-multi-complexity/Web/Program.cs new file mode 100644 index 0000000000..e3b5f129cf --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/advanced-multi-complexity/Web/Program.cs @@ -0,0 +1,4 @@ +using Microsoft.AspNetCore.Builder; + +var builder = WebApplication.CreateBuilder(args); +builder.Build().Run(); diff --git a/tests/dotnet-nuget/convert-to-cpm/advanced-multi-complexity/Web/Web.csproj b/tests/dotnet-nuget/convert-to-cpm/advanced-multi-complexity/Web/Web.csproj new file mode 100644 index 0000000000..51ac88b806 --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/advanced-multi-complexity/Web/Web.csproj @@ -0,0 +1,9 @@ + + + net8.0 + + + + + + diff --git a/tests/dotnet-nuget/convert-to-cpm/eval.yaml b/tests/dotnet-nuget/convert-to-cpm/eval.yaml new file mode 100644 index 0000000000..b154142253 --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/eval.yaml @@ -0,0 +1,194 @@ +scenarios: + - name: "Decline CPM conversion for packages.config project" + prompt: "Convert my simple-packages-config/LegacyApp project to Central Package Management." + expect_activation: false + setup: + copy_test_files: true + assertions: + - type: "output_contains" + value: "packages.config" + - type: "output_contains" + value: "PackageReference" + - type: "file_not_exists" + path: "simple-packages-config/Directory.Packages.props" + rubric: + - "Detected the project uses packages.config instead of PackageReference format" + - "Informed the user that CPM requires PackageReference and cannot be applied to packages.config projects" + - "Suggested migrating from packages.config to PackageReference first" + - "Did not attempt to create Directory.Packages.props or modify any project files" + timeout: 300 + + - name: "Recommend CPM when updating packages with version conflicts" + prompt: "The System.Text.Json and Azure.Identity packages have gotten out of sync across projects in moderate-version-conflicts/Inventory.slnx. Can you align them to the latest versions?" + setup: + copy_test_files: true + assertions: + - type: "output_matches" + pattern: "(Central Package Management|CPM|Directory\\.Packages\\.props)" + - type: "output_matches" + pattern: "(conflict|mismatch|different version|out of sync)" + rubric: + - "Identified the version conflicts across projects before attempting any changes" + - "Strongly recommended adopting Central Package Management to prevent versions from drifting apart again in the future" + - "Explained that without CPM, manually aligning versions across projects is error-prone and the same drift will likely recur" + - "Offered to perform the CPM conversion as part of resolving the version alignment request" + timeout: 600 + + - name: "Recommend CPM when updating packages in a complex repository" + prompt: "I need to update and align NuGet package versions across the advanced-multi-complexity/Enterprise.slnx solution. Package versions have drifted out of sync — some are defined as MSBuild properties, some are conditional for multi-targeting, and there's a shared Common.props. Can you bump everything to the latest and get them consistent?" + setup: + copy_test_files: true + assertions: + - type: "output_matches" + pattern: "(Central Package Management|CPM|Directory\\.Packages\\.props)" + - type: "output_matches" + pattern: "(BlobsVersion|HostingVersion|Common\\.props)" + rubric: + - "Audited the repository complexity: MSBuild property-based versions, conditional references, shared props files, and version conflicts across projects" + - "Strongly recommended adopting Central Package Management as essential for a repository of this complexity — manual package updates across scattered version definitions are high-risk and unsustainable" + - "Explained that CPM would consolidate the MSBuild properties, conditional versions, and shared props references into a single governed file, greatly reducing the risk of version drift and update errors" + - "Offered to perform the full CPM conversion rather than making piecemeal version updates that would leave the underlying governance problem unresolved" + timeout: 600 + + - name: "Convert single project to CPM" + prompt: "Convert my project at simple-single-project/MyApp/MyApp.csproj to use Central Package Management." + setup: + copy_test_files: true + assertions: + - type: "file_contains" + path: "simple-single-project/Directory.Packages.props" + value: "ManagePackageVersionsCentrally" + - type: "file_contains" + path: "simple-single-project/Directory.Packages.props" + value: "PackageVersion" + rubric: + - "Created a Directory.Packages.props file with ManagePackageVersionsCentrally set to true" + - "Listed all three packages (Microsoft.Extensions.Logging, Polly, System.Text.Json) as PackageVersion items" + - "Removed Version attributes from PackageReference items in the .csproj" + - "Ran dotnet restore and dotnet build to validate the conversion" + - "Produced a markdown report comparing baseline package references and versions against the CPM result so the user can review what changed" + - "Captured binlogs for both the baseline and converted builds and informed the user they are available for manual validation and troubleshooting" + - "Offered reassurance that the conversion is safe when no material changes were detected, or warned about any risks" + timeout: 600 + + - name: "Convert multi-project solution to CPM" + prompt: "I'd like to convert simple-solution/MyApp.sln to Central Package Management. Use the highest version for any conflicts." + setup: + copy_test_files: true + assertions: + - type: "file_contains" + path: "simple-solution/Directory.Packages.props" + value: "ManagePackageVersionsCentrally" + - type: "file_contains" + path: "simple-solution/Tests/Tests.csproj" + value: "PrivateAssets" + rubric: + - "Enumerated projects in the solution (Web, Core, Tests)" + - "Created Directory.Packages.props at the solution root with ManagePackageVersionsCentrally set to true" + - "Listed all 6 unique packages as PackageVersion items" + - "Removed Version attributes from all three project files" + - "Preserved PrivateAssets attribute on xunit.runner.visualstudio" + - "Ran dotnet restore and dotnet build to validate the conversion" + - "Produced a markdown report summarizing all package references and versions across projects, comparing baseline state against the CPM result" + - "When differing package versions were found across projects, guided the user through reconciliation or explicit acceptance of each version" + - "Captured binlogs for both the baseline and converted builds and informed the user they are available for manual validation and troubleshooting" + - "Offered reassurance when the conversion is straightforward, or warned about potential risks from version changes that could cause unintended consequences" + timeout: 600 + + - name: "Convert solution with MSBuild property versions to CPM" + prompt: "Convert moderate-msbuild-properties/Platform.sln to Central Package Management. The package versions are currently defined as MSBuild properties in Directory.Build.props. Inline the resolved values into Directory.Packages.props and use the highest version for any conflicts." + setup: + copy_test_files: true + assertions: + - type: "file_contains" + path: "moderate-msbuild-properties/Directory.Packages.props" + value: "ManagePackageVersionsCentrally" + - type: "file_not_contains" + path: "moderate-msbuild-properties/Directory.Build.props" + value: "OTelVersion" + - type: "file_not_contains" + path: "moderate-msbuild-properties/Directory.Build.props" + value: "DIVersion" + - type: "file_contains" + path: "moderate-msbuild-properties/Directory.Build.props" + value: "OutputPath" + rubric: + - "Traced each MSBuild property (OTelVersion, DIVersion) to its definition in Directory.Build.props" + - "Clearly showed which packages use properties vs literal versions" + - "Asked the user whether to inline the resolved values or keep the property references" + - "Created Directory.Packages.props with inlined resolved values as directed by the user" + - "Removed only the version-related properties from Directory.Build.props, preserving the OutputPath property" + - "Verified no remaining references to removed properties exist" + - "Ran dotnet restore and dotnet build to validate the conversion" + - "Produced a markdown report summarizing all package references and versions across projects, comparing baseline state against the CPM result" + - "When differing package versions were found across projects, guided the user through reconciliation or explicit acceptance of each version" + - "Captured binlogs for both the baseline and converted builds and informed the user they are available for manual validation and troubleshooting" + - "Offered reassurance when the conversion is straightforward, or warned about potential risks from version or property changes that could cause unintended consequences" + timeout: 600 + + - name: "Convert solution with version conflicts to CPM" + prompt: "Convert moderate-version-conflicts/Inventory.slnx to Central Package Management. Use the highest version for any conflicts." + setup: + copy_test_files: true + assertions: + - type: "file_contains" + path: "moderate-version-conflicts/Directory.Packages.props" + value: "ManagePackageVersionsCentrally" + - type: "output_matches" + pattern: "(conflict|mismatch|different version)" + - type: "file_contains" + path: "moderate-version-conflicts/Directory.Packages.props" + value: "System.Text.Json" + - type: "file_contains" + path: "moderate-version-conflicts/Directory.Packages.props" + value: "Azure.Identity" + rubric: + - "Audited all 4 projects and identified both version conflicts (System.Text.Json and Azure.Identity)" + - "Presented the System.Text.Json conflict clearly: 10.0.1 in Api/Shared/Tests vs 8.0.4 in Worker" + - "Presented the Azure.Identity conflict: 1.13.2 in Api vs 1.10.0 in Shared" + - "Applied the user's chosen strategy of aligning to the highest version for each conflict" + - "Created Directory.Packages.props with the highest version for each conflicting package" + - "Ran dotnet restore and dotnet build to validate the conversion" + - "Produced a markdown report summarizing all package references and resolved versions across projects, comparing baseline state against the CPM result" + - "Guided the user through reconciliation or explicit acceptance of each differing version, surfacing the rationale and impact of each choice" + - "Captured binlogs for both the baseline and converted builds and informed the user they are available for manual validation and troubleshooting" + - "Warned about potential risks from version changes or unintended consequences, and offered reassurance where the resolution is safe" + timeout: 600 + + - name: "Convert complex repository with multiple CPM challenges" + prompt: "I need to convert this entire repository to Central Package Management. The solution is at advanced-multi-complexity/Enterprise.slnx. There are some complications: package versions defined as MSBuild properties, conditional package references for multi-targeting, and a shared Common.props that adds a package to all projects. Inline MSBuild property values and use the highest version for any conflicts." + setup: + copy_test_files: true + assertions: + - type: "file_contains" + path: "advanced-multi-complexity/Directory.Packages.props" + value: "ManagePackageVersionsCentrally" + - type: "file_contains" + path: "advanced-multi-complexity/Directory.Packages.props" + value: "System.Text.Json" + - type: "file_not_contains" + path: "advanced-multi-complexity/Directory.Build.props" + value: "BlobsVersion" + - type: "file_not_contains" + path: "advanced-multi-complexity/Directory.Build.props" + value: "HostingVersion" + - type: "output_matches" + pattern: "(condition|conditional|TargetFramework)" + - type: "output_matches" + pattern: "Common\\.props" + rubric: + - "Performed a thorough audit across all 5 projects plus Common.props and Directory.Build.props" + - "Identified the three-way System.Text.Json version conflict (10.0.1, 9.0.0, 8.0.4) including the security advisory on 8.0.4" + - "Identified the Azure.Storage.Blobs version mismatch between the BlobsVersion property and the literal in Legacy" + - "Traced MSBuild properties (BlobsVersion, HostingVersion) to their definitions in Directory.Build.props" + - "Identified the conditional PackageReference for Microsoft.AspNetCore.Mvc.NewtonsoftJson with different versions per TFM" + - "Identified the PackageReference in Common.props that applies to all projects" + - "Presented the findings and applied the user's chosen strategy of using the highest version for conflicts and inlining MSBuild property values" + - "Created Directory.Packages.props reflecting the user's directed resolution strategy" + - "Preserved non-version properties (LangVersion, ImplicitUsings) in Directory.Build.props" + - "Ran dotnet restore and dotnet build to validate the conversion" + - "Produced a markdown report summarizing all package references, resolved versions, and decisions across projects, comparing baseline state against the CPM result" + - "Guided the user through reconciliation or explicit acceptance of each differing version, including version conflicts, property-based versions, and conditional references" + - "Captured binlogs for both the baseline and converted builds and informed the user they are available for manual validation and troubleshooting" + - "Warned about potential risks from version changes, property removals, or conditional reference adjustments, and offered reassurance where outcomes are safe and expected" + timeout: 600 diff --git a/tests/dotnet-nuget/convert-to-cpm/moderate-msbuild-properties/Api/Api.csproj b/tests/dotnet-nuget/convert-to-cpm/moderate-msbuild-properties/Api/Api.csproj new file mode 100644 index 0000000000..5ba871126e --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/moderate-msbuild-properties/Api/Api.csproj @@ -0,0 +1,9 @@ + + + net8.0 + + + + + + diff --git a/tests/dotnet-nuget/convert-to-cpm/moderate-msbuild-properties/Api/Program.cs b/tests/dotnet-nuget/convert-to-cpm/moderate-msbuild-properties/Api/Program.cs new file mode 100644 index 0000000000..e3b5f129cf --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/moderate-msbuild-properties/Api/Program.cs @@ -0,0 +1,4 @@ +using Microsoft.AspNetCore.Builder; + +var builder = WebApplication.CreateBuilder(args); +builder.Build().Run(); diff --git a/tests/dotnet-nuget/convert-to-cpm/moderate-msbuild-properties/Data/Data.csproj b/tests/dotnet-nuget/convert-to-cpm/moderate-msbuild-properties/Data/Data.csproj new file mode 100644 index 0000000000..62564a7276 --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/moderate-msbuild-properties/Data/Data.csproj @@ -0,0 +1,9 @@ + + + net8.0 + + + + + + diff --git a/tests/dotnet-nuget/convert-to-cpm/moderate-msbuild-properties/Directory.Build.props b/tests/dotnet-nuget/convert-to-cpm/moderate-msbuild-properties/Directory.Build.props new file mode 100644 index 0000000000..47b1574dca --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/moderate-msbuild-properties/Directory.Build.props @@ -0,0 +1,7 @@ + + + 1.15.0 + 9.0.0 + $(MSBuildThisFileDirectory)artifacts\$(MSBuildProjectName)\ + + diff --git a/tests/dotnet-nuget/convert-to-cpm/moderate-msbuild-properties/Platform.sln b/tests/dotnet-nuget/convert-to-cpm/moderate-msbuild-properties/Platform.sln new file mode 100644 index 0000000000..cd1ca070f2 --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/moderate-msbuild-properties/Platform.sln @@ -0,0 +1,24 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Api", "Api\Api.csproj", "{D1E2F3A4-B5C6-7890-1234-567890ABCDEF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Data", "Data\Data.csproj", "{E2F3A4B5-C6D7-8901-2345-67890ABCDEF0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D1E2F3A4-B5C6-7890-1234-567890ABCDEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D1E2F3A4-B5C6-7890-1234-567890ABCDEF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D1E2F3A4-B5C6-7890-1234-567890ABCDEF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D1E2F3A4-B5C6-7890-1234-567890ABCDEF}.Release|Any CPU.Build.0 = Release|Any CPU + {E2F3A4B5-C6D7-8901-2345-67890ABCDEF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E2F3A4B5-C6D7-8901-2345-67890ABCDEF0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E2F3A4B5-C6D7-8901-2345-67890ABCDEF0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E2F3A4B5-C6D7-8901-2345-67890ABCDEF0}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/tests/dotnet-nuget/convert-to-cpm/moderate-version-conflicts/Api/Api.csproj b/tests/dotnet-nuget/convert-to-cpm/moderate-version-conflicts/Api/Api.csproj new file mode 100644 index 0000000000..0a8ee5cd18 --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/moderate-version-conflicts/Api/Api.csproj @@ -0,0 +1,9 @@ + + + net8.0 + + + + + + diff --git a/tests/dotnet-nuget/convert-to-cpm/moderate-version-conflicts/Api/Program.cs b/tests/dotnet-nuget/convert-to-cpm/moderate-version-conflicts/Api/Program.cs new file mode 100644 index 0000000000..e3b5f129cf --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/moderate-version-conflicts/Api/Program.cs @@ -0,0 +1,4 @@ +using Microsoft.AspNetCore.Builder; + +var builder = WebApplication.CreateBuilder(args); +builder.Build().Run(); diff --git a/tests/dotnet-nuget/convert-to-cpm/moderate-version-conflicts/Inventory.slnx b/tests/dotnet-nuget/convert-to-cpm/moderate-version-conflicts/Inventory.slnx new file mode 100644 index 0000000000..dbc7be43d0 --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/moderate-version-conflicts/Inventory.slnx @@ -0,0 +1,6 @@ + + + + + + diff --git a/tests/dotnet-nuget/convert-to-cpm/moderate-version-conflicts/Shared/Shared.csproj b/tests/dotnet-nuget/convert-to-cpm/moderate-version-conflicts/Shared/Shared.csproj new file mode 100644 index 0000000000..dbbe7701de --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/moderate-version-conflicts/Shared/Shared.csproj @@ -0,0 +1,9 @@ + + + net8.0 + + + + + + diff --git a/tests/dotnet-nuget/convert-to-cpm/moderate-version-conflicts/Tests/Tests.csproj b/tests/dotnet-nuget/convert-to-cpm/moderate-version-conflicts/Tests/Tests.csproj new file mode 100644 index 0000000000..fb3a889a3e --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/moderate-version-conflicts/Tests/Tests.csproj @@ -0,0 +1,9 @@ + + + net8.0 + + + + + + diff --git a/tests/dotnet-nuget/convert-to-cpm/moderate-version-conflicts/Worker/Program.cs b/tests/dotnet-nuget/convert-to-cpm/moderate-version-conflicts/Worker/Program.cs new file mode 100644 index 0000000000..f4565698d2 --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/moderate-version-conflicts/Worker/Program.cs @@ -0,0 +1,4 @@ +using Microsoft.Extensions.Hosting; + +var builder = Host.CreateApplicationBuilder(args); +builder.Build().Run(); diff --git a/tests/dotnet-nuget/convert-to-cpm/moderate-version-conflicts/Worker/Worker.csproj b/tests/dotnet-nuget/convert-to-cpm/moderate-version-conflicts/Worker/Worker.csproj new file mode 100644 index 0000000000..94918465b5 --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/moderate-version-conflicts/Worker/Worker.csproj @@ -0,0 +1,10 @@ + + + net8.0 + + + + + + + diff --git a/tests/dotnet-nuget/convert-to-cpm/simple-packages-config/LegacyApp/LegacyApp.csproj b/tests/dotnet-nuget/convert-to-cpm/simple-packages-config/LegacyApp/LegacyApp.csproj new file mode 100644 index 0000000000..ac077673ff --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/simple-packages-config/LegacyApp/LegacyApp.csproj @@ -0,0 +1,14 @@ + + + + + v4.8 + Library + + + + ..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll + + + + diff --git a/tests/dotnet-nuget/convert-to-cpm/simple-packages-config/LegacyApp/packages.config b/tests/dotnet-nuget/convert-to-cpm/simple-packages-config/LegacyApp/packages.config new file mode 100644 index 0000000000..efd7b640c2 --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/simple-packages-config/LegacyApp/packages.config @@ -0,0 +1,4 @@ + + + + diff --git a/tests/dotnet-nuget/convert-to-cpm/simple-single-project/MyApp/MyApp.csproj b/tests/dotnet-nuget/convert-to-cpm/simple-single-project/MyApp/MyApp.csproj new file mode 100644 index 0000000000..fe046a7aa8 --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/simple-single-project/MyApp/MyApp.csproj @@ -0,0 +1,10 @@ + + + net8.0 + + + + + + + diff --git a/tests/dotnet-nuget/convert-to-cpm/simple-solution/Core/Core.csproj b/tests/dotnet-nuget/convert-to-cpm/simple-solution/Core/Core.csproj new file mode 100644 index 0000000000..9578490af0 --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/simple-solution/Core/Core.csproj @@ -0,0 +1,8 @@ + + + net8.0 + + + + + diff --git a/tests/dotnet-nuget/convert-to-cpm/simple-solution/MyApp.sln b/tests/dotnet-nuget/convert-to-cpm/simple-solution/MyApp.sln new file mode 100644 index 0000000000..05212c6c8a --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/simple-solution/MyApp.sln @@ -0,0 +1,30 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Web", "Web\Web.csproj", "{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core", "Core\Core.csproj", "{B2C3D4E5-F6A7-8901-BCDE-F12345678901}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{C3D4E5F6-A7B8-9012-CDEF-123456789012}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Release|Any CPU.Build.0 = Release|Any CPU + {B2C3D4E5-F6A7-8901-BCDE-F12345678901}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B2C3D4E5-F6A7-8901-BCDE-F12345678901}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B2C3D4E5-F6A7-8901-BCDE-F12345678901}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B2C3D4E5-F6A7-8901-BCDE-F12345678901}.Release|Any CPU.Build.0 = Release|Any CPU + {C3D4E5F6-A7B8-9012-CDEF-123456789012}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C3D4E5F6-A7B8-9012-CDEF-123456789012}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C3D4E5F6-A7B8-9012-CDEF-123456789012}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C3D4E5F6-A7B8-9012-CDEF-123456789012}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/tests/dotnet-nuget/convert-to-cpm/simple-solution/Tests/Tests.csproj b/tests/dotnet-nuget/convert-to-cpm/simple-solution/Tests/Tests.csproj new file mode 100644 index 0000000000..44ad7507ef --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/simple-solution/Tests/Tests.csproj @@ -0,0 +1,13 @@ + + + net8.0 + + + + + + + + + + diff --git a/tests/dotnet-nuget/convert-to-cpm/simple-solution/Web/Program.cs b/tests/dotnet-nuget/convert-to-cpm/simple-solution/Web/Program.cs new file mode 100644 index 0000000000..e3b5f129cf --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/simple-solution/Web/Program.cs @@ -0,0 +1,4 @@ +using Microsoft.AspNetCore.Builder; + +var builder = WebApplication.CreateBuilder(args); +builder.Build().Run(); diff --git a/tests/dotnet-nuget/convert-to-cpm/simple-solution/Web/Web.csproj b/tests/dotnet-nuget/convert-to-cpm/simple-solution/Web/Web.csproj new file mode 100644 index 0000000000..5fd46893b1 --- /dev/null +++ b/tests/dotnet-nuget/convert-to-cpm/simple-solution/Web/Web.csproj @@ -0,0 +1,12 @@ + + + net8.0 + + + + + + + + +