Thank you for your interest in contributing to GoLangGraph! This document provides guidelines and information for contributors.
- Code of Conduct
- Getting Started
- Development Setup
- Making Changes
- Testing
- Code Style
- Submitting Changes
- Release Process
- Community
This project adheres to a code of conduct that we expect all contributors to follow. Please be respectful, inclusive, and constructive in all interactions.
- Be respectful: Treat everyone with respect and kindness
- Be inclusive: Welcome people of all backgrounds and experience levels
- Be constructive: Focus on what is best for the community
- Be patient: Help others learn and grow
- Be collaborative: Work together to achieve common goals
- Go 1.21 or later
- Git
- Docker and Docker Compose (for integration tests)
- Make (for build automation)
-
Fork the repository on GitHub
-
Clone your fork locally:
git clone https://github.com/YOUR_USERNAME/GoLangGraph.git cd GoLangGraph -
Add upstream remote:
git remote add upstream https://github.com/UnicoLab/GoLangGraph.git
-
Install dependencies:
go mod tidy
-
Verify setup:
make test
# Start development services (PostgreSQL, Redis)
make dev-up
# Run tests
make test
# Run linting
make lint
# Format code
make fmt
# Build the project
make build
# Stop development services
make dev-downCreate a .env file for local development:
# Database Configuration
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_DB=golanggraph_dev
POSTGRES_USER=postgres
POSTGRES_PASSWORD=password
# Redis Configuration
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=
# LLM Provider Configuration
OPENAI_API_KEY=your_openai_api_key
GEMINI_API_KEY=your_gemini_api_key
OLLAMA_BASE_URL=http://localhost:11434├── pkg/ # Core packages
│ ├── core/ # Graph execution engine
│ ├── agent/ # AI agent framework
│ ├── llm/ # LLM provider integrations
│ ├── persistence/ # Database and storage
│ ├── tools/ # Built-in tools
│ ├── server/ # HTTP server
│ └── debug/ # Debugging utilities
├── cmd/ # Command-line applications
├── examples/ # Example applications
├── docs/ # Documentation
├── scripts/ # Build and deployment scripts
├── .github/ # GitHub workflows
└── Makefile # Build automation
-
Create a feature branch from
main:git checkout main git pull upstream main git checkout -b feature/your-feature-name
-
Make your changes following the guidelines below
-
Commit your changes with clear messages:
git add . git commit -m "feat: add new feature description"
-
Push to your fork:
git push origin feature/your-feature-name
We follow the Conventional Commits specification:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
Types:
feat: New featurefix: Bug fixdocs: Documentation changesstyle: Code style changes (formatting, etc.)refactor: Code refactoringtest: Adding or updating testschore: Maintenance tasksperf: Performance improvementsci: CI/CD changes
Examples:
feat(core): add conditional edge support
fix(persistence): resolve connection pool leak
docs(readme): update installation instructions
test(agent): add comprehensive agent tests
- Fix existing functionality that isn't working correctly
- Include reproduction steps in the issue
- Add tests to prevent regression
- Add new functionality to the project
- Discuss in an issue before implementing large features
- Include documentation and tests
- Improve existing documentation
- Add new documentation for features
- Fix typos and improve clarity
- Add missing tests
- Improve test coverage
- Add integration tests
- Improve build process
- Update CI/CD pipelines
- Enhance development tools
# Run all tests
make test
# Run specific package tests
go test ./pkg/core -v
go test ./pkg/agent -v
go test ./pkg/persistence -v
# Run tests with coverage
make test-coverage
# Run integration tests (requires running services)
make test-integration
# Run benchmarks
make benchmark
# Run race detection
make test-race- Test individual functions and methods
- Use table-driven tests for multiple scenarios
- Mock external dependencies
- Aim for high test coverage
func TestFunction(t *testing.T) {
tests := []struct {
name string
input string
expected string
wantErr bool
}{
{
name: "valid input",
input: "hello",
expected: "HELLO",
wantErr: false,
},
// ... more test cases
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := Function(tt.input)
if (err != nil) != tt.wantErr {
t.Errorf("Function() error = %v, wantErr %v", err, tt.wantErr)
return
}
if result != tt.expected {
t.Errorf("Function() = %v, expected %v", result, tt.expected)
}
})
}
}- Test component interactions
- Use real databases when possible
- Clean up resources after tests
//go:build integration
func TestDatabaseIntegration(t *testing.T) {
// Setup test database
db := setupTestDB(t)
defer db.Close()
// Test integration
// ...
}- Measure performance of critical paths
- Use
testing.Bfor benchmarks
func BenchmarkFunction(b *testing.B) {
for i := 0; i < b.N; i++ {
Function("test input")
}
}We follow standard Go conventions with some additions:
- Use
gofmtfor formatting - Use
goimportsfor import organization - Run
make fmtbefore committing
- Use descriptive names for variables and functions
- Follow Go naming conventions (PascalCase for exported, camelCase for unexported)
- Use meaningful package names
- Always handle errors explicitly
- Use wrapped errors for context:
fmt.Errorf("operation failed: %w", err) - Return errors as the last return value
// Good
func ProcessData(data string) (string, error) {
if data == "" {
return "", fmt.Errorf("data cannot be empty")
}
result, err := transform(data)
if err != nil {
return "", fmt.Errorf("failed to transform data: %w", err)
}
return result, nil
}- Add godoc comments for all exported functions, types, and packages
- Use complete sentences in comments
- Include examples for complex functions
// ProcessData transforms the input data according to the specified rules.
// It returns the transformed data or an error if the transformation fails.
//
// Example:
// result, err := ProcessData("hello world")
// if err != nil {
// log.Fatal(err)
// }
// fmt.Println(result) // Output: HELLO WORLD
func ProcessData(data string) (string, error) {
// ...
}We use golangci-lint with a comprehensive configuration:
# Run linting
make lint
# Auto-fix issues where possible
make lint-fix- Keep packages focused and cohesive
- Avoid circular dependencies
- Use internal packages for implementation details
- Group related functionality in the same file
- Keep files reasonably sized (< 500 lines)
- Use meaningful file names
- Keep interfaces small and focused
- Define interfaces where they're used, not where they're implemented
- Use composition over inheritance
-
Ensure your branch is up to date:
git checkout main git pull upstream main git checkout feature/your-feature-name git rebase main
-
Run the full test suite:
make test make lint -
Create a pull request with:
- Clear title and description
- Reference any related issues
- Include screenshots for UI changes
- List any breaking changes
## Description
Brief description of changes
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
## Testing
- [ ] Unit tests pass
- [ ] Integration tests pass
- [ ] Manual testing completed
## Checklist
- [ ] Code follows style guidelines
- [ ] Self-review completed
- [ ] Documentation updated
- [ ] Tests added/updated- Automated checks must pass (CI/CD, linting, tests)
- Code review by maintainers
- Address feedback and update PR
- Final approval and merge
- All CI checks pass
- Code review approval from maintainer
- No merge conflicts
- Documentation updated if needed
- Tests added for new functionality
We follow Semantic Versioning:
MAJOR.MINOR.PATCH- Major: Breaking changes
- Minor: New features (backward compatible)
- Patch: Bug fixes (backward compatible)
-
Prepare release:
- Update version numbers
- Update CHANGELOG.md
- Create release branch
-
Test release:
- Run full test suite
- Test examples and documentation
- Verify builds on all platforms
-
Create release:
- Tag the release
- Build and publish artifacts
- Update documentation
-
Announce release:
- GitHub release notes
- Community announcements
- GitHub Issues: Bug reports and feature requests
- GitHub Discussions: General questions and discussions
- Pull Requests: Code contributions and reviews
- Check existing issues and documentation
- Search previous discussions
- Create a new issue with detailed information
- Be patient and respectful when asking for help
When reporting bugs, please include:
-
Environment information:
- Go version
- Operating system
- GoLangGraph version
-
Reproduction steps:
- Minimal code example
- Expected behavior
- Actual behavior
-
Additional context:
- Error messages
- Logs
- Screenshots if applicable
When requesting features:
- Describe the problem you're trying to solve
- Explain the proposed solution
- Consider alternatives you've thought of
- Provide use cases and examples
We appreciate all contributions! Contributors will be:
- Listed in the project's contributors
- Mentioned in release notes for significant contributions
- Invited to join the maintainer team for sustained contributions
If you have any questions about contributing, please:
- Check this document first
- Search existing issues and discussions
- Create a new discussion or issue
- Reach out to maintainers
Thank you for contributing to GoLangGraph! 🚀