This guide describes the conventions used across Simply Jet repositories. It applies as the default for every repository in the organisation that does not provide its own CONTRIBUTING.md.
These conventions are enforced where possible by tooling (lefthook, commitlint, biome, ruff, branch protection). This document explains the rules and helps new contributors set up their environment.
- The
mainbranch is protected. All changes land via pull request with at least one approval and clean CI. - The
stagingbranch (where present) is unprotected. Direct pushes are permitted for fast iteration on staging environments. - Feature work happens on short-lived branches.
<type>/<kebab-case-description>
Allowed types: feat, fix, chore, docs, refactor, test, ci, perf, build, style, revert.
Examples:
feat/passenger-search-by-tail-numberfix/booking-timeout-on-stripechore/bump-drizzle-ormdocs/clarify-deploy-section
A lefthook pre-push hook validates the branch name locally.
We follow Conventional Commits. Every commit message must follow this format:
<type>(<optional scope>): <imperative summary>
Examples:
feat: add passenger search by tail numberfix(booking): retry on Stripe timeoutchore(deps): bump drizzle-orm from 0.30 to 0.31docs(readme): clarify how to run the staging container
A commitlint hook enforces the format on every commit. Failed commits show which rule broke so you can amend the message.
- Git history remains scannable (
git log --onelinereads like a changelog). - Changelogs and version bumps can be generated automatically.
- Reviewers quickly identify the nature of a change.
- Open a PR from your feature branch into
main(orstagingfor staging-specific work). - Fill in the PR template completely. Reviewers rely on it.
- Each PR requires at least 1 approval and clean CI before merging.
- Default merge strategy is squash. The squash commit uses the PR title and body.
- Force pushes to
mainare blocked. To clean up history, rebase on your feature branch before pushing. - The head branch is automatically deleted after merge.
- One purpose per PR. Mixing unrelated changes makes review harder.
- Description matches the change. The PR template prompts for what, why, how tested, and reviewer notes. Use them.
- CI is green before requesting review.
- Screenshots or recordings for UI changes.
- Small enough to review in one sitting. Aim for under 400 lines changed where possible.
- Review within 1 business day of being assigned.
- Be specific in feedback; cite the file and line.
- Distinguish blocking comments from nice-to-haves (use the
nit:prefix for the latter). - Approve only when you would be comfortable owning the change yourself.
Each language has a tool that enforces formatting automatically:
| Language | Tool | Auto-enforced |
|---|---|---|
| TypeScript and JavaScript | biome |
Pre-commit hook and CI |
| Python | ruff and ruff format |
Pre-commit hook and CI |
| Terraform | terraform fmt and tflint |
Pre-commit hook and CI |
Run the relevant tool before opening a PR. The lefthook pre-commit hook does this automatically for staged files. CI rejects PRs with style failures.
After cloning a repository:
# Install dependencies (varies by repo)
bun install # JavaScript and TypeScript repos
uv sync # Python repos
# Install the git hooks
lefthook installMost repos run lefthook install automatically as a post-install step. Verify by attempting a commit; if the commit-msg hook does not fire, run lefthook install manually.
- Dependency updates are proposed automatically by Dependabot every Monday.
- Security updates are auto-PR'd as soon as a CVE is published for a vulnerable dependency.
- Manual dependency updates should go through the normal PR flow.
- Major version bumps for critical libraries (database drivers, framework cores) are blocked by
dependabot.ymland require a manual migration plan.
For vulnerability reports, see SECURITY.md. Do not file security issues as public GitHub issues.
- General engineering questions: ask in the team Slack channel.
- GitHub, tooling, or organisation questions: rama-kairi or mondalraj.
- Security questions: it@simply-jet.ch.
- Website: simply-jet.ch
- LinkedIn: @simply-jet-sa