Contributing to Intune Commander¶
Thank you for your interest in contributing to Intune Commander! This document provides guidelines for submitting pull requests and maintaining code quality.
Pull Request Guidelines¶
PR Title Convention¶
Use conventional commit format with priority labels:
<type>(<scope>): <description> [Priority]
Examples:
feat(auth): add certificate authentication [P1]
fix(ui): resolve dark mode contrast issue [P1]
docs: update CLAUDE.md with cache patterns [P2]
refactor(services): extract common pagination helper [P3]
test(core): add unit tests for ProfileService [P2]
Types:
feat: New featurefix: Bug fixdocs: Documentation onlyrefactor: Code restructuring without behavior changetest: Adding or updating testsstyle: Code style changes (formatting, etc.)perf: Performance improvementschore: Maintenance tasks, dependencies
Priorities:
[P1]- Critical: Security issues, broken features, blocking bugs[P2]- Important: Significant improvements, major bugs, essential docs[P3]- Enhancement: Nice-to-have features, optimizations, minor fixes
PR Description Template¶
Every PR should include these sections:
## Summary
Brief description of what this PR does and why.
## Changes
- Bullet list of specific modifications
- Each change on its own line
- Link to related issues if applicable
## Test Plan
- [ ] `dotnet build` - no errors/warnings
- [ ] `dotnet test` - all tests pass
- [ ] Manual testing: describe steps taken
- [ ] Specific scenarios verified
## Breaking Changes
If any breaking changes exist:
- Describe what breaks
- Provide migration path
- Update CHANGELOG.md
## Documentation
- [ ] Updated relevant documentation
- [ ] Added code comments where needed
- [ ] Updated CHANGELOG.md if user-facing
Before Submitting¶
- Build and Test Locally
- Follow Code Conventions
- Review
.github/copilot-instructions.md - Review
CLAUDE.mdfor architectural patterns -
Match existing code style
-
Update Documentation
- Update CHANGELOG.md for user-facing changes
- Update CLAUDE.md if changing patterns
-
Add XML doc comments for public APIs
-
Commit Messages
- Use meaningful commit messages
- Reference issue numbers where applicable
- Keep commits focused and atomic
Code Standards¶
C# Conventions¶
- Namespace:
Intune.Commander.Core.*orIntune.Commander.DesktopReact.* - Nullable reference types: Enabled everywhere
- Private fields:
_camelCase - Public members:
PascalCase - Async methods: Always end with
Async, always acceptCancellationToken - React frontend: TypeScript strict mode, Zustand for state, bridge client for .NET interop
Graph API Patterns¶
Manual Pagination (Required)
var response = await _graphClient.SomeEndpoint
.GetAsync(req => req.QueryParameters.Top = 200, cancellationToken);
var result = new List<SomeType>();
while (response != null)
{
if (response.Value != null)
result.AddRange(response.Value);
if (!string.IsNullOrEmpty(response.OdataNextLink))
{
response = await _graphClient.SomeEndpoint
.WithUrl(response.OdataNextLink)
.GetAsync(cancellationToken: cancellationToken);
}
else
{
break;
}
}
Never use PageIterator - it silently truncates results on some tenants.
Async Rules (.NET)¶
Critical: Never block with .Result, .Wait(), or .GetAwaiter().GetResult() — always await.
React Frontend Conventions¶
- Components live in
intune-commander-react/src/components/organized by feature (login/,shell/,workspace/) - State management: Zustand stores in
src/store/— one store per domain (e.g.settingsCatalogStore,searchStore) - .NET interop: Use the typed bridge client in
src/bridge/— never callwindow.chrome.webview.postMessagedirectly - New workspaces: Add a workspace component, a Zustand store, and a bridge service class in the WPF host
Service Implementation Pattern¶
Every Intune object type service follows this pattern:
public interface ISomeService
{
Task<List<SomeType>> ListAsync(CancellationToken cancellationToken = default);
Task<SomeType?> GetByIdAsync(string id, CancellationToken cancellationToken = default);
Task<SomeType> CreateAsync(SomeType item, CancellationToken cancellationToken = default);
Task<SomeType> UpdateAsync(string id, SomeType item, CancellationToken cancellationToken = default);
Task DeleteAsync(string id, CancellationToken cancellationToken = default);
Task<List<Assignment>> GetAssignmentsAsync(string id, CancellationToken cancellationToken = default);
}
public class SomeService : ISomeService
{
private readonly GraphServiceClient _graphClient;
public SomeService(GraphServiceClient graphClient)
{
_graphClient = graphClient;
}
// Implementation with manual pagination on List methods
}
Testing Requirements¶
Unit Tests¶
- Use xUnit with
[Fact]or[Theory] - Test files mirror source structure
- Test class name:
{ClassUnderTest}Tests - Cover: happy path, edge cases, null handling, exceptions
Test Conventions¶
[Fact]
public async Task MethodName_Scenario_ExpectedBehavior()
{
// Arrange
var service = new SomeService(mockClient);
// Act
var result = await service.SomeMethodAsync();
// Assert
Assert.NotNull(result);
}
Documentation Standards¶
Code Comments¶
- Add XML doc comments for public APIs
- Use
//comments sparingly, only for complex logic - Code should be self-documenting where possible
Documentation Files¶
- CHANGELOG.md: User-facing changes, release notes
- CLAUDE.md: Architectural decisions and patterns
- README.md: Getting started, build instructions
Review Process¶
What Reviewers Look For¶
- Correctness: Does it work as intended?
- Tests: Are there sufficient tests?
- Code Quality: Is it maintainable and readable?
- Documentation: Are changes documented?
- Breaking Changes: Are they necessary and documented?
- Performance: Any obvious performance issues?
- Security: No credentials, sensitive data, or vulnerabilities?
Addressing Review Feedback¶
- Respond to all comments
- Make requested changes or explain why not
- Push new commits (don't force-push during review)
- Re-request review after addressing feedback
PR Priorities and Merge Order¶
See GitHub Issues for current PR organization and recommended merge order.
General Priority Order:
- P1 (Critical): Security fixes, broken features, blocking bugs
- P2 (Important): Documentation accuracy, significant improvements
- P3 (Enhancement): Nice-to-have features, optimizations
Dependencies:
- Check GitHub Issues for PR dependencies
- Base your branch on
mainunless depending on another PR - Coordinate with maintainers if multiple PRs affect same code
Getting Help¶
- Questions about implementation: Check
CLAUDE.md - Questions about PR process: See GitHub Issues
- Questions about code patterns: See
.github/copilot-instructions.md - Stuck on something?: Open a draft PR and ask for guidance
Adding a New Workspace¶
The Core library already has 30+ Graph API services built. The main contribution opportunity is wiring them into the React desktop UI as new workspaces. To add a workspace:
- React side: Create a component in
intune-commander-react/src/components/workspace/, a Zustand store, and TypeScript types - Bridge side: Add a bridge service in
src/Intune.Commander.DesktopReact/Services/implementingIBridgeService - Register: Wire the bridge service into
BridgeRouterand add navigation in the React shell
See existing workspaces (Settings Catalog, Detection & Remediation) for the full pattern. Check GitHub Issues for which workspaces are prioritized.
License¶
By contributing to Intune Commander, you agree that your contributions will be licensed under the MIT License.