# Contributing Guidelines Welcome, brave engineer. Before you type `git commit -m "oops"` and vanish for 3 weeks of PTO, let's align on how commits work in this repo. We follow [**Conventional Commits**](https://www.conventionalcommits.org/) with **semantic versioning**.\ This gives us: - Automatic changelogs (no one likes writing them manually) - Predictable version bumps - Clear history that future-you (or your replacement) can actually read --- ## 1. Commit Message Format Every commit **MUST** follow this format: ``` (): [optional body] [optional BREAKING CHANGE: ...] [optional footer(s)] ``` - \`\` → what you did - \`\` *(optional, but strongly encouraged)* → where you did it - \`\` → short explanation (imperative tense) - **Body** → additional details, rationale, or context (wrap at 72 chars if possible) - **Footer** → metadata such as references to backlog items or related issues > ❗ There must be a blank line separating `BREAKING CHANGE:` from any footer lines. ### Examples ``` feat(auth): add token refresh endpoint Added a new endpoint for refreshing authentication tokens to reduce full login frequency. Refs: JIRA-1234 ``` ``` fix(api): correctly parse null values Previously, null values in payloads caused 500 errors due to improper validation. Updated parser to handle null safely. BREAKING CHANGE: Parser behavior has changed for null payloads. Refs: JIRA-9876 ``` --- ## 2. Allowed Commit Types | Type | When to Use | | ---------- | ----------------------------------------- | | `build` | Build system changes (configs, scripts) | | `feat` | A new feature | | `fix` | A bug fix | | `docs` | Documentation updates | | `style` | Non-functional style changes (formatting) | | `refactor` | Code change that isn’t a bug or feature | | `test` | Adding/fixing tests | | `chore` | Maintenance tasks (deps, configs) | --- ## 3. Scopes Scopes keep commits relevant. Commonly you'll find service, or module names, used as the scope: ``` feat(api): add user endpoint fix(web): handle expired token ``` > While unrelated areas should be split into separate commits, multiple scopes can be combined in a single commit if they are related: `refactor(web,api): clean up regex for widget payloads` If you're touching multiple unrelated areas, split the work.\ If you’re touching the **entire repo**, you may omit the scope (e.g. `chore: update prettier config`). --- ## 4. Commit Body Use the body to: - Explain **why** the change was made - Add context or reasoning (if it’s not obvious from the diff) - Mention relevant technical details > ❗ Keep the body wrapped at 72 characters where possible for better readability in CLI tools. Example: ``` fix(auth): improve token handling Added stricter validation to prevent expired tokens from being used in refresh calls. This fixes intermittent 401 errors for long-lived sessions. ``` --- ## 5. Commit Footer Use the footer for: - `BREAKING CHANGE:` declarations (with a blank line after it) - References to backlog items, tickets, or issues - Co-authorship metadata if needed (`Co-authored-by:`) Example: ``` feat(ui): add dark mode toggle Added a dark mode toggle in the user settings page. BREAKING CHANGE: Removed old theme switcher. Refs: JIRA-4567 ``` --- ## 6. Linting & Enforcement This repo uses: - [**commitlint**](https://github.com/conventional-changelog/commitlint) to reject bad commit messages - [**husky**](https://typicode.github.io/husky) to run lint checks pre-commit After cloning the repository, run `npm install` to ensure husky hooks are installed and initialized locally. If you skip this step, GitHub Actions will run the same commit linting on your pull requests. Any bad commits that bypass local checks will result in a failed PR check. If you try to commit `do some stuff`, the hook will fail and mock you.\ Run `npm run commit` if you want a guided prompt. --- ## 7. Pull Requests - Keep PRs small and focused. - Please use `--amend` commits or `--fixup` commits where appropriate - Squash `fixup:` commits, and any commits that don’t add value (e.g. `chore: typo`). - Ensure commit messages still follow Conventional Commits after squashing. --- ## 8. Versioning We use **semantic versioning**: - `fix:` → Patch (`1.0.1`) - `feat:` → Minor (`1.1.0`) - `BREAKING CHANGE:` → Major (`2.0.0`) Your commit messages drive the versioning calculation. --- ### TL;DR - Use Conventional Commits. - Include a scope if it makes sense. - Write meaningful bodies when needed. - Use footers for breaking changes or ticket references. - Leave a blank line between BREAKING CHANGE and footer. - Your branch's commit history should tell the story of what you did. - Bad commits will be rejected by hooks, mocked by your peers, and possibly framed on Slack or in some PowerPoint presentation as "what not to do." --- Happy committing!