Thank you for your interest in contributing to BuildMark! We welcome contributions from the community and appreciate your help in making this project better.
This project adheres to a Code of Conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior through GitHub.
If you find a bug, please create an issue on GitHub with the following information:
- Description: Clear description of the bug
- Steps to Reproduce: Detailed steps to reproduce the issue
- Expected Behavior: What you expected to happen
- Actual Behavior: What actually happened
- Environment: Operating system, .NET version, BuildMark version
- Logs: Any relevant error messages or logs
We welcome feature suggestions! Please create an issue on GitHub with:
- Feature Description: Clear description of the proposed feature
- Use Case: Why this feature would be useful
- Proposed Solution: Your ideas on how to implement it (optional)
- Alternatives: Any alternative solutions you've considered (optional)
We follow a standard GitHub workflow for contributions:
- Fork the repository
- Clone your fork locally
- Create a branch for your changes (
git checkout -b feature/my-feature) - Make your changes following our coding standards
- Test your changes thoroughly
- Commit your changes with clear commit messages
- Push to your fork
- Create a Pull Request to the main repository
- .NET SDK 8.0, 9.0, or 10.0
- Git
- A code editor (Visual Studio, VS Code, or Rider recommended)
-
Clone the repository:
git clone https://github.com/demaconsulting/BuildMark.git cd BuildMark -
Restore dependencies:
dotnet tool restore dotnet restore
-
Build the project:
dotnet build --configuration Release
-
Run tests:
dotnet test --configuration Release
- Follow the C# Coding Conventions
- Use clear, descriptive names for variables, methods, and classes
- Write XML documentation comments for all public, internal, and private members
- Keep methods focused and single-purpose
- Write tests for new functionality
This project enforces code style through .editorconfig. Key requirements:
- Indentation: 4 spaces for C#, 2 spaces for YAML/JSON/XML
- Line Endings: LF (Unix-style)
- Encoding: UTF-8
- Namespaces: Use file-scoped namespace declarations
- Braces: Required for all control statements
- Naming Conventions:
- Interfaces:
IInterfaceName - Classes/Structs/Enums:
PascalCase - Methods/Properties:
PascalCase - Parameters/Local Variables:
camelCase
- Interfaces:
All members require XML documentation with proper indentation:
/// <summary>
/// Brief description of what this does.
/// </summary>
/// <param name="parameter">Description of the parameter.</param>
/// <returns>Description of the return value.</returns>
public int ExampleMethod(string parameter)
{
// Implementation
}Note the spaces after /// for proper indentation in summary blocks.
We use MSTest v4 for unit and integration tests.
Use the pattern: ClassName_MethodUnderTest_Scenario_ExpectedBehavior
Examples:
Program_Main_NoArguments_ReturnsSuccessContext_Create_WithInvalidFlag_ThrowsArgumentExceptionBuildInformation_ToMarkdown_ValidData_ReturnsMarkdown
- Write tests that are clear and focused
- Use modern MSTest v4 assertions:
Assert.HasCount(expectedCount, collection)Assert.IsEmpty(collection)Assert.DoesNotContain(item, collection)
- Always clean up resources (use
try/finallyfor console redirection)
When testing classes that depend on external services (like GitHub GraphQL API):
- Use virtual methods for dependency creation: Classes expose internal virtual methods
(e.g.,
CreateGraphQLClient) that can be overridden in derived test classes - Mock HTTP responses: Use
MockGitHubGraphQLHttpMessageHandlerto simulate GitHub API responses - Helper methods: Use built-in helper methods for common responses
Example:
// Create a mock HTTP handler using helper methods
using var mockHandler = new MockGitHubGraphQLHttpMessageHandler()
.AddCommitsResponse("commit123")
.AddReleasesResponse("v1.0.0")
.AddEmptyPullRequestsResponse();
// Create HttpClient and inject into GitHubGraphQLClient
using var mockHttpClient = new HttpClient(mockHandler);
using var client = new GitHubGraphQLClient(mockHttpClient);
// Now the client will use mock responses instead of real API calls
var commits = await client.GetCommitsAsync("owner", "repo", "branch");See GitHubRepoConnectorTestabilityTests.cs for complete examples.
# Run all tests
dotnet test --configuration Release
# Run specific test
dotnet test --filter "FullyQualifiedName~YourTestName"
# Run with coverage
dotnet test --collect "XPlat Code Coverage"# Run self-validation tests
dotnet run --project src/DemaConsulting.BuildMark \
--configuration Release --framework net10.0 --no-build -- --validateAll markdown files must follow these rules (enforced by markdownlint):
- Maximum line length: 120 characters
- Use ATX-style headers (
# Header) - Lists must be surrounded by blank lines
- Use reference-style links:
[text][ref]with[ref]: urlat document end - Exception:
README.mduses absolute URLs (it's included in the NuGet package) - Exception:
.github/agents/*.mdfiles use inline links so URLs are visible in agent context
All files are spell-checked using cspell. Add project-specific terms to .cspell.yaml:
words:
- mytermNever add a misspelled word to the .cspell.yaml word list to silence a spell-checking failure.
Doing so defeats the purpose of spell-checking and reduces the quality of the repository.
- If cspell flags a word that is misspelled, fix the spelling in the source file.
- If cspell flags a word that is a genuine technical term (tool name, project identifier, etc.) and is spelled correctly, raise a proposal (e.g. comment in a pull request) explaining why the word should be added. The proposal must be reviewed and approved before the word is added to the list.
Before submitting a pull request, ensure all quality checks pass:
# Build the project
dotnet build --configuration Release
# Run unit tests
dotnet test --configuration ReleaseAll tests must pass with zero warnings.
# After making changes: applies dotnet format, markdown, and YAML fixes silently
pwsh ./fix.ps1
# Before submitting a pull request: all linters must pass
pwsh ./lint.ps1Maintain or improve code coverage. Use the --collect "XPlat Code Coverage" option when running tests.
Write clear, concise commit messages:
- Use present tense ("Add feature" not "Added feature")
- Use imperative mood ("Move cursor to..." not "Moves cursor to...")
- Limit first line to 72 characters
- Reference issues and pull requests when applicable
Examples:
Add support for custom report headersFix crash when results file path is invalidUpdate documentation for --report-depth optionRefactor argument parsing for better testability
- Update Documentation: Update relevant documentation for your changes
- Add Tests: Include tests that cover your changes
- Run Quality Checks: Ensure all linters, tests, and builds pass
- Submit PR: Create a pull request with a clear description
- Code Review: Address feedback from maintainers
- Merge: Once approved, a maintainer will merge your PR
When creating a pull request, include:
- Description: What changes does this PR introduce?
- Motivation: Why are these changes needed?
- Related Issues: Link to any related issues
- Testing: How have you tested these changes?
- Checklist:
- Tests added/updated
- Documentation updated
- All tests pass
- Code follows style guidelines
- No new warnings introduced
BuildMark uses DemaConsulting.ReqStream for requirements traceability:
- All requirements are defined in
requirements.yaml - Each requirement must be linked to at least one test case
- Run
dotnet reqstreamto generate the requirements documentation - Use the
--enforceflag in CI to ensure all requirements are covered
When adding new features:
- Add the requirement to
requirements.yaml - Write tests that validate the requirement
- Link the tests to the requirement in
requirements.yaml
Releases follow this process:
- Create a release issue to track the release
- Update version references as needed
- Create a pull request with the release changes
- Merge the pull request after review
- Create a GitHub release with the new version tag — CI/CD will automatically build and publish the NuGet package
If you need help or have questions:
- GitHub Issues: For bug reports and feature requests — open an issue
- GitHub Discussions: For general questions and discussions — start a discussion
- Pull Request Comments: For questions about specific code changes
- Security Vulnerabilities: Please review the Security Policy before reporting
By contributing to BuildMark, you agree that your contributions will be licensed under the MIT License.
Thank you for contributing to BuildMark!