Skip to main content

Contributing to Runix

Thank you for your interest in contributing to Runix! This guide covers the basics.

Code of Conduct​

Be respectful, constructive, and collaborative.

How to Contribute​

  1. Fork the repository
  2. Create a feature branch from main: git checkout -b feat/my-feature
  3. Make changes following the conventions below
  4. Run tests: make test
  5. Run lint: make lint (if golangci-lint is installed)
  6. Commit with conventional commit messages
  7. Open a pull request with a clear description

Commit Conventions​

Use conventional commit prefixes:

PrefixUsage
feat:New feature
fix:Bug fix
docs:Documentation change
refactor:Code refactoring
test:Adding or updating tests
chore:Build, CI, tooling changes
perf:Performance improvement

Examples:

feat: add --format json to list command
fix: prevent double-close on exited channel
docs: update configuration reference
test: add integration test for rolling reload

Code Conventions​

Logging​

  • Use zerolog structured logging: log.Info().Str("name", name).Msg("message")
  • Return errors; never log-and-return-nil
  • Let the caller decide whether to log

Error Handling​

  • Wrap errors with context: fmt.Errorf("failed to start %q: %w", name, err)
  • Don't suppress errors silently

Initialization​

  • No init() functions — all setup is explicit via New*() constructors
  • Use context.Background() when no context is available (never context.TODO())

Build​

  • CGO_ENABLED=0 everywhere — no C dependencies
  • -trimpath for reproducible builds

Testing​

  • Standard library testing only — no testify or other test frameworks
  • Table-driven tests where applicable
  • Co-locate tests in _test.go files
  • E2E tests go in internal/e2e/

Project Structure​

cmd/runix/ CLI commands (thin cobra wrappers)
internal/ Internal packages (not importable externally)
pkg/types/ Shared types (importable, no internal deps)
configs/ Example configuration
docs/ Documentation
scripts/ Build and install scripts

See Architecture Overview for the full module map.

Where to Add Things​

TaskLocation
CLI commandcmd/runix/<command>.go
Shared typepkg/types/<name>.go
Internal logicinternal/<package>/<name>.go
E2E testinternal/e2e/<name>_test.go

What's Next​