Organizational

Git & Commit Conventions

Standards for version control, conventional commits, and branching strategies.

Production

Commit Message Convention

We follow the Conventional Commits specification. This provides a structured history that allows for automated changelog generation and semantic versioning.

Format

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

[optional body]

[optional footer(s)]

Types

You MUST use one of the following types:

TypeDescriptionWhen to use
featFeatureA new feature for the user, not a new feature for the build script.
fixBug FixA bug fix for the user.
choreChoreChanges to the build process or auxiliary tools and libraries such as documentation generation.
docsDocumentationDocumentation only changes.
styleStyleChanges that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc).
refactorRefactoringA code change that neither fixes a bug nor adds a feature.
perfPerformanceA code change that improves performance.
testTestsAdding missing tests or correcting existing tests.
ciCIChanges to our CI configuration files and scripts (e.g. GitHub Actions, Taskfile).
buildBuildChanges that affect the build system or external dependencies (example scopes: gulp, broccoli, npm).
revertRevertReverts a previous commit.

Scope (Optional)

The scope provides additional context:

  • feat(auth): add login support
  • fix(api): handle timeout in user service
  • chore(deps): upgrade react to v18

Description

  • Use the imperative, present tense: "change" not "changed" nor "changes".
  • Don't capitalize the first letter.
  • No dot (.) at the end.

Breaking Changes

Breaking changes MUST be indicated by:

  1. A ! after the type/scope: feat(api)!: remove v1 endpoint
  2. Or a BREAKING CHANGE: footer.

Note on Squash and Merge

Only the final squashed commit merged into master must strictly follow the Conventional Commits specification.
Intermediate commits within a Pull Request may be less strict (e.g. WIP, fixup), as they will not land on master.


Pull Request Rules

  • Pull Requests should be small and focused on a single logical change.
  • The PR title will be used as the final squashed commit message and must follow Conventional Commits.
  • The PR description should clearly explain the why of the change, not only the what.
  • All CI checks (lint, tests) must pass before merging.
  • At least one approval is required before merging.

Branching Strategy

We use a simplified flow based on Feature Branches.

  • master: Production-ready code. Protected branch.
  • feature/*: For new features (e.g., feature/user-auth).
  • fix/*: For bug fixes (e.g., fix/login-error).
  • chore/*: For maintenance (e.g., chore/update-deps).

Workflow

  1. Create a branch from master.
  2. Commit changes using Conventional Commits.
  3. Open a Pull Request (PR) to master.
  4. Wait for CI checks (lint, test) to pass.
  5. Get code review approval.
  6. Squash and Merge into master.

Examples

Feature:

feat(search): add autocomplete to search bar

Adds a debounced search input that queries the autocomplete API
after 300ms of inactivity.

Bug Fix:

fix(payment): prevent double charge on retry

The payment button was not disabled after the first click,
allowing users to submit the form multiple times.

Breaking Change:

feat(auth)!: switch to JWT only

BREAKING CHANGE: The `session_id` cookie is no longer supported.
Clients must now send the `Authorization: Bearer <token>` header.

Chore:

chore(deps): update terraform to 1.5.0

Why This Matters

  • Automated Changelogs: We can generate release notes automatically based on feat and fix commits.
  • Semantic Versioning: We can determine if a release is Major, Minor, or Patch based on the commit types.
  • Readability: The history becomes easy to scan and understand.