chore: update target frameworks to net8.0 and net10.0#7
Conversation
- Drop net6.0 (end of support November 2024) - Add net10.0 (current LTS, released November 2025) - Now targets: net462, net8.0, net10.0 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Summary of ChangesHello @joshsmithxrm, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request modernizes the project's target frameworks by removing an outdated version and incorporating the latest Long Term Support (LTS) release. This update ensures the project remains current, secure, and compatible with the evolving .NET ecosystem, facilitating future development and maintenance. Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request updates the project's target frameworks by removing net6.0 and adding net10.0, which is a good proactive measure. The changes to the .csproj files are correct and align with this goal. I have one minor suggestion for the CHANGELOG.md file to improve the accuracy of the description for the newly added framework.
There was a problem hiding this comment.
Pull request overview
This pull request updates the target frameworks for the PPDS.Plugins library by removing net6.0 (which reached end of support in November 2024) and adding net10.0. The package will now target net462, net8.0, and net10.0.
Key Changes:
- Removed
net6.0target framework from the main library project - Added
net10.0target framework to both the library and test projects - Updated changelog to document the framework changes
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/PPDS.Plugins/PPDS.Plugins.csproj | Updated TargetFrameworks from net462;net6.0;net8.0 to net462;net8.0;net10.0 |
| tests/PPDS.Plugins.Tests/PPDS.Plugins.Tests.csproj | Changed from single TargetFramework net8.0 to multi-target net8.0;net10.0 |
| CHANGELOG.md | Added entry documenting the framework target changes in the Unreleased section |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Addresses issues #7, #9, #15, #27 from code review: - #7: Add thread-safety remarks to ConsoleProgressReporter - #9: Add documentation for role mapping limitation in TieredImporter - #15: Replace Console.WriteLine with AuthenticationOutput in auth library - New AuthenticationOutput class allows consumers to redirect or suppress output - Set AuthenticationOutput.Writer = null to suppress, or provide custom Action<string> - #27: Add validation in CredentialProviderFactory before null-forgiveness - ValidateRequiredFields checks GitHubFederated, AzureDevOpsFederated, UsernamePassword 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: add thread-safe async locking to ProfileConnectionSource Add SemaphoreSlim for proper async synchronization in GetSeedClientAsync. The previous implementation checked _seedClient outside any lock, allowing concurrent calls to create duplicate providers and clients. Changes: - Add _asyncLock SemaphoreSlim for async method synchronization - Implement double-check locking pattern in GetSeedClientAsync - Dispose SemaphoreSlim in Dispose method Fixes part of #71 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: use ConcurrentBag for thread-safe provider tracking Replace List<ICredentialProvider> with ConcurrentBag<ICredentialProvider> to prevent collection corruption when CreateFromProfileAsync is called concurrently from multiple threads. Changes: - Add System.Collections.Concurrent using - Change _activeProviders to ConcurrentBag<ICredentialProvider> - Update Dispose to use TryTake pattern instead of Clear() Fixes part of #71 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: properly unregister MSAL cache in InteractiveBrowserCredentialProvider Unregister the MsalCacheHelper from the token cache during disposal to release file locks on the token cache file. Fixes part of #71 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: properly unregister MSAL cache in GlobalDiscoveryService Unregister the MsalCacheHelper from the token cache during disposal to release file locks on the token cache file. Fixes part of #71 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: remove redundant CancellationTokenSource from Program.cs System.CommandLine 2.x handles Ctrl+C automatically and passes the cancellation token to command handlers via SetAction's cancellationToken parameter. The manual CancelKeyPress handler was creating a CTS that was never connected to the command invocation pipeline. Removed the unused CTS and added a clarifying comment about how cancellation is handled. Fixes part of #71 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: use ConcurrentDictionary for entity type code cache Replace Dictionary<string, int> with ConcurrentDictionary<string, int> for the _entityTypeCodeCache to ensure thread-safe access in case of concurrent operations. Fixes part of #71 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: extract duplicate ParseBypassPlugins to DataCommandGroup Move the ParseBypassPlugins method from ImportCommand and CopyCommand to DataCommandGroup as a shared internal helper. Both commands now reference the single implementation. Fixes part of #71 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: suppress NU1702 warning for cross-framework PPDS.Plugins reference PPDS.Plugins must target net462 (Dataverse plugin sandbox requirement) but is referenced by projects targeting net8.0+. Since the package contains only attributes and enums with no framework-specific APIs, this cross-framework reference is intentional and safe. Added explanatory comments in each affected project file. Fixes part of #71 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: remove NU1903 vulnerability warning suppression The high-severity vulnerability in transitive dependencies has been fixed upstream. Remove the suppression so future vulnerabilities are properly reported. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: use X509CertificateLoader for .NET 9+ certificate loading Replace deprecated X509Certificate2 constructor with X509CertificateLoader on .NET 9+. Uses conditional compilation to maintain compatibility with .NET 8. Fixes SYSLIB0057 warnings on net9.0 and net10.0 targets. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: suppress SYSLIB0014 warning for ServicePointManager ServicePointManager is obsolete in .NET 6+, but these settings are required for optimal Dataverse throughput. The Dataverse SDK uses HttpWebRequest internally, so these settings still apply. No alternative exists until Microsoft updates their SDK to use HttpClient. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: use async/await in thread safety tests (xUnit1031) Convert blocking Task.WaitAll() to async Task.WhenAll() to resolve xUnit1031 analyzer warnings about potential deadlocks in test methods. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: address 11 code review findings from #80 Critical fixes: - Fix copy-paste bug in CertificateStoreCredentialProvider (StoreName→StoreLocation) - Fix memory leak in DeviceCodeCredentialProvider.Dispose() (unregister cache) - Fix memory leak in UsernamePasswordCredentialProvider.Dispose() (unregister cache) - Fix double-checked locking bug in ConnectionStringSource (add volatile) High priority fixes: - Add debug logging for expected role lookup failures in TieredImporter - Remove duplicate endpoint lookup in GlobalDiscoveryService - Remove dead code ExecuteBatchesParallelAsync (76 lines) Medium priority fixes: - Redact exception messages in TieredImporter using ConnectionStringRedactor - Add validation for empty entity/field names in CmtSchemaReader - Add validation for MaxParallelEntities >= 1 in ImportOptions - Preserve FaultException error codes in BulkOperationExecutor Closes #80 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: add AuthenticationOutput for configurable auth messaging (#80) Addresses issues #7, #9, #15, #27 from code review: - #7: Add thread-safety remarks to ConsoleProgressReporter - #9: Add documentation for role mapping limitation in TieredImporter - #15: Replace Console.WriteLine with AuthenticationOutput in auth library - New AuthenticationOutput class allows consumers to redirect or suppress output - Set AuthenticationOutput.Writer = null to suppress, or provide custom Action<string> - #27: Add validation in CredentialProviderFactory before null-forgiveness - ValidateRequiredFields checks GitHubFederated, AzureDevOpsFederated, UsernamePassword 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: address remaining issue 71 code review findings (8, 12) Issue 8: Wrap sync-over-async in Task.Run to avoid deadlock - ProfileConnectionSource.GetSeedClient() now runs async code on threadpool to prevent deadlock in sync contexts (UI/ASP.NET) Issue 12: Use Uri.TryCreate instead of try-catch for flow control - AuthCommandGroup.ExtractEnvironmentName() refactored to avoid exception-based control flow 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor: extract phase processors from TieredImporter (#18) Extract schema validation, deferred field processing, and relationship processing into separate classes to improve testability and maintainability. New components: - ISchemaValidator/SchemaValidator: Load target metadata, detect mismatches - DeferredFieldProcessor: Process self-referential lookup updates - RelationshipProcessor: Process M2M associations with role mapping - ImportContext: Shared context for all import phases - FieldMetadataCollection: Type-safe wrapper for field validity data - SchemaMismatchResult: Result type with detailed error message builder - IImportPhaseProcessor/PhaseResult: Common interface for phase processors TieredImporter reduced from 1,085 to 646 lines, now focused on orchestration. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: address PR review feedback (issues 1, 3, 4) - Remove unused roleNameCache from RelationshipProcessor (#1) The cache was built with a network call but never used since LookupRoleByIdAsync queries by ID directly, not by name. - Add volatile to AuthenticationOutput._writer (#3) Ensures thread-safe reads/writes of the static field. - Unify ProfileConnectionSource locking (#4) Both sync and async paths now use the same SemaphoreSlim lock, preventing race conditions between GetSeedClient and GetSeedClientAsync. Also marked _seedClient as volatile for proper double-checked locking. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
Bug #6: Context menu now shows entity name ("Open account Record") when falling back to the row's primary key, instead of generic "Open Record". Bug #7: Added "Filter to This Value" to the results context menu. Right- click a cell to instantly filter the results table to matching rows. Bug #14: Panel titles now use "Profile · Environment — Panel" format. Drops the #N suffix when only one panel is open. Environment-first layout for quick tab identification (e.g., "PPDS · DEV — Data Explorer"). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Bug #6: Context menu now shows entity name ("Open account Record") when falling back to the row's primary key, instead of generic "Open Record". Bug #7: Added "Filter to This Value" to the results context menu. Right- click a cell to instantly filter the results table to matching rows. Bug #14: Panel titles now use "Profile · Environment — Panel" format. Drops the #N suffix when only one panel is open. Environment-first layout for quick tab identification (e.g., "PPDS · DEV — Data Explorer"). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Solutions (#1,#2,#3,#5): Include Managed toggle, sort controls, Visible/API Managed fields, Maker Portal button, isVisible/isApiManaged end-to-end C# support. Import Jobs (#7,#8,#9): Search bar, Operation Context column (end-to-end C#→TS), record count with filtered status. Plugin Traces (#11,#12,#17,#18,#55): CRITICAL Trace Level dropdown fix, Maker Portal URL fix (Dynamics 365 classic), status text labels, record count, search bar. Web Resources (#19): Restored Created By and Created On columns. Connection References (#23,#24,#25,#28,#55): Expandable flow/connection detail with chevron toggle, ISO timestamp formatting, search bar, status badge improvements (Unknown/Unbound), Sync Settings button. Environment Variables (#29,#31,#55): Modified On column restored, search bar, Sync Settings button. Metadata Browser (#37): Custom Only filter toggle for entities. Data Explorer (#41,#42): Clear button, Import button (file dialog). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Solutions (#1,#2,#3,#5): Include Managed toggle, sort controls, Visible/API Managed fields, Maker Portal button, isVisible/isApiManaged end-to-end C# support. Import Jobs (#7,#8,#9): Search bar, Operation Context column (end-to-end C#→TS), record count with filtered status. Plugin Traces (#11,#12,#17,#18,#55): CRITICAL Trace Level dropdown fix, Maker Portal URL fix (Dynamics 365 classic), status text labels, record count, search bar. Web Resources (#19): Restored Created By and Created On columns. Connection References (#23,#24,#25,#28,#55): Expandable flow/connection detail with chevron toggle, ISO timestamp formatting, search bar, status badge improvements (Unknown/Unbound), Sync Settings button. Environment Variables (#29,#31,#55): Modified On column restored, search bar, Sync Settings button. Metadata Browser (#37): Custom Only filter toggle for entities. Data Explorer (#41,#42): Clear button, Import button (file dialog). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(cdp): use pwsh Expand-Archive for VSIX extraction on Windows bsdtar interprets the C: drive prefix as a remote host, breaking VSIX extraction in --vsix mode. Use PowerShell's Expand-Archive on Windows; keep tar on other platforms. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * plan: extension UX audit fixes — 28 findings across 10 phases Side-by-side comparison of legacy v0.3.4 vs new extension produced 55 findings. After triage: 28 fixes, 22 keep-new-behavior, 5 deferred. Organized into 10 phases (1 cross-cutting + 9 per-panel) for parallel agent execution. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(ext): Phase 1 — cross-cutting infrastructure fixes - Add Connection References + Environment Variables to sidebar Tools (#56, #57) - Standardize command titles: "Open Data Explorer", "Open Plugin Traces" (#51) - Remove text-transform: uppercase from 5 panel CSS files for Title Case headers (#10) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(ext): Phases 2-9 — UX audit fixes across all 8 panels Solutions (#1,#2,#3,#5): Include Managed toggle, sort controls, Visible/API Managed fields, Maker Portal button, isVisible/isApiManaged end-to-end C# support. Import Jobs (#7,#8,#9): Search bar, Operation Context column (end-to-end C#→TS), record count with filtered status. Plugin Traces (#11,#12,#17,#18,#55): CRITICAL Trace Level dropdown fix, Maker Portal URL fix (Dynamics 365 classic), status text labels, record count, search bar. Web Resources (#19): Restored Created By and Created On columns. Connection References (#23,#24,#25,#28,#55): Expandable flow/connection detail with chevron toggle, ISO timestamp formatting, search bar, status badge improvements (Unknown/Unbound), Sync Settings button. Environment Variables (#29,#31,#55): Modified On column restored, search bar, Sync Settings button. Metadata Browser (#37): Custom Only filter toggle for entities. Data Explorer (#41,#42): Clear button, Import button (file dialog). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(ext): review fixes — colSpan bug and command injection - Connection References: fix colCount from wrong heuristic (8) to correct value (7) matching actual column count - CDP tool: sanitize paths for PowerShell injection (escape single quotes); use execFileSync for tar on Unix to avoid shell interpretation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * style(ext): extract inline styles to CSS classes per Gemini review Move search input and sort select inline styles to dedicated .toolbar-search and .toolbar-select CSS classes across 4 panels (Connection Refs, Env Variables, Import Jobs, Solutions). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(ext): add missing webview entry points to knip config The 6 non-query/solutions webview panels are esbuild entry points but were missing from knip.json, causing false-positive unused-file reports. Also un-export internal-only types from shared modules. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(ext): solution filter GUID bug and raw ISO timestamps - SolutionFilter shared component used uniqueName as option value instead of GUID id, causing "solutionId must be a valid GUID" error on Web Resources (and silently wrong on Conn Refs / Env Vars) - Import Jobs and Web Resources rendered raw ISO timestamps; add formatDateTime helper matching Plugin Traces / Conn Refs pattern Found by QA blind verification agents. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(ext): review fixes — escaping, shell safety, URL normalization - Solutions panel: escape rootComponentBehavior and boolean ternaries before innerHTML insertion (S1 compliance) - Connection References: escape literal "Unbound" for consistent escaping discipline - CDP tool: use execFileSync instead of execSync for PowerShell VSIX extraction (S2 compliance — no shell: true) - Plugin Traces: strip trailing slash from environment URL before Maker Portal link construction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(ext): escape formatDate output in solutions detail card Wrap formatDate() calls in escapeHtml() for consistent escaping discipline — formatDate can return raw ISO string on parse failure. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
net6.0(end of support November 2024)net10.0(current LTS, released November 2025)net462,net8.0,net10.0Test plan
🤖 Generated with Claude Code