Type: bug / enhancement · Area: test target, dependency provisioning
Summary
make test runs the language test runners (pytest, vitest) inside dev-toolchain, but the container ships only the runners — not the project's runtime dependencies. DevRail never installs project deps (uv sync / npm ci / pip install), so make test fails at import time for essentially any real application.
Environment
- Image:
ghcr.io/devrail-dev/dev-toolchain:v1
.devrail.yml: languages: [python, javascript]
- Project: FastAPI backend (uv, in
api/) + Vue/Vite frontend (npm, in frontend/)
Reproduction
make test:
Python
rootdir: /workspace
collected 0 items / 1 error
ERROR collecting api/tests
api/tests/conftest.py:5: in <module>
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
E ModuleNotFoundError: No module named 'sqlalchemy'
JavaScript (same class of failure — vue/primevue/etc. not installed):
Error: Cannot find package '@/components/BatchActionToolbar.vue' ...
Root cause
- The Makefile
_test target runs pytest / vitest directly.
- There is no dependency-installation step anywhere in the flow — grep for
uv sync, npm ci, pip install -r, poetry install finds nothing; the only install is pip install --user pre-commit (for git hooks).
DEVELOPMENT.md: "All tools are pre-installed in the dev-toolchain container." True for tools, but a project's dependencies can never be pre-baked into a generic image.
Impact
Affects every dependency-bearing project, regardless of language (FastAPI, Django, Flask, Vue, React, Express, …). Only fully-stdlib code can be tested today. lint / format / security / scan are unaffected because they are tool-only.
Proposed solution (autodetect-first)
Before _test (and any target that imports project code), install project dependencies, autodetected from lockfiles/manifests — zero config in the common case:
Python (first match wins):
| Signal |
Command |
uv.lock |
uv sync --frozen |
poetry.lock |
poetry install |
Pipfile.lock |
pipenv sync |
requirements*.txt |
pip install -r <file> |
pyproject.toml / setup.py |
pip install -e . |
JavaScript/TypeScript (first match wins):
| Signal |
Command |
package-lock.json |
npm ci |
pnpm-lock.yaml |
pnpm install --frozen-lockfile |
yarn.lock |
yarn install --frozen-lockfile |
Escape hatches in .devrail.yml for what autodetect can't infer:
test:
install: "uv sync --frozen" # override autodetected dep install
setup: "make migrate" # pre-test hook (fixtures, migrations)
services: # ephemeral services for tests
- postgres:16
- redis:7
Services are the one piece autodetect can't fully infer. Support an explicit services: list — DevRail starts throwaway containers on the test network and injects standard env (DATABASE_URL, REDIS_URL, …). Optionally autodetect from a docker-compose.test.yml when present.
Acceptance criteria
make test installs deps via the autodetected manager, then runs the suite green for a dependency-bearing project with zero extra config.
- Optional
.devrail.yml test.install / test.setup / test.services override/augment autodetection.
- All installs happen inside the container; nothing leaks to the host.
Type: bug / enhancement · Area:
testtarget, dependency provisioningSummary
make testruns the language test runners (pytest, vitest) insidedev-toolchain, but the container ships only the runners — not the project's runtime dependencies. DevRail never installs project deps (uv sync/npm ci/pip install), somake testfails at import time for essentially any real application.Environment
ghcr.io/devrail-dev/dev-toolchain:v1.devrail.yml:languages: [python, javascript]api/) + Vue/Vite frontend (npm, infrontend/)Reproduction
make test:Python
JavaScript (same class of failure —
vue/primevue/etc. not installed):Root cause
_testtarget runspytest/vitestdirectly.uv sync,npm ci,pip install -r,poetry installfinds nothing; the onlyinstallispip install --user pre-commit(for git hooks).DEVELOPMENT.md: "All tools are pre-installed in the dev-toolchain container." True for tools, but a project's dependencies can never be pre-baked into a generic image.Impact
Affects every dependency-bearing project, regardless of language (FastAPI, Django, Flask, Vue, React, Express, …). Only fully-stdlib code can be tested today.
lint/format/security/scanare unaffected because they are tool-only.Proposed solution (autodetect-first)
Before
_test(and any target that imports project code), install project dependencies, autodetected from lockfiles/manifests — zero config in the common case:Python (first match wins):
uv.lockuv sync --frozenpoetry.lockpoetry installPipfile.lockpipenv syncrequirements*.txtpip install -r <file>pyproject.toml/setup.pypip install -e .JavaScript/TypeScript (first match wins):
package-lock.jsonnpm cipnpm-lock.yamlpnpm install --frozen-lockfileyarn.lockyarn install --frozen-lockfileEscape hatches in
.devrail.ymlfor what autodetect can't infer:Services are the one piece autodetect can't fully infer. Support an explicit
services:list — DevRail starts throwaway containers on the test network and injects standard env (DATABASE_URL,REDIS_URL, …). Optionally autodetect from adocker-compose.test.ymlwhen present.Acceptance criteria
make testinstalls deps via the autodetected manager, then runs the suite green for a dependency-bearing project with zero extra config..devrail.ymltest.install/test.setup/test.servicesoverride/augment autodetection.