Skip to content

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 feature
  • fix: Bug fix
  • docs: Documentation only
  • refactor: Code restructuring without behavior change
  • test: Adding or updating tests
  • style: Code style changes (formatting, etc.)
  • perf: Performance improvements
  • chore: 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

  1. Build and Test Locally
dotnet build
dotnet test
  1. Follow Code Conventions
  2. Review .github/copilot-instructions.md
  3. Review CLAUDE.md for architectural patterns
  4. Match existing code style

  5. Update Documentation

  6. Update CHANGELOG.md for user-facing changes
  7. Update CLAUDE.md if changing patterns
  8. Add XML doc comments for public APIs

  9. Commit Messages

  10. Use meaningful commit messages
  11. Reference issue numbers where applicable
  12. Keep commits focused and atomic

Code Standards

C# Conventions

  • Namespace: Intune.Commander.Core.* or Intune.Commander.DesktopReact.*
  • Nullable reference types: Enabled everywhere
  • Private fields: _camelCase
  • Public members: PascalCase
  • Async methods: Always end with Async, always accept CancellationToken
  • 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.

// ❌ BAD
var result = SomeAsyncMethod().Result;

// ✅ GOOD
var result = await SomeAsyncMethod();

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 call window.chrome.webview.postMessage directly
  • 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

  1. Correctness: Does it work as intended?
  2. Tests: Are there sufficient tests?
  3. Code Quality: Is it maintainable and readable?
  4. Documentation: Are changes documented?
  5. Breaking Changes: Are they necessary and documented?
  6. Performance: Any obvious performance issues?
  7. 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:

  1. P1 (Critical): Security fixes, broken features, blocking bugs
  2. P2 (Important): Documentation accuracy, significant improvements
  3. P3 (Enhancement): Nice-to-have features, optimizations

Dependencies:

  • Check GitHub Issues for PR dependencies
  • Base your branch on main unless 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:

  1. React side: Create a component in intune-commander-react/src/components/workspace/, a Zustand store, and TypeScript types
  2. Bridge side: Add a bridge service in src/Intune.Commander.DesktopReact/Services/ implementing IBridgeService
  3. Register: Wire the bridge service into BridgeRouter and 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.