# Git Workflow ## Branching - Never commit directly to `main` - Delete branches after merge - Use the appropriate branch prefix for the type of work: | Prefix | Use when | |---|---| | `feature/-` | Adding new functionality or enhancing existing features | | `bug/-` | Fixing a non-urgent defect found during development or testing | | `hotfix/-` | Fixing a production issue that needs immediate attention | | `chore/-` | Routine maintenance, cleanup, dependency bumps, or tooling | | `docs/-` | Documentation-only changes | | `refactor/-` | Restructuring code without changing behavior | | `release/-` | Preparing a release (version bump, tag, changelog) | The prefixes mirror the commit types in [commit-messages.md](commit-messages.md#types), so the branch and its commits speak the same vocabulary. **bug vs hotfix:** Use `bug/` for defects caught before they affect production (failing tests, broken dev flows, issues found in review). Use `hotfix/` only when production is impacted and the fix needs to bypass normal review cadence. **Jira key:** When the work tracks a Jira issue, put the key after the prefix: `feature/PROJ-123-add-receipt-parser` (substitute the real project key, e.g. the infra or software-development project). This is what wires the branch, commits, and PR into the issue's development panel. See [Linking to Jira](#linking-to-jira) below. Work with no Jira issue (one-off scripts, trivial fixes) omits the key and uses a plain description. ## Commits - Commit each logical change individually with a descriptive message - See [commit-messages.md](commit-messages.md) for formatting rules - Keep the working tree clean: commit or stash before switching context ## Linking to Jira Work is tracked in Jira (`seahaven.atlassian.net`). Jira is the source of truth for *work*; GitHub is the source of truth for *code*. We do not duplicate issues between the two — we link them. The org-level **GitHub for Jira** app is already installed across all repos. It detects the Jira issue key (e.g. `PROJ-123`) wherever it appears and surfaces the branch, commits, PR, and deployment status in that issue's development panel automatically. To make that happen, mention the key in at least one of: - the branch name (`feature/PROJ-123-add-receipt-parser`) - the PR title (`[PROJ-123] Add receipt parser`) - a commit message (the `Refs:` trailer, see [commit-messages.md](commit-messages.md)) Mentioning it in the branch name covers all three at once, so that is the minimum bar. ### Smart Commit commands The integration also accepts inline commands in commit messages to act on the issue without opening Jira: | Command | Effect | |---|---| | `PROJ-123 #comment ` | Add a comment to the issue | | `PROJ-123 #time 2h ` | Log work | | `PROJ-123 #done` (or another transition name) | Transition the issue | Transition names are case-insensitive and match the issue's workflow (`#in-progress`, `#done`). Use these sparingly; the link itself is the main goal, not driving the whole workflow from commits. ## Deploy-Then-Merge The standard flow for changes that deploy to AWS: 1. Create a feature branch (`feature/add-receipt-parser`) 2. Develop and commit locally 3. Open a PR via `gh pr create` 4. Merge the feature branch into `main` locally 5. Deploy to the target environment (`sam deploy`, etc.) 6. Verify in production 7. Merge the PR on GitHub This ensures production works before the PR closes. If the deploy fails, the PR stays open and `main` on GitHub is still clean. ## Push Discipline - Push regularly; don't accumulate unpushed commits - Never force push `main` - Never amend or rewrite commits already pushed to `main` - If you need to add context to a past change, use PR descriptions or issue comments ## Versioning Use [Semantic Versioning](https://semver.org/) (SemVer) as the standard: `MAJOR.MINOR.PATCH`. | Increment | When | |---|---| | `MAJOR` | Breaking changes to the public API or contract (removed endpoints, changed request/response shapes, incompatible config changes) | | `MINOR` | New functionality that is backwards-compatible (new endpoints, new optional fields, new features) | | `PATCH` | Backwards-compatible bug fixes, dependency updates, documentation corrections | ### When to version Not every project needs versioning. Apply SemVer when the project has consumers that depend on its interface: | Version | Don't version | |---|---| | Published packages (npm, PyPI) | Internal SAM stacks with no external consumers | | Public APIs with external consumers | One-off scripts and migration tools | | Shared libraries used across repos | Internal tools used only by the team that builds them | | CLIs distributed to users | | ### How to tag Create annotated tags on `main` after the PR is merged: ```bash git tag -a v1.2.0 -m "v1.2.0" git push origin v1.2.0 ``` Start at `v0.1.0` for new projects. Move to `v1.0.0` when the interface is stable and has external consumers. ## Git Hooks Recommended hooks live in [`hooks/`](hooks/) — copy them into `.git/hooks/` when setting up a project. | Hook | Purpose | |---|---| | `pre-push` | Runs `npm ci` to catch lock file drift before it breaks CI | Install for a Node.js project: ```bash cp ~/Documents/repositories/engineering-handbook/hooks/pre-push .git/hooks/pre-push chmod +x .git/hooks/pre-push ``` ## Cleaning Up After a PR is merged: ```bash git checkout main git pull git branch -d feature/add-receipt-parser ``` Don't let stale local branches or untracked project directories accumulate.