Skip to content

No monorepo / subdirectory support — tools run only from repo root, ignoring subdir project configs #53

Description

@matthew-on-git

Type: enhancement · Area: project discovery, working directory, monorepo

Summary

DevRail runs every tool from the repo root. In a monorepo where each language lives in its own subdirectory with its own manifest and tool config, tools run in the wrong working directory and never load per-project configuration.

Environment

  • Image: ghcr.io/devrail-dev/dev-toolchain:v1
  • .devrail.yml: languages: [python, javascript]
  • Layout (no manifests at repo root):
    api/       pyproject.toml, uv.lock, src/, tests/                      (Python, uv)
    frontend/  package.json, package-lock.json, vite.config.ts, tsconfig.json  (Vue/Vite)
    

Reproduction

make test / make lint from the repo root:

  • vitest can't resolve the @ alias defined in frontend/vite.config.ts:
    Error: Cannot find package '@/components/BatchActionToolbar.vue'
           imported from /workspace/frontend/src/__tests__/...
    
  • tsc: skipping tsc type check: no tsconfig.json found (it's at frontend/tsconfig.json).
  • eslint: looks for config at repo root; the frontend's config lives under frontend/.
  • pytest: runs from /workspace, but imports (src.*) and config (api/pyproject.toml) resolve relative to api/.

Note: ruff happens to work because it discovers the nearest pyproject.toml per file. That per-file discovery is the exception — most tools (vitest, tsc, eslint, pytest) resolve config and rootdir from the current working directory.

Impact

Any repo that isn't single-language-at-root: api/ + frontend/, services/*, packages/*, Nx/Turbo/Cargo workspaces, etc. Config discovery and cwd-relative resolution break even when the language itself is fully supported.

Proposed solution (autodetect-first)

Autodetect project roots by scanning for language manifests, then run each language's tools with cwd set to the detected directory (so vite/tsc/eslint/pytest load local config and resolve aliases):

Language Root signal
Python pyproject.toml / setup.py / setup.cfg
JS/TS package.json
Go go.mod
Rust Cargo.toml
Ansible ansible.cfg / playbook dir

For each detected project, run lint/format/test/etc. from that directory and aggregate results per project.

Explicit override in .devrail.yml for non-standard layouts (autodetect used when omitted):

projects:
  - path: api
    languages: [python]
  - path: frontend
    languages: [javascript]

Acceptance criteria

  • With no projects: config, DevRail discovers api/ and frontend/ from their manifests and runs each language's tools in the correct cwd (local config + path aliases resolve).
  • projects: override supported for layouts autodetect can't infer.
  • Results reported per project/path (so a failure says which project failed).
  • Combines cleanly with the dependency-provisioning work (install runs per detected project root).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions