Skip to content

refactor: add logging to GetComponentTypeAsync catch block#110

Merged
joshsmithxrm merged 2 commits intomainfrom
xenodochial-black
Jan 3, 2026
Merged

refactor: add logging to GetComponentTypeAsync catch block#110
joshsmithxrm merged 2 commits intomainfrom
xenodochial-black

Conversation

@joshsmithxrm
Copy link
Copy Markdown
Owner

Summary

  • Add required ILogger<PluginRegistrationService> dependency to enable diagnostic logging
  • Replace generic catch clause with specific FaultException handlers for better error categorization
  • Log metadata retrieval failures at Debug level for troubleshooting

Changes

  • PluginRegistrationService - Added logger dependency, specific exception handling in GetComponentTypeAsync
  • Command handlers - Updated ListCommand, CleanCommand, DiffCommand, DeployCommand to get logger from DI
  • Tests - Added 6 unit tests for PluginRegistrationService

Test plan

  • All unit tests pass (216 CLI tests, 6 new)
  • Build succeeds with warnings as errors
  • Changelog updated

Fixes #61

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings January 3, 2026 09:08
@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 significantly enhances the security and robustness of the application's authentication mechanisms. It introduces a dedicated secure credential store to isolate sensitive information from profile configurations, aligning with best practices for handling secrets. Concurrently, it refines error handling and logging within the plugin registration process, making the system more resilient and easier to diagnose. The underlying profile storage schema has been updated to a more flexible and secure version, with a clear migration path for existing users.

Highlights

  • Secure Credential Storage: Sensitive authentication details like client secrets, certificate passwords, and user passwords are now stored in platform-native secure storage (e.g., Windows DPAPI, macOS Keychain, Linux libsecret) using MSAL.Extensions, rather than directly in the profile JSON.
  • Profile Storage Schema V2: The authentication profile storage format has been modernized to schema v2. Profiles are now stored as an array, and the active profile is tracked by name instead of a numeric index. Existing v1 profiles will be automatically deleted upon the first load, requiring users to re-authenticate.
  • Improved Logging and Error Handling: The PluginRegistrationService now includes an ILogger dependency for diagnostic output. The GetComponentTypeAsync method's catch block has been refined to handle specific FaultException types, logging metadata retrieval failures at a Debug level for better troubleshooting without disrupting graceful degradation.
  • Credential Provider Factory Enhancements: A new asynchronous CredentialProviderFactory.CreateAsync() method has been introduced to retrieve secrets from the secure store. It also supports an environment variable (PPDS_SPN_SECRET) for service principal secrets in CI/CD scenarios, providing more flexible credential management.
  • AuthProfile and EnvironmentInfo Simplification: Several redundant or sensitive fields have been removed from AuthProfile (e.g., ClientSecret, Password, CertificatePassword) as they are now managed by the secure credential store. EnvironmentInfo.Id has also been removed, with OrganizationId or EnvironmentId being used instead. A new AuthProfile.Authority field stores the full authority URL.
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 introduces a significant and valuable security enhancement by refactoring authentication profile storage, moving secrets from a JSON file to a platform-native secure store using MSAL.Extensions. The introduction of a v2 profile schema is handled well, with a clear (though destructive) migration path for v1 profiles. The secondary change to add logging and specific exception handling in PluginRegistrationService also improves diagnostics and robustness. The code is well-structured and includes comprehensive test updates. I have a few suggestions to further improve exception handling and code quality, such as refining JsonException handling in ProfileStore.cs and addressing a redundant null check.

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 PR adds diagnostic logging to PluginRegistrationService and replaces generic exception handling with specific FaultException handlers for better error categorization. Additionally, it includes a major refactoring to profile storage schema v2 with platform-native secure credential storage.

Key Changes:

  • Added ILogger<PluginRegistrationService> dependency for diagnostic logging in exception handlers
  • Replaced generic catch clause with specific FaultException<OrganizationServiceFault> and FaultException handlers in GetComponentTypeAsync
  • Migrated profile storage to v2 schema using array-based storage and name-based active profile tracking
  • Implemented SecureCredentialStore for platform-native credential encryption (DPAPI/Keychain/libsecret)
  • Moved secrets from profile JSON to secure credential store

Reviewed changes

Copilot reviewed 27 out of 27 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/PPDS.Cli/Plugins/Registration/PluginRegistrationService.cs Added logger dependency and specific exception handling for metadata retrieval failures
src/PPDS.Cli/Commands/Plugins/ListCommand.cs Updated to inject logger for PluginRegistrationService
src/PPDS.Cli/Commands/Plugins/DiffCommand.cs Updated to inject logger for PluginRegistrationService
src/PPDS.Cli/Commands/Plugins/DeployCommand.cs Updated to inject logger for PluginRegistrationService
src/PPDS.Cli/Commands/Plugins/CleanCommand.cs Updated to inject logger for PluginRegistrationService
src/PPDS.Cli/Commands/Auth/AuthCommandGroup.cs Updated to use secure credential store for storing secrets during profile creation
src/PPDS.Cli/CHANGELOG.md Documented breaking changes and new logger requirement
src/PPDS.Auth/Profiles/ProfileStore.cs Refactored to support v2 schema with v1 migration (deletion) logic
src/PPDS.Auth/Profiles/ProfileCollection.cs Changed from dictionary to array storage with name-based active profile
src/PPDS.Auth/Profiles/EnvironmentInfo.cs Removed redundant Id field
src/PPDS.Auth/Profiles/AuthProfile.cs Removed secret fields (ClientSecret, CertificatePassword, Password) and added Authority field
src/PPDS.Auth/Profiles/ProfilePaths.cs Added CredentialCacheFileName constant
src/PPDS.Auth/Credentials/SecureCredentialStore.cs New class providing platform-native encrypted credential storage
src/PPDS.Auth/Credentials/ISecureCredentialStore.cs New interface defining secure credential storage contract
src/PPDS.Auth/Credentials/CredentialProviderFactory.cs Added CreateAsync method supporting secure store lookups and environment variable overrides
src/PPDS.Auth/Credentials/ClientSecretCredentialProvider.cs Updated factory methods to support credential store and environment variables
src/PPDS.Auth/Credentials/CertificateFileCredentialProvider.cs Updated factory methods to support credential store for passwords
src/PPDS.Auth/Credentials/JwtClaimsParser.cs Refactored claim extraction with helper methods
src/PPDS.Auth/CHANGELOG.md Documented breaking changes for profile v2 schema and secure credential storage
tests/PPDS.Cli.Tests/Plugins/Registration/PluginRegistrationServiceTests.cs Added 6 unit tests for basic PluginRegistrationService operations
tests/PPDS.Cli.Tests/PPDS.Cli.Tests.csproj Added Moq package reference for testing
tests/PPDS.Auth.Tests/Profiles/ProfileStoreTests.cs Updated tests for v2 schema including migration tests
tests/PPDS.Auth.Tests/Profiles/ProfileCollectionTests.cs Updated tests for name-based active profile tracking
tests/PPDS.Auth.Tests/Profiles/EnvironmentInfoTests.cs Removed Id parameter from tests
tests/PPDS.Auth.Tests/Profiles/AuthProfileTests.cs Removed secret field tests and updated validation tests
tests/PPDS.Auth.Tests/Credentials/SecureCredentialStoreTests.cs New comprehensive test suite for secure credential storage
tests/PPDS.Auth.Tests/Credentials/CredentialProviderFactoryTests.cs Updated tests for new credential store requirements

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@codecov
Copy link
Copy Markdown

codecov bot commented Jan 3, 2026

- Add required ILogger<PluginRegistrationService> dependency
- Update all callers (ListCommand, CleanCommand, DiffCommand, DeployCommand)
  to get logger from service provider and pass to constructor
- Replace generic catch clause with specific FaultException handlers
- Log failures at Debug level for troubleshooting while maintaining
  graceful degradation behavior (returns 0 to skip solution addition)
- Add System.ServiceModel using for FaultException types
- Add unit tests for PluginRegistrationService

Fixes #61

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@joshsmithxrm
Copy link
Copy Markdown
Owner Author

@gemini-code-assist review

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 is a solid improvement, correctly adding dependency injection for the logger and enhancing exception handling in PluginRegistrationService with more specific FaultException catches and diagnostic logging. The changes are consistently applied across all relevant command handlers. The addition of unit tests for PluginRegistrationService is also a great step forward for code quality.

My review includes a couple of suggestions for the new test file to further improve its robustness and consistency with the project's coding standards, primarily by using the existing early-bound entity classes and by adding a test case to verify the new logging behavior.

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

Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Refactor tests to use early-bound entity classes (PluginAssembly,
  SdkMessage) instead of late-bound Entity with magic strings
- Fix exception handling tests to use UpsertPluginTypeAsync (which
  actually calls GetComponentTypeAsync) instead of UpsertPackageAsync
  (which uses CreateWithSolutionHeaderAsync and doesn't call it)
- Add tests for FaultException, FaultException<OrganizationServiceFault>,
  and solution addition skip when componentType returns 0

Addresses bot review comments #8, #14, #15

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@joshsmithxrm joshsmithxrm merged commit a34a713 into main Jan 3, 2026
8 checks passed
@github-project-automation github-project-automation bot moved this from Todo to Done in PPDS Roadmap Jan 3, 2026
@joshsmithxrm joshsmithxrm deleted the xenodochial-black branch January 3, 2026 18:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

refactor: add logging to GetComponentTypeAsync catch block

3 participants