Prerequisite: You should be familiar with basic Git operations and
understand the Monorepo Architecture of our
codebase.
Overview
Tuturuuu follows standardized conventions for Git commits and branch naming to improve collaboration, automate releases, and maintain a clean, navigable repository history. We use two main specifications:- Conventional Commits for structured commit messages
- Conventional Branch for consistent branch naming
Conventional Commits
What are Conventional Commits?
Conventional Commits is a specification for adding human and machine-readable meaning to commit messages. It provides a set of rules for creating an explicit commit history, making it easier to write automated tools on top of. The basic structure of a conventional commit is:Types
Tuturuuu uses the following commit types:| Type | Description | Example |
|---|---|---|
feat | New feature or enhancement | feat: add dark mode support |
fix | Bug fix | fix: prevent crash when user data is undefined |
docs | Documentation changes | docs: update installation instructions |
style | Code style changes (formatting, no code change) | style: format code with prettier |
refactor | Code refactoring | refactor: simplify authentication logic |
perf | Performance improvements | perf: optimize database queries |
test | Add or fix tests | test: add unit tests for auth middleware |
build | Changes affecting build system or dependencies | build: update dependency to fix security issue |
ci | Changes to CI configuration files and scripts | ci: simplify workflow branch filters |
chore | Routine tasks, maintenance | chore: update package.json metadata |
Scopes
Scopes provide additional context about which part of the codebase is affected. In our monorepo structure, we often use package or app names as scopes:Breaking Changes
Breaking changes must be indicated by adding a! after the type/scope or by using a BREAKING CHANGE: footer:
Examples
Here are some examples of conventional commits used in our codebase:Conventional Branches
What are Conventional Branches?
Conventional Branch refers to a structured naming convention for Git branches that makes it easier to identify branches by type and purpose. The basic structure is:Branch Types
Tuturuuu uses the following branch types:| Type | Description | Example |
|---|---|---|
main | Main development branch | main |
feature | For new features | feature/user-dashboard |
feat | Short feature prefix also accepted | feat/invite-link-permissions |
fix | Short bug-fix prefix also accepted | fix/invite-membership-check |
bugfix | For bug fixes | bugfix/login-error |
hotfix | For urgent fixes | hotfix/security-vulnerability |
release | For preparing releases | release/v1.2.0 |
chore | For maintenance tasks | chore/update-dependencies |
docs | For documentation-only work | docs/git-conventions-refresh |
style | For formatting or stylistic cleanups | style/biome-pass |
refactor | For internal code restructuring | refactor/task-query-shell |
perf | For performance-focused changes | perf/workspace-user-search |
dependabot | Automated dependency update branches | dependabot/npm_and_yarn/next |
claude | AI-assisted scratch or experimental PR | claude/rate-limit-audit |
release-please--branches-- prefix. Do not create human-authored branches with
that prefix.
Naming Rules
- Use lowercase alphanumeric characters and hyphens
- Keep names concise but descriptive
- Include ticket/issue numbers when applicable
- Avoid special characters (except hyphens)
Examples
Merge Commit Exception
Authored commits should follow Conventional Commits. The common exception is a Git-generated merge commit when syncing a long-lived branch, for example:How These Conventions Improve Our Workflow
1. Automated Changelog Generation
Our conventional commits are used to automatically generate changelogs for releases. Different commit types are categorized accordingly:2. Semantic Versioning
Conventional commits help determine the next semantic version for packages:fix:commits trigger a PATCH increment (1.0.0 → 1.0.1)feat:commits trigger a MINOR increment (1.0.0 → 1.1.0)- Commits with
BREAKING CHANGEtrigger a MAJOR increment (1.0.0 → 2.0.0)
3. Automated Release PRs And Package Publishing
Release Please reads Conventional Commits fromproduction, updates
release-please-config.json packages through .release-please-manifest.json,
and opens one combined release PR with package versions and changelogs. Package
publish workflows do not generate versions; they publish only after a
release-please version bump lands on production. Local manifests keep
Tuturuuu workspace dependencies as workspace:*; npm release workflows rewrite
the checked-out package manifest with
scripts/ci/prepare-npm-package-manifest.js immediately before npm pack so
published artifacts contain installable npm version ranges. Before that rewrite,
scripts/ci/package-release-readiness.js waits for publishable Tuturuuu
workspace dependency versions on npm, and publish jobs wait for their own
version to become visible after npm publish. Dependency waits inspect the
related release workflow for the same production SHA and fail fast when that
workflow already failed. Workflow-published package manifests must carry
provenance-compatible repository metadata for tutur3u/platform; otherwise
npm rejects trusted publishes with E422. For example,
release-types-package.yaml triggers from production changes to
packages/types/package.json:
When bringing the generated release PR branch back to main, run
bun git-release-please from a clean main checkout. The helper fetches the
latest release-please--branches--production branch, merges it without
committing, syncs platform-version.txt into the platform badge constant and
test expectation, runs bun ff, stages the resolved merge, then lets the normal
commit hook run bun check and conditional bun check:mobile before the merge
commit lands. If you are already inside a manual merge, run
bun release:sync-platform-version to resolve the recurring
TUTURUUU_PLATFORM_VERSION conflict before staging the merge.
4. Better Code Reviews
With conventional commits and branches, it’s easier to understand the purpose of a pull request at a glance:- A PR from
feature/user-dashboardwith commits likefeat: add user stats widgetclearly indicates a new feature - A PR from
bugfix/auth-issuewith commits likefix: prevent token expiration errorindicates a bug fix
5. Simplifying Navigation
Conventional branch names make it easier to navigate the repository history and find specific changes. For example:Tools and Enforcement
We use a dedicated CI/CD check to enforce our Git conventions:Branch Naming Check
We use a GitHub Action workflow to verify that branch names follow our convention:Best Practices
Writing Good Commit Messages
- Use the imperative mood (“add” not “added” or “adds”)
- Capitalize the first letter of the description
- Do not end the description with a period
- Keep the description under 72 characters
- Use the body to explain the what and why, not the how
Coordinating Commits In Shared Checkouts
When multiple agents or humans may commit in the same checkout, use the commit window before changing the staged set. The lock is advisory and lives under the ignoredtmp/agent-coordination/ directory, so it protects the Git index and
commit operation without becoming part of a commit. Claims default to 10
minutes and may only be 5-10 minutes, so claim only when ready to stage,
inspect, and commit.
wait. The
command sleeps until the active lock is released or expires, then claims the
window before reporting that it is safe to proceed. The waiting period can be
longer than the claim TTL, but the claimed window remains capped at 10 minutes:
--allow-staged only after inspecting existing staged files. The commit
window does not grant ownership of files or permission to stage unrelated paths.
Branch Management
- Create branches from the latest
mainbranch - Keep branches focused on a single task or issue
- Regularly rebase long-lived branches on
mainto avoid merge conflicts - Delete branches after they’ve been merged
Synchronizing Release Branches
Use the root command below whenproduction should point at the same commit as
main:
origin, creates a temporary detached worktree, refreshes
main, and fast-forwards production to the current main commit from that
temporary worktree before pushing those branches. It finishes by fetching again
and verifying that local and remote main and production both resolve to the
same commit. The checkout you started from is left untouched, so uncommitted
work on another branch can keep running while the release refs are synchronized.
If a branch that needs to move is already checked out in another worktree, Git
will refuse to force-update that branch. Switch that worktree away from the
branch or update it manually, then rerun bun git-sync.
bun git-sync does not create commits for you. Commit all intended changes on
main first; if production contains commits that are not already in main,
reconcile the branch manually before rerunning the command.
Use --only-branch to update one active sync branch while leaving the other
untouched:
main is still refreshed locally as the source commit, but only production is
fast-forwarded and pushed. Use --only-branch main when you only want to pull
and push main.
The retired staging branch is no longer a supported --only-branch target.
The Supabase staging environment still exists, but its workflow is driven from
main.
Use --no-push for local-only synchronization:
--no-push, the command fetches, pulls with --ff-only, and fast-forwards
the selected local branches, but it never pushes to origin. Final verification
checks local refs only.
Pull Request Workflow
- Create a branch with the appropriate type based on the work
- Make commits using conventional commit messages
- Push the branch and create a pull request
- Use conventional commit style for the PR title
- After approval and merge, delete the branch