Contributing
GospeLib is a polyglot monorepo spanning TypeScript (Next.js), Python (FastAPI), and Go (Chi) services. This guide covers everything you need to go from a fresh clone to a merged pull request.
Getting Started
For initial setup, see Getting Started.
Branch Naming
Create a branch from master using the following prefixes:
| Prefix | Use when... | Example |
|---|---|---|
feat/ | Adding a new feature | feat/lexicon-search |
fix/ | Fixing a bug | fix/gateway-timeout |
docs/ | Documentation-only changes | docs/add-testing-guide |
chore/ | Maintenance, dependency updates, tooling | chore/upgrade-vitest |
refactor/ | Restructuring code without behavior change | refactor/content-query-layer |
Keep branch names short and descriptive. Use hyphens, not underscores.
Commit Conventions
This project enforces Conventional Commits via commitlint and a Husky commit-msg hook. Every commit must follow this format:
type(scope): description
[optional body]
[optional footer(s)]
Types
| Type | Purpose |
|---|---|
feat | New feature |
fix | Bug fix |
docs | Documentation only |
style | Formatting, missing semicolons, etc. |
refactor | Code change that neither fixes nor adds |
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 |
revert | Reverts a previous commit |
Scopes
Use one of these scopes to indicate the area of the change:
web | mobile | admin | gateway | content | auth | billing | ai | notifications | ingest | ui | sdk | types | config | infra | ci | deps
Examples
feat(web): add dark mode toggle
fix(gateway): handle timeout on health check
docs(content): update API schema docs
Interactive Commit Workflow
Instead of writing the message manually, use the Commitizen wizard:
pnpm commit
# or
make commit
This walks you through type, scope, description, body, and breaking changes interactively.
Breaking Changes
To signal a breaking change (triggers a major version bump), add a BREAKING CHANGE footer:
feat(sdk)!: redesign authentication flow
BREAKING CHANGE: The `login()` method now returns a session object instead of a token string.
Pull Request Process
-
Keep PRs focused on a single concern. One feature, one bug fix, or one refactor per PR.
-
Title your PR using conventional commit format:
feat(web): add search pagefix(gateway): handle missing JWT gracefullydocs(guides): add testing guide -
Link related issues in the PR description so they close automatically on merge.
-
Ensure CI passes before requesting review. All lint, type-check, and test jobs must be green.
-
Request review from at least one team member.
CI Flow
Every pull request triggers the following pipeline:
PR opened / updated
--> Lint (all languages)
pnpm nx affected -t lint --parallel=4
pnpm nx affected -t typecheck --parallel=4
--> Test (parallel by language)
test-js: nx affected -t test --parallel=3
test-python: uv run pytest (per service, with containers)
test-go: go test ./... -race (per service)
--> Build check
pnpm nx affected -t build
All jobs must pass before a PR can be merged. Lint and type-check failures block merge.
Pre-Commit Pipeline
Every local commit runs through Husky hooks automatically:
git commit
--> lint-staged
*.{js,jsx,ts,tsx,mjs,cjs,mts,cts} --> eslint --fix, prettier --write
*.{json,md,yml,yaml,css,scss} --> prettier --write
--> commitlint (validates Conventional Commits format)
This catches formatting and lint issues before they reach CI.
Release Process
Component Releases (Automated)
Component releases are fully automated via release-please:
- Commits to
masterare analyzed by release-please. - A release PR is auto-created (or updated) with changelog entries and version bumps.
- Merging the release PR triggers the release -- tags are created per component (e.g.,
gateway/v1.0.0).
No manual versioning or changelog editing is required.
Production Releases
Production deployments are triggered by pushing a release/v*.*.* tag. The production CD pipeline runs the full regression suite, waits for manual approval via GitHub environment protection rules, then builds, pushes, and deploys all service images.
Documentation
GospeLib's engineering documentation lives in a Docusaurus site under apps/docs/. The live site is deployed at docs.gospelib.com.
Adding or Editing a Doc Page
- Create or edit a Markdown file in
apps/docs/docs/under the appropriate directory. - Sidebar ordering is autogenerated -- you usually do not need to edit
sidebars.ts. Usesidebar_positionin frontmatter or_category_.jsonto control ordering. - Preview locally with
pnpm --filter docs devbefore pushing.
Adding a Blog Post
Create a new Markdown file in apps/docs/blog/ named YYYY-MM-DD-slug.md with title, authors, and tags frontmatter.
Development Guides
For detailed standards on code quality, testing, and operational practices, see:
- Code Quality -- Linters, formatters, and type checkers across all languages
- Testing -- How to run and write tests (Vitest, pytest, Go test)
- Logging & Observability -- Structured logging, tracing, profiling, and health endpoints
- Error Handling -- Error catalog, response envelope, and per-language error patterns