Your First PR
This guide walks you through the workflow for making a change and getting it merged — from branch creation to CI passing.
1. Create a Branch
Branch from main using this naming convention:
<type>/<scope>-<short-description>
Examples:
git checkout main
git pull origin main
git checkout -b feat/web-add-search-page
git checkout -b fix/gateway-timeout-handling
git checkout -b docs/content-update-api-docs
The type and scope match the Conventional Commits convention below.
2. Write Conventional Commits
Every commit must follow Conventional Commits. This is enforced by a commit-msg hook — commits that don't match will be rejected.
Format
type(scope): description
[optional body]
[optional footer(s)]
Types
| Type | When to Use |
|---|---|
feat | New feature |
fix | Bug fix |
docs | Documentation only |
style | Formatting, semicolons, etc. (no logic change) |
refactor | Code change that neither fixes nor adds a feature |
perf | Performance improvement |
test | Adding or updating tests |
build | Build system or external dependencies |
ci | CI configuration and scripts |
chore | Other changes that don't modify src or tests |
Scopes
Use one of these scopes to indicate the area of change:
web · mobile · admin · gateway · content · auth · billing · ai · notifications · ingest · ui · sdk · types · config · infra · ci · deps
Examples
git commit -m "feat(web): add dark mode toggle"
git commit -m "fix(gateway): handle timeout on health check"
git commit -m "docs(content): update API schema docs"
Interactive Commit (Recommended)
Instead of writing the commit message manually, use the Commitizen wizard:
pnpm commit
This walks you through type, scope, description, body, and breaking changes interactively.
3. Run Checks Locally
Before pushing, run the same checks that CI will run:
# Lint TypeScript/JavaScript
pnpm lint
# Type-check TypeScript
pnpm typecheck
# Run tests
pnpm test
For changes in a specific service:
# Python service (e.g., content)
cd services/content
uv run ruff check . # Lint
uv run mypy . # Type check
uv run pytest # Test
# Go service (e.g., gateway)
cd services/gateway
go vet ./... # Vet
go test ./... -race # Test
For faster checks, use Nx to run only what's affected by your changes:
pnpm nx affected -t lint --parallel=4
pnpm nx affected -t test --parallel=3
4. Push and Open a PR
git push origin feat/web-add-search-page
Then open a pull request on GitHub. Use the same Conventional Commit format for the PR title:
feat(web): add search page
PR Guidelines
- Keep PRs focused on a single concern. One feature, one fix, or one refactor per PR.
- Link related issues in the PR description (e.g.,
Closes #42). - Ensure CI passes before requesting review.
5. What CI Checks
When you open a PR, the CI pipeline runs:
| Job | What It Does |
|---|---|
| Lint | nx affected -t lint --parallel=4 — ESLint for TS/JS |
| Typecheck | TypeScript strict type checking |
| Test JS | Vitest for affected TypeScript/JavaScript projects |
| Test Python | pytest for affected Python services (with FalkorDB + PostgreSQL containers) |
| Test Go | go test ./... -race for affected Go services |
| Build | Docker image builds for all affected services |
All jobs must pass before a PR can be merged.
6. After Merge — Releases
Releases are fully automated via release-please:
- Commits to
mainare analyzed by release-please. - A release PR is auto-created with changelog entries and version bumps.
- Merging the release PR creates tags per component (e.g.,
gateway/v1.0.0). - CD pipelines trigger on component tags.
No manual versioning or changelog editing required.
Verify It Worked
After your PR is merged:
- Check that CI passed on
main. - If release-please opened or updated a release PR, your change is included in the changelog.
- Your commit appears in the
mainbranch history with the correct conventional commit format.
Next Step
See the Port Map & Services Overview for a quick reference of all services, ports, and data stores.
For coding standards, review guidelines, and more on the development workflow, see the Contributing section.