Contributing to DevRepro Doctor¶
Thank you for helping kill "works on my machine"! 🩺
Ground rules¶
- Read-only default is sacred. Any feature that mutates a system must be dry-run by default, risk-tiered, and gated behind explicit confirmation.
- Privacy is non-negotiable. Never capture usernames, home directory absolute paths, tokens, keys, or credential material in findings/evidence. Add synthetic-secret tests for anything that reads env vars or config files.
- One failing probe must never crash a scan. Wrap risky operations; the probe engine isolates failures by design.
- Never invent exact versions. Requirements come only from what projects actually declare in manifests/lockfiles/policies.
mainis the only permanent branch. Reconcile useful work into main, delete stale branches, never rewrite published history.
Development setup¶
Requires Python 3.11+ and Node 18+ (for the frontend).
git clone https://github.com/webdevsamran/devrepro-doctor
cd devrepro-doctor
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e ".[test,lint]"
pre-commit install
cd web && npm ci && cd .. # frontend deps
Running checks locally¶
ruff check devrepro tests && ruff format --check devrepro tests
mypy # strict mode
pytest # full suite, fixture-driven
pytest --cov=devrepro --cov-report=term-missing
cd web && npm run lint && npm run typecheck && npm test && npm run build
Project layout¶
See ARCHITECTURE.md for the module map and data flow. Key contracts:
- Probes: subclass
devrepro.probes.base.Probe, returnProbeResultwith typedFindings andEvidence. Register via entry point groupdevrepro.probes. - Rules: subclass
devrepro.rules.base.Rule; packs live underdevrepro/rules/packs/<name>.py. Entry point groupdevrepro.rules. - Remediations: subclass
devrepro.remediation.base.Remediation; must declarerisk,preconditions,changes,rollback. Entry point groupdevrepro.remediations. - Project detectors: implement
ProjectDetector; entry point groupdevrepro.project_detectors. - Exporters: implement
Exporter; entry point groupdevrepro.exporters.
Plugin APIs are versioned: see docs/PLUGINS.md.
Testing requirements¶
- Tests must not depend on the real developer machine. Use fixtures in
tests/fixtures/and inject fake command runners. - A fake runner is not enough on its own. Three probes still read the host
around their
ProbeContext-- a hardcoded/usr/lib/jvm,Path.home(),platform.machine()-- and their tests passed on the author's machine and failed on somebody else's. If a probe must ask the running process something, make it overridable throughctx.extraand state both sides in the test. See ARCHITECTURE.md decision 2. - If the same context gives a different answer on a different machine, that is the bug -- in the probe, not in the runner that found it.
- Use property-based tests (
hypothesis) for version-range logic, PATH normalization, manifest parsers, and sanitization. - Every new redaction surface needs a synthetic-secret regression test.
Commit style¶
Conventional commits: feat(probes): add rustup probe, fix(diff): ...,
docs: ..., ci: .... Logical commits pushed to main after validation.
Branch protection¶
main is protected at the repository level (GitHub API, Settings → Branches):
- Force pushes and deletion are blocked; rules are admin-enforced for collaborators, with an intentional bypass for the repository owner so direct-to-main maintenance pushes keep working.
- Pull requests can only merge when all 18 required checks are green:
every CI matrix job (
Python (ubuntu/macos/windows-latest, 3.11–3.14)),Frontend,Docs site,Dependency security scan,analyze (python),analyze (javascript-typescript)andCode scanning results / CodeQL. - Direct pushes by maintainers remain permitted (no review gate for this single-maintainer project); PR merges require passing checks either way.
If you add, remove or rename a CI job, update the required-check list in Settings → Branches → main afterwards — otherwise pull requests hang on a check that no longer exists. Branch protection lives in repository settings, not in git history, so it is not reproducible from this repo's files alone.
Release¶
Maintainers cut releases per docs/release.md: a v* tag builds, generates an SPDX SBOM, and publishes to PyPI through Trusted Publishing (provenance attested by the publish action; no separate checksum files are produced).
Do not claim Homebrew/winget/Scoop availability until those packages exist.
Questions¶
Open a discussion or issue. For security matters, see SECURITY.md.