Skip to content

chore: update target frameworks to net8.0 and net10.0#7

Merged
joshsmithxrm merged 1 commit intomainfrom
feature/update-target-frameworks
Dec 19, 2025
Merged

chore: update target frameworks to net8.0 and net10.0#7
joshsmithxrm merged 1 commit intomainfrom
feature/update-target-frameworks

Conversation

@joshsmithxrm
Copy link
Copy Markdown
Owner

Summary

  • Drop net6.0 (end of support November 2024)
  • Add net10.0 (current LTS, released November 2025)
  • Package now targets: net462, net8.0, net10.0

Test plan

  • Build succeeds for all target frameworks
  • Tests pass on net8.0 and net10.0
  • NuGet package includes all framework targets

🤖 Generated with Claude Code

- 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>
Copilot AI review requested due to automatic review settings December 19, 2025 20:14
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello @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

  • Target Framework Update: The project's target frameworks have been updated to remove net6.0 (which reaches end of support in November 2024) and introduce net10.0 (the current LTS version, released November 2025).
  • Supported Frameworks: The package now targets net462, net8.0, and net10.0, ensuring compatibility with both older and the latest .NET environments.

🧠 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 Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.0 target framework from the main library project
  • Added net10.0 target 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.

@joshsmithxrm joshsmithxrm merged commit 47ed0b6 into main Dec 19, 2025
8 checks passed
@joshsmithxrm joshsmithxrm deleted the feature/update-target-frameworks branch December 25, 2025 10:10
joshsmithxrm added a commit that referenced this pull request Jan 2, 2026
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>
joshsmithxrm added a commit that referenced this pull request Jan 2, 2026
* 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>
joshsmithxrm added a commit that referenced this pull request Jan 8, 2026
joshsmithxrm added a commit that referenced this pull request Mar 15, 2026
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>
joshsmithxrm added a commit that referenced this pull request Mar 16, 2026
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>
joshsmithxrm added a commit that referenced this pull request Mar 18, 2026
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>
joshsmithxrm added a commit that referenced this pull request Mar 19, 2026
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>
joshsmithxrm added a commit that referenced this pull request Mar 19, 2026
* 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants