Skip to content

Contributing

This guide covers contribution guidelines, Git workflow, and commit message conventions.


Git Workflow

Branching Strategy

We use a three-tier branching model based on the urgency and type of change:

Branch Type Target Branch Purpose
Feature branches next/minor New features and enhancements
Bug fix branches next/bugs Non-critical bug fixes
Critical fix branches master Critical bugs requiring immediate deployment

Branch naming convention:

  • Features: feature/TICKET_ID_task_subject
  • Bug fixes: fix/TICKET_ID_task_subject

Example branch names:

feature/666352_easy_ai_global_deactivation  → merge to next/minor
fix/665117_end_date_expiration              → merge to next/bugs
fix/670999_critical_security_patch          → merge to master

Creating a Feature Branch

# Create and switch to a new feature branch
git checkout -b feature/12345_add_dark_mode

# Push to remote and set upstream
git push -u origin feature/12345_add_dark_mode

Choosing the Right Target Branch

Use next/minor when:

  • Adding new features
  • Implementing enhancements
  • Making non-critical improvements
  • Refactoring code

Use next/bugs when:

  • Fixing bugs that can wait for the next release
  • Resolving non-critical issues
  • Making minor corrections

Use master when:

  • Fixing critical production bugs
  • Addressing security vulnerabilities
  • Resolving issues that require immediate deployment
  • Always coordinate with the team before targeting master

Commit Message Convention

We use a variant of Conventional Commits with ticket references at the end of the commit message.

Format

<type>(<optional-scope>): <description> [optional: (refs #1234 | refs #issue-1234 | refs #pbi-1234)]

Commit Types

Type Description
feat New feature
fix Bug fix
docs Documentation changes
style Code style changes (formatting, whitespace)
refactor Code refactoring without behavior changes
test Adding or updating tests
chore Build process, dependencies, or tooling changes
perf Performance improvements

Scope (Optional)

The scope provides additional context about which part of the codebase is affected. You can use simple or more granular scopes with dot notation:

Simple scopes:

feat(easy_ai): add new AI provider
style(design_system): update button spacing
fix(time_entry_form): resolve custom field validation

Granular scopes (supported but not required):

feat(easy_ai.project_planner): add translation support
fix(design_system.time_entry_form): resolve date picker validation
refactor(easy_extensions.api): simplify authentication flow

Use granular scopes when you want to be more specific about the component or module affected.

Ticket References (Optional)

Include the reference at the end only when issue/PBI is known. Supported formats:

  • Numeric issue: (refs #1234)
  • Issue with prefix: (refs #issue-1234)
  • Product backlog item: (refs #pbi-1234)
feat: add dark mode toggle (refs #12345)
fix(api): resolve GraphQL timeout issue (refs #issue-67890)
docs: update contribution guidelines (refs #pbi-9146)
chore: clean up dead code

For commits affecting multiple references:

feat: implement user authentication (refs #12345, refs #12346)
feat: add new feature (refs #pbi-9146, refs #12345)

Examples

Good commit messages:

feat(easy_ai): add global deactivation button (refs #666352)
fix: resolve end date expiration in cloud (refs #issue-665117)
docs: update backend plugin development guide (refs #670348)
style(design_system): apply destructive styling to deactivation button (refs #666352)
refactor(custom_fields): simplify validation logic (refs #662662)
test: fix hosting services test coverage (refs #665446)
feat: implement user dashboard (refs #pbi-9146)

Bad commit messages:

# Missing ticket reference
feat: add new feature

# Missing type
Added new feature (refs #12345)

# Vague description
fix: fixed bug (refs #12345)

# Wrong reference format
feat: add feature refs: #12345
feat: add feature #12345

Multi-line Commit Messages

For complex changes, use a detailed commit body:

feat(authentication): implement OAuth2 integration (refs #12345)

- Add OAuth2 provider configuration
- Implement token refresh mechanism
- Update user model to support external auth
- Add comprehensive test coverage

Merge Request Guidelines

Creating a Merge Request

  1. Run relevant tests:
# Backend - identify and run tests related to your changes
bin/rspec spec/path/to/relevant_spec.rb

# Frontend - run tests for modified components
npm test path/to/test
npm run lint

Note: You don't need to run the entire test suite locally (it takes too long). Focus on tests directly affected by your changes. The CI pipeline will run the full test suite.

  1. Push your feature branch:
git push origin feature/12345_your_feature
  1. Create MR to the appropriate target branch:
  2. Features → next/minor
  3. Bug fixes → next/bugs
  4. Critical fixes → master (coordinate with team first)
  5. If MR assignee/reviewer are not specified, set assignee to me and reviewer to merge_request_pool (ID 93)

MR Title Format

Use the same convention as commit messages:

feat(scope): description (refs #1234)
feat(scope): description (refs #issue-1234)
feat(scope): description (refs #pbi-1234)
feat(scope): description

MR title must not use branch naming format.

MR Description Template

## Summary

Brief description of changes

## Changes

- List key changes
- Bullet points preferred

## Test Plan

- [ ] Manual testing performed
- [ ] Unit tests added/updated
- [ ] E2E tests added/updated

## Related Issues

refs #12345
refs #pbi-9146

Code Review

  • Address all review comments before merging
  • Keep discussions constructive and focused on code quality
  • Use GitLab's suggestion feature for small fixes
  • Re-request review after making changes

Best Practices

Commit Hygiene

  • Make atomic commits - Each commit should represent a single logical change
  • Commit frequently - Don't wait until everything is done
  • Write clear messages - Future you will thank you
  • Keep commits focused - Avoid mixing unrelated changes

Before Committing

# Check what will be committed
git status
git diff --staged

# Run linters
bundle exec rubocop -a  # Ruby
npm run lint:fix        # JavaScript/TypeScript

# Run relevant tests only
bin/rspec spec/models/user_spec.rb              # Specific backend test
npm test src/components/MyComponent.test.ts     # Specific frontend test

Testing Strategy: Run only the tests relevant to your changes. The full test suite runs in CI and takes considerable time. Identify which specs or test files are affected by your changes and run those locally.

Avoiding Common Mistakes

Don't commit:

  • Sensitive data (.env files, credentials, API keys)
  • Build artifacts (unless required)
  • IDE-specific files (.idea/, .vscode/ - use .gitignore)
  • Temporary files or debug code
  • Commented-out code blocks

Do commit:

  • Source code changes
  • Test files
  • Documentation updates
  • Configuration changes
  • Database migrations

Getting Help

  • Documentation: Run make docs-serve to access full developer docs
  • Code style: Follow existing patterns in the codebase
  • Questions: Ask in team channels or code review comments
  • Issues: Report bugs at the project's issue tracker

Quick Reference

# Create feature branch (targets next/minor)
git checkout -b feature/12345_description

# Create bug fix branch (targets next/bugs)
git checkout -b fix/12345_description

# Stage changes
git add path/to/file

# Commit with proper message
git commit -m "feat(scope): description (refs #12345)"
# or for PBI references
git commit -m "feat(scope): description (refs #pbi-9146)"

# Push to remote
git push -u origin feature/12345_description

# Create merge request to appropriate branch:
# - Features: next/minor
# - Bug fixes: next/bugs
# - Critical: master
# Use GitLab UI or gh CLI

Remember: Good commits make code review easier, debugging faster, and collaboration smoother!