Contributing Code - joinruach/JoinRuach GitHub Wiki

Contributing Code


Overview

Thank you for contributing to Ruach Studios. This guide will help you submit high-quality code that aligns with our standards and workflow.

Key Principles:

  • Quality over speed — Take time to do it right
  • Test before you ship — No untested code in production
  • Document as you go — Future you will thank present you
  • Ask questions early — Clarify before you code

Before You Start

1. Pick an Issue

Browse open issues and find one that matches your skill level:

  • Good First Issue — Perfect for newcomers
  • Help Wanted — Ready for contribution
  • Bug — Something broken that needs fixing
  • Enhancement — New feature or improvement

Comment on the issue to let others know you're working on it.


2. Understand the Task

Read the issue carefully and ask questions if anything is unclear. Better to clarify now than to rework later.


3. Set Up Your Environment

Follow the Development Setup guide if you haven't already.


Development Workflow

Step 1: Create a Branch

Always create a new branch for your work:

# For new features
git checkout -b feat/feature-name

# For bug fixes
git checkout -b fix/bug-description

# For documentation
git checkout -b docs/update-readme

Branch Naming Convention:

  • feat/ — New feature
  • fix/ — Bug fix
  • docs/ — Documentation
  • refactor/ — Code refactoring
  • test/ — Adding tests
  • chore/ — Maintenance tasks

Step 2: Write Code

Code Style

We use ESLint and Prettier to enforce consistent code style.

# Check for linting errors
pnpm lint

# Auto-fix linting errors
pnpm lint:fix

# Format code
pnpm format

TypeScript Guidelines

  • Always use types — Avoid any unless absolutely necessary
  • Export types — Make types reusable
  • Use Zod for validation — Runtime type safety

Example:

import { z } from 'zod';

// Define schema
const UserSchema = z.object({
  email: z.string().email(),
  name: z.string().min(1),
  age: z.number().min(18).optional(),
});

// Infer type
type User = z.infer<typeof UserSchema>;

// Validate data
const user = UserSchema.parse(data);

React Guidelines

  • Use functional components — No class components
  • Prefer server components — Use client components only when necessary
  • Keep components small — Single Responsibility Principle
  • Use TypeScript — Always type props

Example:

// Server Component (default)
export default function ServerComponent() {
  return <div>Server-rendered content</div>;
}

// Client Component (when interactivity is needed)
'use client';
import { useState } from 'react';

export default function ClientComponent() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(count + 1)}>{count}</button>;
}

Step 3: Write Tests

Every feature or bug fix should include tests.

Unit Tests (Vitest)

import { describe, it, expect } from 'vitest';
import { validateEmail } from './utils';

describe('validateEmail', () => {
  it('should return true for valid email', () => {
    expect(validateEmail('[email protected]')).toBe(true);
  });

  it('should return false for invalid email', () => {
    expect(validateEmail('not-an-email')).toBe(false);
  });
});

Component Tests (React Testing Library)

import { render, screen } from '@testing-library/react';
import { expect, it } from 'vitest';
import Button from './Button';

it('renders button with text', () => {
  render(<Button>Click me</Button>);
  expect(screen.getByRole('button')).toHaveTextContent('Click me');
});

Run Tests

# Run all tests
pnpm test

# Run tests in watch mode
pnpm test:watch

# Run tests with coverage
pnpm test:coverage

Step 4: Document Your Code

Inline Comments

// Good: Explains WHY, not WHAT
// Using debounce to prevent excessive API calls during rapid input
const debouncedSearch = debounce(search, 300);

// Avoid: States the obvious
// Set count to 0
const count = 0;

JSDoc (for complex functions)

/**
 * Fetches user data from the API
 * @param userId - The unique identifier for the user
 * @returns Promise containing user data
 * @throws {Error} If user is not found
 */
async function fetchUser(userId: string): Promise<User> {
  // ...
}

Update README (if needed)

If your changes affect setup, usage, or configuration, update the README.


