Thank you for your interest in contributing to blocks-localization-net! Your contributions help improve this localization management platform for everyone. Whether you're reporting a bug, suggesting an enhancement, or submitting code changes, we welcome your input.
- Code of Conduct
- How to Contribute
- Development Setup
- Branching Strategy
- Git Guidelines
- Coding Guidelines
- Testing
- Code Review Process
- License
Please read and follow our Code of Conduct. By participating in this project, you agree to abide by its terms.
If you encounter a bug or have a feature request, please open an issue and include:
For Bugs:
- Description: Clear, concise description of the issue
- Steps to Reproduce: Detailed steps to replicate the problem
- Expected Behavior: What should happen
- Actual Behavior: What actually happens
- Environment: .NET SDK version, OS, Docker version (if applicable), local dependency versions
- Logs/Error Output: Relevant error messages or stack traces
- Type: Label as
bug
For Feature Requests:
- Use Case: Clear explanation of the feature and its use case
- Proposed Solution: Your suggested implementation (if any)
- Alternative Approaches: Any alternative approaches considered
- Type: Label as
enhancement
- Fork the Repository: Click the "Fork" button at the top right of the repository page.
- Clone Your Fork: Clone your forked repository to your local machine.
git clone https://github.com/SELISEdigitalplatforms/blocks-localization-net.git cd blocks-localization-net - Create a Branch: Create a new branch for your feature or bugfix (see Branching Strategy).
git checkout -b feature/your-feature-name
- Set up Development Environment: Follow Development Setup.
- Make Changes: Implement your changes following Coding Guidelines.
- Write/Update Tests: Ensure new code has tests (see Testing).
- Run Tests: Verify all tests pass locally.
dotnet test src/blocks-localization-net.sln - Commit Changes: Follow Git Guidelines for commit messages.
- Push to GitHub: Push your changes to your forked repository.
git push origin feature/your-feature-name
- Open a Pull Request: Navigate to the original repository and click "New Pull Request". Link any related issues.
# Verify required tools
dotnet --version
git --version
docker --versionInstall and run the local dependencies required by the project, such as MongoDB, Redis-compatible cache, and RabbitMQ or Azure Service Bus-compatible local infrastructure, before starting the services.
dotnet restore src/blocks-localization-net.slnSet the required environment variables for local development. At minimum, configure database, cache, message broker, and environment selection.
Using Bash:
export BlocksSecret__DatabaseConnectionString="mongodb://localhost:27017"
export BlocksSecret__RootDatabaseName="BlocksRootDb"
export BlocksSecret__CacheConnectionString="redis://localhost:6379"
export BlocksSecret__MessageConnectionString="amqp://guest:guest@localhost:5672"
export ASPNETCORE_ENVIRONMENT="Development"Using PowerShell:
$env:BlocksSecret__DatabaseConnectionString = "mongodb://localhost:27017"
$env:BlocksSecret__RootDatabaseName = "BlocksRootDb"
$env:BlocksSecret__CacheConnectionString = "redis://localhost:6379"
$env:BlocksSecret__MessageConnectionString = "amqp://guest:guest@localhost:5672"
$env:ASPNETCORE_ENVIRONMENT = "Development"For the full list of supported variables, see README.md.
dotnet build src/blocks-localization-net.sln --configuration Releasedotnet test src/XUnitTest/XUnitTest.csproj -v normalTo run the application locally:
# API host
dotnet run --project src/Api/Api.csproj
# Worker host
dotnet run --project src/Worker/Worker.csprojWe follow Git Flow for branching:
main: Production-ready, stable releases.dev: Active development branch (default for PRs).feature/*: New features branching fromdev(e.g.,feature/schema-caching).bugfix/*: Bug fixes branching fromdev(e.g.,bugfix/null-tenant-context).hotfix/*: Emergency fixes branching frommainfor critical production issues.docs/*: Documentation updates (e.g.,docs/api-reference).
All PRs should target the dev branch unless otherwise agreed.
We follow Conventional Commits specification for standardized commit messages.
<type>(<scope>): <subject>
<body>
<footer>
feat: A new featurefix: A bug fixdocs: Documentation only changesstyle: Changes that don't affect code logic (formatting, whitespace, semicolons)refactor: Code change that refactors without feature/fix (no functional changes)perf: Performance improvementstest: Adding/updating testschore: Build process, dependency updates, tooling changes
Indicate the affected component or module:
api: API controllers and HTTP endpoint behaviordomainservice: Core business logic, validators, repositories, and shared modelsworker: Background consumers and asynchronous workflowskey: Key, timeline, translation, and UILM flowslanguage: Language management and defaultsmodule: Module management behaviorglossary: Glossary CRUD and suggestion logicconfig: Configuration and service registration updatestest: Test coverage and test infrastructure
- Use imperative mood ("add feature", not "added feature")
- Do not capitalize first letter
- Do not end with a period
- Maximum 50 characters
- Be specific and descriptive
- Use imperative mood
- Explain what and why, not how
- Wrap at 72 characters
- Separate each logical change with a blank line
Reference related issues or breaking changes:
Fixes #123
Closes #456
BREAKING CHANGE: description of breaking change
feat(api): add schema aggregation endpoint
- Add endpoint that returns schemas with access summaries
- Include pagination and filter support
- Update API documentation examples
Closes #42
fix(worker): handle null tenant id during import
The schema import workflow could throw when tenant context was missing.
Add validation and return a safer error path before processing starts.
Fixes #189
docs: update local setup instructions
Update environment variable examples and worker startup steps.
- C# Conventions: Follow Microsoft's C# coding conventions.
- Line Length: Maximum 120 characters (project convention).
- Imports:
- Organize imports in three groups: framework, third-party, local (separated by blank lines).
- Use explicit, clear namespaces.
- Avoid circular dependencies between projects.
- Async/Await: Use
async/awaitconsistently for asynchronous methods. Ensure proper exception handling in async flows. - Nullable Reference Types: Respect nullable reference types and model nullability explicitly.
public async Task<SchemaDefinition?> GetSchemaAsync(string id) { return await repository.GetByIdAsync(id); }
When adding new features, follow the existing structure:
src/
├── Api/
│ ├── Controllers/
│ │ ├── AssistantController.cs
│ │ ├── GlossaryController.cs
│ │ ├── KeyController.cs
│ │ ├── LanguageController.cs
│ │ └── ModuleController.cs
│ └── Program.cs
├── DomainService/
│ ├── Services/
│ ├── Repositories/
│ ├── Shared/
│ └── Validation/
├── Worker/
│ ├── Consumers/
│ └── Program.cs
└── XUnitTest/
├── Api/
├── Repositories/
├── Services/
├── Validation/
└── Worker/
For new features:
- Add contracts, models, and services in
src/DomainService/. - Add or extend controllers in
src/Api/Controllers/when exposing HTTP endpoints. - Add worker consumers in
src/Worker/Consumers/if asynchronous processing is required. - Add matching tests in
src/XUnitTest/mirroring the source structure.
- Endpoint Naming: Use resource-oriented HTTP endpoints and follow the existing REST patterns.
- Response Models: Use clear request/response contracts and keep validation close to the domain layer.
- Status Codes:
200 OKfor successful GET/PUT operations201 Createdfor successful POST operations when creating resources204 No Contentfor successful DELETE operations where no payload is returned400 Bad Requestfor validation errors404 Not Foundfor missing resources500 Internal Server Errorfor server errors
- Error Responses: Return structured error responses consistent with current controller behavior.
- Documentation: Add XML comments and keep Swagger/OpenAPI-visible endpoints understandable.
/// <summary> /// Creates or updates a localization module. /// </summary> [HttpPost("/Module/Save")] public async Task<IActionResult> Save(SaveModuleRequest request) { // Implementation }
- Use the .NET logging abstractions (
ILogger<T>) instead of console prints. - Use appropriate log levels:
LogDebug,LogInformation,LogWarning,LogError,LogCritical.logger.LogInformation("Localization key saved: {KeyName}", keyName); logger.LogError(exception, "Failed to process translation job for project {ProjectKey}", projectKey);
- Always respect project and tenant context when processing requests.
- Avoid hardcoding tenant IDs, project keys, URLs, or secret values.
- Keep localization, translation, and import/export operations aligned with the current request context and configured providers.
- Use specific exception types where possible.
- Provide meaningful error messages.
- Log exceptions with relevant context.
if (string.IsNullOrWhiteSpace(request.ProjectKey)) { return BadRequest("Project key is required."); }
Tests are organized in src/XUnitTest/ to mirror source structure:
src/XUnitTest/
├── Api/
├── Repositories/
├── Services/
├── Shared/
├── Validation/
└── Worker/
- Framework: Use
xUnitwithMoqfor mocking andFluentAssertionsfor expressive assertions. - File Naming: Test files should generally be named after the target type with a
Testssuffix. - Method Naming: Test methods should clearly describe the expected behavior.
- Shared Helpers: Use shared test utilities where appropriate for reusable fixtures and helpers.
- Mocking: Mock external dependencies and isolate domain behavior.
Example:
[Fact]
public async Task Save_WithValidRequest_ReturnsSuccess()
{
var request = new SaveModuleRequest { Name = "catalog" };
var result = await service.Save(request);
result.Should().NotBeNull();
}Run all tests:
dotnet test src/blocks-localization-net.slnRun specific test project:
dotnet test src/XUnitTest/XUnitTest.csprojRun with coverage:
dotnet test src/XUnitTest/XUnitTest.csproj --collect:"XPlat Code Coverage"- New features must include tests.
- Bug fixes should include regression tests.
- Aim for >80% code coverage on core service layers where practical.
- All tests must pass before PR submission.
All PRs undergo review to maintain quality:
-
PR Submission:
- Ensure PR is focused on a single feature/fix.
- Link related issues.
- Provide clear description of changes.
- Verify all tests pass locally.
-
Automated Checks:
- CI/CD will run tests and linting.
- Code must pass all checks.
-
Peer Review:
- At least one maintainer must review and approve.
- Address review comments promptly.
- Request re-review after making changes.
-
Merge Process:
- Once approved and all checks pass, the PR is merged into
dev. - Use "Squash and merge" for feature PRs to keep history clean.
- Once approved and all checks pass, the PR is merged into
By contributing, you agree that your contributions will be licensed under the MIT License.