Thank you for your interest in contributing to the SonarQube Go Client! This guide will help you get started with development, testing, and submitting contributions.
- Code of Conduct
- Getting Started
- Project Structure
- Development Workflow
- Testing
- Makefile Commands
- Pull Request Guidelines
- Reporting Issues
We strive to maintain a welcoming and inclusive community. When contributing, please:
- Be respectful: Treat all contributors with respect and professionalism
- Be constructive: Provide helpful feedback and suggestions
- Be patient: Remember that everyone has different experience levels
- Be collaborative: Work together to improve the project
- Stay on topic: Keep discussions focused on the project
- Follow conventions: Respect the established coding style and patterns
- Go 1.25 or higher - Installation guide
- Docker or Podman (for integration tests) - The Makefile automatically detects which is available
- Git - For version control
- curl - For API specification fetching
-
Fork and clone the repository:
git clone https://github.com/boxboxjason/sonarqube-client-go.git cd sonarqube-client-go -
Install Go dependencies:
go mod download
-
Install development tools (optional, they will be installed automatically when needed):
# Test runner with enhanced output go install gotest.tools/gotestsum@v1.13.0 # Linter go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.8.0 # Integration test framework go install github.com/onsi/ginkgo/v2/ginkgo@v2.28.1
-
Verify your setup:
make lint make test
sonarqube-client-go/
├── sonar/ # SDK source code and unit tests
│ ├── client.go # Main client implementation
│ ├── *_service.go # Service implementations (e.g., projects_service.go)
│ ├── *_service_test.go # Unit tests for services
│ ├── common.go # Shared types and utilities
│ ├── errors.go # Error handling
│ └── ...
├── integration_testing/ # End-to-end integration tests
│ ├── *_test.go # Integration test files
│ ├── suite_test.go # Test suite setup
│ └── helpers/ # Test utilities
│ ├── client.go # Shared test client
│ ├── cleanup.go # Resource cleanup helpers
│ └── wait.go # Wait and retry utilities
├── assets/ # API specifications and resources
├── codequality/ # Generated test reports and coverage
├── .github/ # GitHub workflows and issue templates
├── Makefile # Build and development tasks
├── go.mod # Go module dependencies
└── README.md # Project documentation
This is the main package containing:
- Service files: Each
*_service.gofile implements a SonarQube API service (e.g.,projects_service.go,issues_service.go) - Unit test files: Corresponding
*_service_test.gofiles contain unit tests with mocked API responses - Core client:
client.goprovides the main client structure and HTTP communication - Common types: Shared structs, constants, and utility functions
When adding or modifying SDK functionality:
- Place your code in the appropriate
*_service.gofile - Add corresponding unit tests in
*_service_test.go - Use the
fakesubdirectories for test helpers and mock data
This directory contains integration tests that run against a real SonarQube instance:
- Each
*_test.gofile corresponds to a service being tested - Tests use the Ginkgo testing framework
- Helper utilities are located in
integration_testing/helpers/ - Tests validate actual API communication and responses
-
Create a branch from
main:git checkout -b feat/your-feature-name # or git checkout -b fix/your-bug-fix -
Follow conventional commit format for your commit messages:
feat:- New featurefix:- Bug fixdocs:- Documentation changestest:- Test additions or modificationsrefactor:- Code refactoringchore:- Maintenance tasksperf:- Performance improvementsci:- CI configuration changesbuild:- Build system changes
Example:
git commit -m "feat: add support for project analysis history" -
Write clean, idiomatic Go code:
- Follow the existing project style and naming conventions
- Add godoc comments for all exported functions, types, and methods
- Keep functions focused and reasonably sized
- Use descriptive variable names
-
Document complex logic:
- Add comments explaining the "why" for non-obvious code
- Document any assumptions or edge cases
- Reference related issues or SonarQube API documentation when relevant
All code must pass the project's linter. The configuration is in .golangci.yml and includes:
- Formatters:
gci,gofmt,gofumpt,goimports - Linters:
govet, and many others (see.golangci.ymlfor the full list) - Import ordering: Standard library → External packages → This project
Run the linter before submitting:
make lintUnit tests are located alongside the source code in the sonar/ directory.
Requirements:
- Achieve 80-100% coverage for new or modified code
- Use table-driven tests for functions with multiple scenarios
- Mock API responses - Do not make real HTTP calls in unit tests
- Use common test utilities from
test_helpers_test.goorfake/subdirectories
Writing unit tests:
func TestMyService_MyMethod(t *testing.T) {
tests := []struct {
name string
input MyInput
mockResp string
mockStatus int
expected *MyOutput
expectError bool
}{
{
name: "successful request",
input: MyInput{Field: "value"},
mockResp: `{"result": "success"}`,
mockStatus: 200,
expected: &MyOutput{Result: "success"},
},
// More test cases...
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Test implementation
})
}
}Run unit tests:
make test # Run all unit tests
make coverage # Run tests with coverage reportIntegration tests validate the SDK against a real SonarQube instance.
Requirements:
- Located in
integration_testing/directory - Use Ginkgo/Gomega testing framework
- Clean up resources after tests (use helpers from
integration_testing/helpers/cleanup.go) - Handle eventual consistency with retry logic (use helpers from
integration_testing/helpers/wait.go)
Run integration tests:
make e2e # Starts SonarQube and runs integration testsThe make e2e command automatically:
- Checks if SonarQube is already running
- Starts a SonarQube container if needed (Docker/Podman)
- Waits for SonarQube to be ready
- Runs all integration tests
To teardown the SonarQube instance:
make teardown.sonarThe project includes several Make targets for common development tasks:
| Command | Description |
|---|---|
make test |
Run all unit tests with pretty output and generate JUnit XML report |
make coverage |
Run unit tests with coverage report (generates codequality/coverage.out) |
make e2e |
Set up SonarQube and run end-to-end integration tests |
| Command | Description |
|---|---|
make lint |
Run golangci-lint and generate a checkstyle report for CI |
| Command | Description |
|---|---|
make setup.sonar |
Start a SonarQube instance for testing (Docker/Podman) |
make teardown.sonar |
Stop and remove the SonarQube container |
make api |
Fetch the SonarQube API specification from a running instance |
| Command | Description |
|---|---|
make changelog |
Generate CHANGELOG.md using git-cliff |
make changelog-check |
Verify CHANGELOG.md is up-to-date |
You can customize the Makefile behavior with environment variables:
# Example: Use a different SonarQube instance for integration tests
make e2e endpoint=http://my-sonarqube:9000 username=admin password=mypassAvailable variables:
endpoint- SonarQube API endpoint (default:http://127.0.0.1:9000)username- SonarQube username (default:admin)password- SonarQube password (default:admin)sonarqube_version- Docker image version (default:26.1.0.118079-community)
Ensure your pull request meets these requirements:
- Linting passes:
make lintcompletes without errors - Unit tests pass:
make testcompletes successfully - Integration tests pass:
make e2ecompletes successfully (when applicable) - Code coverage: New code has at least 80% test coverage
- Conventional commits: All commits follow the conventional commit format
- Issue reference: PR description references the issue it addresses (e.g., "Fixes #123")
- Documentation: Code includes godoc comments for exported symbols
- Tests included: New features and bug fixes include appropriate tests
When you create a PR, GitHub will automatically populate the description with our template. Be sure to:
- Describe what your PR does
- Reference the issue it fixes:
Fixes #<issue-number> - Check off all completed items in the checklist
- Describe how you tested your changes
- Automated checks: CI will run linting, unit tests, and integration tests
- Code review: Maintainers will review your code for quality and correctness
- Feedback: Address any comments or requested changes
- Approval: Once approved, a maintainer will merge your PR
- Missing tests: Add unit tests covering your changes
- Documentation gaps: Add godoc comments for exported functions
- Linting errors: Run
make lintand fix reported issues - Test failures: Ensure
make testandmake e2epass locally - Code complexity: Consider breaking large functions into smaller helpers
- Naming conventions: Follow Go naming conventions and match the existing style
If you discover a bug:
- Check existing issues: Search GitHub Issues to see if it's already reported
- Create a new issue: If not found, open a new issue
- Provide details:
- Clear description of the bug
- Steps to reproduce
- Expected vs actual behavior
- Go version and OS (if relevant)
- SonarQube version (if relevant)
- Code sample demonstrating the issue (if possible)
Have an idea for a new feature?
- Check existing issues: See if someone else has requested it
- Open a feature request: Create a new issue with the
enhancementlabel - Describe your use case:
- What problem would this solve?
- How would you like it to work?
- Are there alternatives you've considered?
For general questions or discussions:
- Open a GitHub Discussion (if enabled)
- Create an issue with the
questionlabel - Check the project documentation first
Thank you for contributing to the SonarQube Go Client! Your efforts help make this SDK better for everyone. 🎉