Thank you for your interest in contributing to the Energy Management System! This document provides guidelines and instructions for contributing to the project.
- Getting Started
- Development Setup
- Running Tests
- Code Quality
- CI/CD Pipeline
- Pull Request Process
- Code Coverage
- Coding Standards
- Fork the repository
- Clone your fork:
git clone https://github.com/YOUR_USERNAME/energy-management-system.git cd energy-management-system - Add the upstream repository:
git remote add upstream https://github.com/devskill-org/ems.git
- Go 1.25.1 or later
- Make (optional, but recommended)
- golangci-lint (for linting)
# Using Make
make deps
# Or manually
go mod download
go mod tidy# Using Make
make setup
# Or manually
go install golang.org/x/lint/golint@latest
go install golang.org/x/tools/cmd/goimports@latest
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest# Using Make
make test
# Or manually
go test -v -race -coverprofile=coverage.out ./...# Using Make
make test-coverage
# Or manually
go test -v -race -coverprofile=coverage.out ./...
go tool cover -html=coverage.out -o coverage.html# Run tests in a specific package
go test -v ./scheduler/
# Run a specific test
go test -v -run TestSchedulerRun ./scheduler/# Using Make
make fmt
# Or manually
gofmt -s -w .
go mod tidy# Using Make
make lint
# Or manually
golangci-lint run# Using Make
make vet
# Or manually
go vet ./...make checkOur CI/CD pipeline automatically runs on:
- Every push to
main,master, ordevelopbranches - Every pull request targeting these branches
-
Test Job:
- Runs all unit tests
- Enables race detection
- Generates code coverage reports
- Uploads coverage to Codecov (if configured)
- Creates coverage badge
- Archives coverage reports
-
Lint Job:
- Runs golangci-lint with comprehensive checks
- Ensures code quality standards
-
Build Job:
- Compiles the binary
- Verifies successful build
- Archives build artifacts
- Navigate to the "Actions" tab in the GitHub repository
- Click on the workflow run you want to inspect
- Review job results and logs
- Download artifacts if needed
Before pushing, you can simulate CI checks locally:
# Run the same checks as CI
make check test build
# Or step by step
make fmt # Format code
make vet # Run go vet
make lint # Run golangci-lint
make test # Run tests with coverage
make build # Build binary-
Create a feature branch:
git checkout -b feature/your-feature-name
-
Make your changes and commit them:
git add . git commit -m "Description of your changes"
-
Run all checks locally:
make check test -
Update tests if you've added functionality
-
Update documentation if needed
-
Sync with upstream:
git fetch upstream git rebase upstream/main
-
Push your branch:
git push origin feature/your-feature-name
-
Open a Pull Request on GitHub
-
Fill out the PR template with:
- Description of changes
- Related issues
- Testing performed
- Screenshots (if applicable)
-
Wait for CI checks to pass (all three jobs must succeed)
-
Request review from maintainers
- ✅ All CI checks must pass
- ✅ Code coverage should not decrease
- ✅ All tests must pass
- ✅ Code must be formatted (
make fmt) - ✅ No linting errors
- ✅ Documentation updated if needed
- ✅ At least one approving review
We aim to maintain high code coverage (>70%).
- New features should include tests
- Bug fixes should include regression tests
- Critical paths should have >90% coverage
- Coverage should not decrease with new PRs
# Generate and view coverage
make test-coverage
# Open coverage.html in your browser- Coverage is automatically calculated on every PR
- Coverage badge is updated on main branch
- Coverage reports are archived as artifacts
- Follow Effective Go
- Use
gofmtfor formatting - Write clear, descriptive variable and function names
- Add comments for exported functions and types
- Keep functions small and focused
- Handle errors explicitly
energy-management-system/
├── entsoe/ # ENTSO-E API client for electricity pricing
├── meteo/ # Weather/meteorological data integration
├── miners/ # Controllable load management (miners, etc.)
├── mpc/ # Model Predictive Control for optimization
├── scheduler/ # Main scheduling and control logic
├── sigenergy/ # SigEnergy PV/battery system integration
├── sun/ # Solar position calculations
├── utils/ # Utility functions
├── web/ # Web dashboard and API
└── test_data/ # Test fixtures
- Write table-driven tests where appropriate
- Use descriptive test names:
TestFunctionName_Scenario_ExpectedResult - Mock external dependencies
- Test error paths, not just happy paths
- Use
t.Run()for subtests
Example:
func TestScheduler_Run_WithHighPrice_ReducesLoads(t *testing.T) {
// Arrange
scheduler := NewScheduler(...)
// Act
err := scheduler.Run()
// Assert
if err != nil {
t.Errorf("unexpected error: %v", err)
}
}Follow conventional commits format:
type(scope): subject
body
footer
Types:
feat: New featurefix: Bug fixdocs: Documentation changestest: Adding or updating testsrefactor: Code refactoringstyle: Formatting changeschore: Maintenance tasksci: CI/CD changes
Example:
feat(scheduler): add thermal protection for controllable loads
Implements automatic mode switching when fan speeds exceed 70%
to prevent overheating. Recovers to standard mode when temps normalize.
Closes #123
- Open an issue for bugs or feature requests
- Use discussions for questions
- Check existing issues and PRs before creating new ones
By contributing, you agree that your contributions will be licensed under the same license as the project.
Thank you for contributing! 🎉