Thank you for your interest in contributing to the UptimeRobot .NET Client Library! This document provides guidelines and instructions for contributing.
- Code of Conduct
- Getting Started
- Development Setup
- How to Contribute
- Coding Standards
- Testing Guidelines
- Pull Request Process
- Reporting Issues
- Feature Requests
This project adheres to a code of conduct that all contributors are expected to follow:
- Be Respectful: Treat everyone with respect and kindness
- Be Collaborative: Work together constructively
- Be Professional: Keep discussions focused and professional
- Be Inclusive: Welcome contributors of all backgrounds and experience levels
See SECURITY.md for:
- How to handle API keys safely in tests
- Protected file patterns in
.gitignore - Best practices for secret management
- What to do if you accidentally commit a key
Before you begin, ensure you have the following installed:
- .NET SDK: 9.0, 8.0, or 6.0 (preferably all three for testing)
- Download from: https://dotnet.microsoft.com/download
- Git: For version control
- Download from: https://git-scm.com/
- IDE: Visual Studio 2022, VS Code, or JetBrains Rider
- Fork the repository on GitHub
- Clone your fork locally:
git clone https://github.com/YOUR_USERNAME/uptimerobot-dotnet.git cd uptimerobot-dotnet - Add the upstream repository:
git remote add upstream https://github.com/strvmarv/uptimerobot-dotnet.git
dotnet restoredotnet builddotnet test# Build for all frameworks
dotnet build --configuration Release
# Test on all frameworks
dotnet test --configuration Releaseuptimerobot-dotnet/
├── src/ # Source code
│ ├── Apis/ # API implementations
│ ├── Exceptions/ # Custom exceptions
│ ├── Models/ # Data models
│ └── *.cs # Core client files
├── test/ # Test projects
│ └── UptimeRobotDotNetTests/
├── docs/ # Documentation
├── .editorconfig # Code style configuration
└── README.md # Main documentation
We welcome various types of contributions:
- Bug Fixes: Fix issues reported in GitHub Issues
- New Features: Implement new functionality
- Documentation: Improve or add documentation
- Tests: Add or improve test coverage
- Performance: Optimize existing code
- Code Quality: Refactoring and cleanup
- Check Existing Issues: Look for existing issues or create a new one
- Discuss First: For major changes, discuss in an issue first
- Create a Branch: Create a feature branch from
main - Make Changes: Implement your changes
- Write Tests: Add tests for new functionality
- Update Documentation: Update docs as needed
- Submit PR: Create a pull request
Use descriptive branch names:
feature/add-account-details-api
bugfix/fix-pagination-offset
docs/improve-readme-examples
test/add-status-page-tests
refactor/optimize-reflection-caching
Follow standard .NET coding conventions:
- PascalCase for class names, method names, and public properties
- camelCase for local variables and private fields
- _camelCase for private fields (with underscore prefix)
- UPPERCASE for constants
The project includes .editorconfig for consistent formatting. Ensure your IDE respects these settings.
-
Nullable Reference Types
- Enable nullable reference types in all new files
- Explicitly mark nullable and non-nullable types
public string? NullableString { get; set; } public string NonNullableString { get; set; } = null!;
-
Async/Await
- Use
async/awaitfor all I/O operations - Use
ConfigureAwait(false)in library code - Accept
CancellationTokenin all async methods
public async Task<Result> GetDataAsync(CancellationToken cancellationToken = default) { var data = await _httpClient.GetAsync(url, cancellationToken).ConfigureAwait(false); return data; }
- Use
-
Exception Handling
- Use custom exception types:
UptimeRobotException,UptimeRobotApiException,UptimeRobotValidationException - Include meaningful error messages
- Log errors appropriately
if (response.Stat == "fail") { throw new UptimeRobotApiException("API request failed", response); }
- Use custom exception types:
-
XML Documentation
- Add XML comments to all public APIs
- Include
<summary>,<param>,<returns>, and<exception>tags
/// <summary> /// Gets a specific monitor by ID. /// </summary> /// <param name="parameters">Search parameters including monitor ID.</param> /// <param name="cancellationToken">Cancellation token for the request.</param> /// <returns>A <see cref="UtrResponse"/> containing the monitor details.</returns> /// <exception cref="UptimeRobotApiException">Thrown when the API returns an error.</exception> public async Task<UtrResponse> GetMonitorAsync( MonitorSearchParameters parameters, CancellationToken cancellationToken = default)
-
Model Properties
- Use PascalCase for property names
- Include
[JsonPropertyName]for API field mapping - Add validation attributes where appropriate
[Required] [JsonPropertyName("friendly_name")] public string FriendlyName { get; set; } = null!; [Range(60, 86400)] [JsonPropertyName("interval")] public int? Interval { get; set; }
-
Enums
- Use strongly-typed enums instead of magic numbers
- Add XML documentation to enum members
/// <summary> /// Represents the type of monitor. /// </summary> public enum MonitorType : int { /// <summary> /// HTTP(s) monitor. /// </summary> HTTP = 1, /// <summary> /// Keyword monitor. /// </summary> Keyword = 2 }
All contributions must include appropriate tests:
- Unit Tests: Test individual components in isolation
- Integration Tests: Test interaction between components
- Edge Cases: Test boundary conditions and error scenarios
Use NUnit framework with the following pattern:
[Test]
public async Task GetMonitor_WithValidId_ReturnsMonitor()
{
// Arrange
var mockParameters = new MonitorSearchParameters { Monitors = "123456" };
Server.Given(Request.Create()
.WithPath($"/{UptimeRobotClientBase.GetRelativePathWithDefaultVersion(UptimeRobotClient.MonitorsGetPath)}")
.UsingPost())
.RespondWith(Response.Create()
.WithStatusCode(200)
.WithBodyAsJson(new
{
stat = "ok",
monitors = new[] { new { id = 123456, friendly_name = "Test" } }
}));
// Act
var client = UptimeRobotClientFactory.Create(Server.CreateClient(), TestApiKey);
var result = await client.GetMonitorAsync(mockParameters);
// Assert
Assert.That(result, Is.Not.Null);
Assert.That(result.Monitors?.Count, Is.GreaterThan(0));
}- Place tests in corresponding folders:
Monitors/,AlertContacts/, etc. - Name test classes with
Testssuffix:MonitorsTests,AlertContactsTests - Use descriptive test method names:
MethodName_Scenario_ExpectedResult - Mark manual integration tests with
[Explicit]attribute
# Run all tests
dotnet test
# Run tests for specific framework
dotnet test --framework net9.0
# Run tests with coverage
dotnet test /p:CollectCoverage=true
# Run specific test
dotnet test --filter "FullyQualifiedName~MonitorsTests.GetMonitor"
# Run tests with verbose output
dotnet test --verbosity detailed- Unit Tests: Aim for >90% coverage
- Integration Tests: Cover all major API paths
- Edge Cases: Test error conditions and boundaries
-
Update Your Branch
git fetch upstream git rebase upstream/main
-
Run All Tests
dotnet test -
Check for Linter Warnings
dotnet build
-
Update Documentation
- Update README.md if adding features
- Update CHANGELOG.md with your changes
- Add XML documentation to new public APIs
-
Push Your Branch
git push origin feature/your-feature-name
-
Create PR on GitHub
- Use a clear, descriptive title
- Reference related issues (e.g., "Fixes #123")
- Provide detailed description of changes
- Include screenshots/examples if applicable
## Description
Brief description of the changes
## Related Issues
Fixes #123
## Type of Change
- [ ] Bug fix (non-breaking change that fixes an issue)
- [ ] New feature (non-breaking change that adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] Documentation update
## Testing
- [ ] Unit tests added/updated
- [ ] All tests pass
- [ ] Manual testing completed
## Checklist
- [ ] Code follows project style guidelines
- [ ] Self-review completed
- [ ] XML documentation added
- [ ] Tests added/updated
- [ ] Documentation updated
- [ ] No new warnings introduced- Automated Checks: GitHub Actions will run tests automatically
- Code Review: Maintainers will review your code
- Address Feedback: Make requested changes
- Approval: Once approved, your PR will be merged
-
Delete Your Branch (optional)
git branch -d feature/your-feature-name git push origin --delete feature/your-feature-name
-
Update Your Fork
git checkout main git pull upstream main git push origin main
When reporting a bug, include:
- Description: Clear description of the bug
- Steps to Reproduce: Step-by-step instructions
- Expected Behavior: What should happen
- Actual Behavior: What actually happens
- Environment: .NET version, OS, library version
- Code Sample: Minimal reproducible example
- Stack Trace: If applicable
## Bug Description
[Clear description of the bug]
## Steps to Reproduce
1. Step one
2. Step two
3. Step three
## Expected Behavior
[What should happen]
## Actual Behavior
[What actually happens]
## Environment
- Library Version: 2.0.0
- .NET Version: 9.0
- OS: Windows 11 / Ubuntu 22.04 / macOS Sonoma
## Code Sample
```csharp
var client = UptimeRobotClientFactory.Create("api-key");
var result = await client.GetMonitorsAsync();
// Bug occurs here[If applicable]
## Feature Requests
### Proposing New Features
1. **Check Existing Issues**: Ensure it's not already requested
2. **Create Issue**: Open a new issue with "Feature Request" label
3. **Describe Feature**: Explain what and why
4. **Provide Examples**: Show how it would be used
5. **Discuss**: Engage in discussion with maintainers
### Feature Request Template
```markdown
## Feature Description
[Clear description of the feature]
## Use Case
[Why is this feature needed? What problem does it solve?]
## Proposed Solution
[How would this feature work?]
## Example Usage
```csharp
// Example of how the feature would be used
[Other approaches you've thought about]
[Any other relevant information]
## Development Best Practices
### 1. Keep PRs Focused
- One feature/fix per PR
- Smaller PRs are easier to review
- Split large changes into multiple PRs
### 2. Write Clear Commit Messages
This project uses [Conventional Commits](https://www.conventionalcommits.org/) and [release-please](https://github.com/googleapis/release-please) for automated releases. Your commit message prefixes directly control version bumps:
| Prefix | Version Bump | Example |
|--------|-------------|---------|
| `feat:` | Minor (x.Y.0) | `feat: add support for account details API` |
| `fix:` | Patch (x.y.Z) | `fix: correct pagination offset calculation` |
| `feat!:` or `BREAKING CHANGE:` | Major (X.0.0) | `feat!: rename all properties to PascalCase` |
| `docs:` | No release | `docs: update README with new examples` |
| `test:` | No release | `test: add tests for status page API` |
| `chore:` | No release | `chore: update CI workflow` |
| `refactor:` | No release | `refactor: optimize BaseModel reflection caching` |
### 3. Update Documentation
- Keep docs in sync with code
- Add examples for new features
- Update API reference if needed
### 4. Performance Considerations
- Profile before optimizing
- Add benchmarks for performance changes
- Consider memory allocations
- Use `ConfigureAwait(false)` in library code
### 5. Backward Compatibility
- Avoid breaking changes when possible
- Mark deprecated APIs with `[Obsolete]`
- Provide migration path for breaking changes
- Update CHANGELOG.md for all breaking changes
### 6. Release Process
This project uses [release-please](https://github.com/googleapis/release-please) for fully automated releases. There are no manual version bumps or changelog edits required.
**How it works:**
1. Merge PRs to `main` using Conventional Commit messages (see above)
2. release-please automatically opens/updates a **Release PR** with:
- Version bump in `src/UptimeRobotDotnet.csproj`
- Updated `CHANGELOG.md` entries
3. When a maintainer merges the Release PR:
- A Git tag and GitHub Release are created automatically
- The `publish` job builds, tests, and pushes the NuGet package
**Important:** Do not manually edit `PackageVersion` in the csproj or the changelog header — release-please manages both.
## Getting Help
### Resources
- **Documentation**: Read the [README](../README.md) and [API Reference](API_REFERENCE.md)
- **Architecture**: See [ARCHITECTURE](ARCHITECTURE.md) for design details
- **Issues**: Browse existing [GitHub Issues](https://github.com/strvmarv/uptimerobot-dotnet/issues)
- **Discussions**: Join [GitHub Discussions](https://github.com/strvmarv/uptimerobot-dotnet/discussions)
### Asking Questions
- Check existing documentation first
- Search closed issues for similar questions
- Create a new discussion for general questions
- Create an issue for bug reports or feature requests
## Recognition
Contributors will be recognized in:
- GitHub contributors list
- Release notes for significant contributions
- CHANGELOG.md for major features
## License
By contributing, you agree that your contributions will be licensed under the MIT License.
---
Thank you for contributing to the UptimeRobot .NET Client Library! Your contributions help make this library better for everyone. 🎉