Thank you for your interest in contributing to this project. This document outlines the guidelines and best practices for contributing.
- Code of Conduct
- Getting Started
- Development Workflow
- Coding Standards
- Commit Guidelines
- Pull Request Process
- Testing
By participating in this project, you agree to maintain a respectful and inclusive environment. Be professional, constructive, and considerate in all interactions.
Ensure you have the following installed:
- Go 1.21+
- Node.js 20+
- Docker & Docker Compose
- Terraform 1.6+
- Make
-
Clone the repository
git clone git@github.com:canerdogan/upstash.git cd upstash -
Start the development environment
make dev-up
-
Verify everything is running
docker-compose ps
Use the following prefixes for branch names:
feature/- New features (e.g.,feature/add-billing-api)fix/- Bug fixes (e.g.,fix/auth-token-expiry)refactor/- Code refactoring (e.g.,refactor/database-layer)docs/- Documentation updates (e.g.,docs/api-endpoints)chore/- Maintenance tasks (e.g.,chore/update-dependencies)
-
Create a new branch from
maingit checkout main git pull origin main git checkout -b feature/your-feature-name
-
Make your changes
-
Write/update tests
-
Run tests locally
make test -
Commit your changes (see Commit Guidelines)
-
Push and create a Pull Request
- Follow Effective Go guidelines
- Use
gofmtfor formatting - Run
golangci-lintbefore committingmake api-lint
- Write meaningful comments for exported functions
- Keep functions small and focused
- Handle errors explicitly - don't ignore them
// CreateDatabase provisions a new Redis database for the user.
// It returns the database details or an error if provisioning fails.
func (s *DatabaseService) CreateDatabase(ctx context.Context, req CreateDatabaseRequest) (*Database, error) {
// Validate request
if err := req.Validate(); err != nil {
return nil, fmt.Errorf("invalid request: %w", err)
}
// Create database
db, err := s.repo.Create(ctx, req)
if err != nil {
return nil, fmt.Errorf("failed to create database: %w", err)
}
return db, nil
}- Use TypeScript for all new code
- Follow the existing code style
- Use functional components with hooks
- Keep components small and reusable
- Use proper typing - avoid
any
interface DatabaseCardProps {
database: Database;
onDelete: (id: string) => void;
}
export const DatabaseCard: React.FC<DatabaseCardProps> = ({ database, onDelete }) => {
const handleDelete = () => {
if (confirm('Are you sure?')) {
onDelete(database.id);
}
};
return (
<div className="p-4 border rounded-lg">
<h3 className="font-bold">{database.name}</h3>
<button onClick={handleDelete}>Delete</button>
</div>
);
};- Use consistent formatting (
terraform fmt) - Organize resources logically
- Use variables for configurable values
- Add descriptions to variables and outputs
- Use modules for reusable components
We follow the Conventional Commits specification.
<type>(<scope>): <description>
[optional body]
[optional footer(s)]
feat- New featurefix- Bug fixdocs- Documentation changesstyle- Code style changes (formatting, etc.)refactor- Code refactoringtest- Adding or updating testschore- Maintenance tasks
feat(api): add database deletion endpoint
fix(auth): resolve JWT token refresh race condition
docs(readme): update installation instructions
refactor(dashboard): extract common form components
- Use imperative mood ("add" not "added")
- Don't capitalize the first letter
- No period at the end of the subject line
- Keep the subject line under 72 characters
- Reference issues in the footer when applicable
- Tests pass locally (
make test) - Code is linted (
make api-lint) - Documentation is updated if needed
- Commit messages follow guidelines
- Branch is up to date with
main
## Summary
Brief description of the changes.
## Changes
- Change 1
- Change 2
## Testing
How to test these changes.
## Related Issues
Closes #123- All PRs require at least one approval
- All CI checks must pass
- Resolve all review comments before merging
- Squash commits when merging if there are many small commits
# Run all tests
make api-test
# Run tests with coverage
make api-test-coverage
# Run specific test
cd services/api && go test -v ./internal/handlers -run TestCreateDatabase# Run all tests
make dashboard-test
# Run tests in watch mode
cd services/dashboard && npm run test:watch- Test one thing per test
- Use descriptive test names
- Include both positive and negative cases
- Mock external dependencies
- Keep tests fast and isolated
func TestDatabaseService_Create(t *testing.T) {
t.Run("creates database successfully", func(t *testing.T) {
// Arrange
mockRepo := NewMockRepository()
service := NewDatabaseService(mockRepo)
// Act
db, err := service.Create(context.Background(), validRequest)
// Assert
assert.NoError(t, err)
assert.NotEmpty(t, db.ID)
})
t.Run("returns error for invalid request", func(t *testing.T) {
// ...
})
}If you have questions about contributing, please reach out to the development team.