Step 5: Commit Your Changes

Commit Message Format

Follow Conventional Commits:

<type>(<scope>): <short description>

<optional body>

<optional footer>

Types:

  • feat: — New feature
  • fix: — Bug fix
  • docs: — Documentation changes
  • style: — Code style changes (formatting, etc.)
  • refactor: — Code refactoring
  • test: — Adding or updating tests
  • chore: — Maintenance tasks

Examples:

git commit -m "feat(auth): add Google OAuth integration"
git commit -m "fix(api): resolve null pointer exception in user endpoint"
git commit -m "docs(readme): update installation instructions"

Commit Often

Make small, atomic commits. Each commit should represent a single logical change.

# Stage specific files
git add src/components/Button.tsx

# Commit
git commit -m "feat(ui): add Button component"

Step 6: Push Your Branch

# Push to GitHub
git push origin feat/your-feature-name

Step 7: Create a Pull Request

  1. Go to GitHub
  2. Click "New Pull Request"
  3. Select your branch
  4. Fill out the PR template:
## Description
Brief description of what this PR does.

## Related Issue
Closes #123

## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Documentation update
- [ ] Code refactoring

## Checklist
- [ ] I have tested my changes locally
- [ ] I have added tests for my changes
- [ ] I have updated documentation (if needed)
- [ ] My code follows the project's style guidelines
- [ ] All tests pass
  1. Request a review from a maintainer

Pull Request Review Process

What Reviewers Look For

  • Code quality — Clean, readable, maintainable
  • Tests — Adequate test coverage
  • Documentation — Clear comments and updated docs
  • Performance — No unnecessary rerenders or inefficiencies
  • Security — No vulnerabilities introduced
  • Alignment — Matches project vision and standards

Responding to Feedback

  • Be open — Feedback is a gift
  • Ask questions — Clarify if something is unclear
  • Make changes — Address all comments
  • Push updates — Your PR will automatically update
# Make requested changes
git add .
git commit -m "refactor: address PR feedback"
git push

After Approval

Once approved, a maintainer will merge your PR. Your code is now in production! 🎉


Code Review Guidelines

For Contributors

  • Review your own PR first — Catch obvious issues before submitting
  • Keep PRs small — Easier to review (under 400 lines of code)
  • Provide context — Explain your decisions in the description
  • Be patient — Reviews take time

For Reviewers

  • Be kind — Everyone is learning
  • Be specific — Point to exact lines and explain why
  • Approve quickly — Don't block good work
  • Suggest, don't demand — Unless it's a critical issue

Common Pitfalls

1. Not Testing Locally

Always run tests before pushing:

pnpm test
pnpm lint
pnpm type-check

2. Committing Environment Variables

Never commit .env.local or sensitive data. Add to .gitignore if needed.


3. Large, Monolithic PRs

Break large changes into smaller, logical PRs. Easier to review and safer to merge.


4. Ignoring Linting Errors

Fix linting errors before pushing. Use:

pnpm lint:fix

5. Not Syncing with Main

Keep your branch up to date with main:

git fetch origin
git rebase origin/main

Advanced Topics

Rebasing

If your branch is behind main, rebase instead of merging:

git fetch origin
git rebase origin/main

If conflicts arise, resolve them and continue:

git add .
git rebase --continue

Squashing Commits

Before merging, you may be asked to squash commits:

# Squash last 3 commits into 1
git rebase -i HEAD~3

Mark all but the first commit as squash, save, and edit the commit message.


Cherry-Picking

To apply a specific commit from another branch:

git cherry-pick <commit-hash>

Getting Help

Stuck on Something?

Found a Bug?

Open an issue on GitHub.


Recognition

Every merged PR earns you:

  • Credit in the Contributors section
  • GitHub history showing your impact
  • Community appreciation — we celebrate wins together

"Whatever you do, work heartily, as for the Lord and not for men." — Colossians 3:23

⚠️ **GitHub.com Fallback** ⚠️