Thank you for your interest in contributing to Alexander Storage! This document provides guidelines and information for contributors.
- Code of Conduct
- Getting Started
- Development Setup
- Making Changes
- Coding Standards
- Testing
- Submitting Changes
- Issue Guidelines
This project adheres to a Code of Conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior to the project maintainers.
Before you begin, ensure you have the following installed:
- Go 1.21+: Download Go
- PostgreSQL 14+: Download PostgreSQL
- Redis 7+: Download Redis (optional)
- Docker and Docker Compose: For running the full stack locally
- Make: For build automation
- golangci-lint: For code linting
- Fork the repository on GitHub
- Clone your fork locally:
git clone https://github.com/YOUR_USERNAME/alexander-storage.git
cd alexander-storage- Add the upstream repository:
git remote add upstream https://github.com/prn-tf/alexander-storage.git- Keep your fork synchronized:
git fetch upstream
git checkout main
git merge upstream/maingo mod downloadUse Docker Compose to start PostgreSQL and Redis:
docker-compose -f configs/docker-compose.yaml up -d postgres redisCopy the example configuration:
cp configs/config.yaml.example configs/config.yamlSet required environment variables:
export ALEXANDER_AUTH_ENCRYPTION_KEY=$(openssl rand -hex 32)
export ALEXANDER_DATABASE_PASSWORD=yourpasswordgo run cmd/alexander-migrate/main.go upmake build
./bin/alexander-serverUse descriptive branch names:
feature/add-bucket-versioningfix/signature-verification-bugdocs/update-readmerefactor/auth-middleware
Follow the conventional commit format:
<type>(<scope>): <description>
[optional body]
[optional footer]
Types:
feat: New featurefix: Bug fixdocs: Documentation changesstyle: Code style changes (formatting, missing semicolons, etc.)refactor: Code refactoringtest: Adding or updating testschore: Maintenance tasks
Examples:
feat(auth): add presigned URL generation
Implement presigned URL generation for GET, PUT, and DELETE operations.
URLs are valid for a configurable duration (default 15 minutes).
Closes #42
fix(storage): handle concurrent blob deletion
Add distributed locking to prevent race conditions when
decrementing blob reference counts.
We follow the standard Go style guidelines:
- Use
gofmtfor formatting - Follow Effective Go
- Follow Go Code Review Comments
-
Error Handling
- Always wrap errors with context:
fmt.Errorf("failed to do X: %w", err) - Define domain-specific errors in
internal/domain/errors.go - Use sentinel errors for expected conditions
- Always wrap errors with context:
-
Logging
- Use structured logging with zerolog
- Include relevant context fields
- Use appropriate log levels:
Debug: Detailed debugging informationInfo: General operational informationWarn: Warning conditionsError: Error conditions
-
Comments
- All exported types, functions, and methods must have doc comments
- Use complete sentences starting with the item name
- Include usage examples for complex APIs
-
Package Structure
- Keep packages focused and cohesive
- Avoid circular dependencies
- Use internal packages for private code
internal/
domain/ # Core business entities (no external dependencies)
repository/ # Data access interfaces and implementations
service/ # Business logic layer
auth/ # Authentication and authorization
storage/ # Blob storage abstraction
config/ # Configuration management
pkg/ # Shared utilities (crypto, etc.)
Run the linter before submitting:
make lintWe use golangci-lint with the configuration in .golangci.yml.
# Run all tests
make test
# Run tests with coverage
make test-coverage
# Run specific package tests
go test ./internal/auth/...
# Run with verbose output
go test -v ./...-
Unit Tests
- Place tests in the same package as the code
- Name test files
*_test.go - Use table-driven tests when appropriate
-
Integration Tests
- Use build tags for integration tests:
//go:build integration - Require external dependencies (database, Redis)
- Clean up test data after each test
- Use build tags for integration tests:
-
Test Coverage
- Aim for at least 70% coverage for new code
- Critical paths (auth, storage) should have higher coverage
Example Test:
func TestEncryptor_EncryptDecrypt(t *testing.T) {
tests := []struct {
name string
plaintext string
}{
{"empty string", ""},
{"short string", "hello"},
{"long string", strings.Repeat("x", 1000)},
}
key := make([]byte, 32)
rand.Read(key)
enc, _ := crypto.NewEncryptor(key)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
encrypted, err := enc.EncryptString(tt.plaintext)
require.NoError(t, err)
decrypted, err := enc.DecryptString(encrypted)
require.NoError(t, err)
assert.Equal(t, tt.plaintext, decrypted)
})
}
}- Update your fork with the latest upstream changes
- Create a feature branch from
main - Make your changes following the coding standards
- Write or update tests for your changes
- Run the full test suite and linter
- Push to your fork and create a pull request
Before submitting, ensure:
- Code follows the project's coding standards
- All tests pass (
make test) - Linter passes (
make lint) - New code has adequate test coverage
- Documentation is updated if needed
- Commit messages follow the conventional format
- CHANGELOG.md is updated for notable changes
- A maintainer will review your PR within a few days
- Address any feedback or requested changes
- Once approved, a maintainer will merge your PR
When reporting bugs, include:
- Summary: A clear and concise description
- Steps to Reproduce: Detailed steps to reproduce the issue
- Expected Behavior: What you expected to happen
- Actual Behavior: What actually happened
- Environment: OS, Go version, PostgreSQL version, etc.
- Logs: Relevant log output (redact sensitive information)
When requesting features, include:
- Problem Statement: What problem does this solve?
- Proposed Solution: Your suggested approach
- Alternatives Considered: Other solutions you've thought about
- Use Cases: How would this feature be used?
bug: Something isn't workingenhancement: New feature or requestdocumentation: Documentation improvementsgood first issue: Good for newcomershelp wanted: Extra attention is neededquestion: Further information is requested
Contributors are recognized in:
- The project's README.md
- Release notes for significant contributions
- The GitHub contributors page
If you have questions, feel free to:
- Open a Discussion
- Ask in an issue with the
questionlabel
Thank you for contributing to Alexander Storage!