Skip to content

Contributing

TruePPM is in its early days and contributions are welcome. The project uses GitLab for issue tracking and merge requests.

Looking for something to work on? Browse issues carrying the backlog label — triaged and not yet scheduled. Check that an issue doesn’t already have an open merge request or an assignee before you pick it up.

For anything beyond a typo or one-line fix, open an issue first describing what you want to change and why. This avoids wasted effort if the change conflicts with the roadmap or the OSS/Enterprise boundary below.

Who reviews, and how fast: the maintainer monitors the issue tracker and merge requests, and responds within a few business days.

Community channel: GitLab issues and merge requests are the project’s only channel today — there is no separate chat or forum yet.

Code of conduct: participation is governed by the Contributor Covenant 2.1. Be respectful — disagreement about technical choices is fine, disrespect toward contributors is not.

Terminal window
git clone git@gitlab.com:trueppm/trueppm.git
cd trueppm
make setup # installs git hooks via pre-commit
make doctor # verifies all prerequisites

See Installation for Docker Compose setup.

The web app reads build-time settings from packages/web/.env (gitignored) — copy packages/web/.env.example and adjust. Vite only exposes variables prefixed with VITE_, and a change takes effect only after restarting the dev server.

VariableDefaultPurpose
VITE_API_BASE_URLunset (dev proxies to localhost:8000)Deployed API base URL for production builds
VITE_FEATURE_FLAGSunsetJSON build-time defaults for runtime feature flags
VITE_REACT_QUERY_DEVTOOLSoffSet to true to show the React Query devtools panel in dev builds

The React Query devtools panel is off by default so it never occupies screen real estate during normal development. To debug query-cache state, set VITE_REACT_QUERY_DEVTOOLS=true in packages/web/.env and restart Vite. It is gated on dev builds, so it is never present in a production bundle regardless of this value.

Branch from main with a conventional prefix:

Terminal window
git checkout main && git pull origin main
git checkout -b feat/my-feature # or fix/, docs/, chore/, test/, refactor/

Never commit or push directly to main — all changes go through a feature branch and merge request.

Follow Conventional Commits:

feat(web): add board/kanban view
fix(api): prevent duplicate membership creation
docs(scheduler): add Monte Carlo CLI examples
test(api): add permission tests for task deletion
chore(ci): upgrade Node to 22 in CI image

Scopes: scheduler, api, web, helm, sync, docs, ci.

Every MR that touches source code must include a changelog fragment in changelog.d/:

Terminal window
# Naming: <slug>.<type>.md
# Types: added, changed, fixed, security
echo "Add board/kanban view with drag-and-drop" > changelog.d/kanban-view.added.md

The CI changelog:check job blocks the pipeline if the fragment is missing. Fragments are assembled automatically at release time — never edit CHANGELOG.md directly.

Exempt: CI config, dependency bumps, test-only changes, docs-only changes.

Terminal window
make test # runs all packages
# Or per-package:
cd packages/scheduler && pytest
cd packages/api && pytest
cd packages/web && npm test
  • Scheduler: pytest, coverage >= 80%
  • API: pytest with testcontainers PostgreSQL, coverage >= 80%
  • Web: vitest, coverage >= 75%

The API suite bans real outbound network sockets: a test that reaches the live network (usually a misdirected mock) fails fast with a SocketConnectBlockedError instead of hanging on a connect timeout and flaking. Only the configured database and Redis hosts are allowed. A test that genuinely needs the network must opt out explicitly with @pytest.mark.enable_socket — keeping the exception visible and reviewable.

All MRs require a green pipeline before merge.

Run make pre-push before every git push — it mirrors the blocking CI gates (lint, typecheck, migrations-check, schema-check).

PackageFormatterLinterType checker
Schedulerruff formatruff checkmypy
APIruff formatruff checkmypy —strict
Webprettiereslinttsc —noEmit
Terminal window
make lint # runs all linters
make typecheck # runs all type checkers
  1. Push your branch and open an MR targeting main
  2. Wait for a green pipeline
  3. Include: description, testing done, screenshots (if UI), issue link
  4. Don’t merge with a failing pipeline — fix the root cause on the branch

Before writing code for a new feature, determine if it belongs in the community or enterprise repo:

  • Community (this repo): everything a PM or program team needs to run a program (including multi-project programs)
  • Enterprise (separate repo): cross-program/portfolio governance, compliance, and org-level policy

The community edition must never import from trueppm_enterprise. Verify with:

Terminal window
grep -r "trueppm_enterprise" packages/
# Must return zero results