mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-11-15 07:41:20 +00:00
Bundled examples keep their behavior tests in backend/tests/, so the core backend workflow ran optional extension behavior on every pull request. Mark those suites with pytest.mark.bundled_extension, exclude them from the core shards and from the duration baseline, and run them in a dedicated workflow through make test-bundled-extensions. Tests of host mechanisms stay in the core shards even when an example package is the payload. The marked suites import deerflow.agents, config, runtime, knowledge and app.gateway, so the workflow triggers for backend/packages/**, backend/app/gateway/** and the marked test modules; a backend test pins those paths, the make target and both marker selections, and fails when a marked module is missing from the path list. Host/extension compatibility checks — a host API gate and authorization of contributed routes — live in test_extension_host_contracts.py so they still fail core CI. The committed duration baseline drops the 482 entries for the excluded suites. Refs #8173 Co-authored-by: REI-330 <173389910+REI-330@users.noreply.github.com> Co-authored-by: willem-bd <143703838+willem-bd@users.noreply.github.com> Co-authored-by: Eilen6316 <136898293+Eilen6316@users.noreply.github.com>
88 lines
4.3 KiB
Makefile
88 lines
4.3 KiB
Makefile
DEER_FLOW_HOME ?= $(CURDIR)/.deer-flow
|
|
DEER_FLOW_HOME := $(abspath $(DEER_FLOW_HOME))
|
|
BACKEND_SANDBOX_HOME := $(abspath $(CURDIR)/sandbox)
|
|
|
|
install:
|
|
uv sync --locked
|
|
|
|
dev:
|
|
mkdir -p "$(DEER_FLOW_HOME)" "$(BACKEND_SANDBOX_HOME)"
|
|
PYTHONPATH=. PYTHONIOENCODING=utf-8 PYTHONUTF8=1 DEER_FLOW_HOME="$(DEER_FLOW_HOME)" uv run --locked uvicorn app.gateway.app:app --host 127.0.0.1 --port 8001 \
|
|
--reload \
|
|
--reload-include='*.yaml' \
|
|
--reload-include='.env' \
|
|
--reload-exclude='*.pyc' \
|
|
--reload-exclude='__pycache__' \
|
|
--reload-exclude="$(BACKEND_SANDBOX_HOME)" \
|
|
--reload-exclude="$(DEER_FLOW_HOME)"
|
|
|
|
gateway:
|
|
PYTHONPATH=. PYTHONIOENCODING=utf-8 PYTHONUTF8=1 uv run --locked uvicorn app.gateway.app:app --host 127.0.0.1 --port 8001
|
|
|
|
# Run all four duration-balanced shards locally; wait for every shard on failure.
|
|
TEST_JOBS ?= 4
|
|
TEST_SHARD_TARGETS := test-shard-1 test-shard-2 test-shard-3 test-shard-4
|
|
.PHONY: test test-shard test-bundled-extensions $(TEST_SHARD_TARGETS)
|
|
test:
|
|
$(MAKE) --no-print-directory -k -j$(TEST_JOBS) $(TEST_SHARD_TARGETS)
|
|
|
|
$(TEST_SHARD_TARGETS):
|
|
$(MAKE) --no-print-directory test-shard SPLITS=4 GROUP=$(patsubst test-shard-%,%,$@)
|
|
|
|
test-live:
|
|
DEER_FLOW_RUN_LIVE_TESTS=1 PYTHONPATH=. PYTHONIOENCODING=utf-8 PYTHONUTF8=1 uv run pytest -m live tests/ -v -s
|
|
|
|
test-blocking-io:
|
|
PYTHONPATH=. PYTHONIOENCODING=utf-8 PYTHONUTF8=1 uv run pytest tests/blocking_io -q --tb=short
|
|
|
|
# Run the backend unit-test suite as one shard of a parallel CI split.
|
|
# SPLITS = total number of shards; GROUP = 1-based shard index.
|
|
# Duration-aware: `least_duration` balances the shards by real wall-clock cost
|
|
# read from .test_durations. Shards only READ that file (no --store-durations),
|
|
# so concurrent CI jobs cannot race writes on it. Refresh it with
|
|
# `make test-shard-durations` after a meaningful change to the test set.
|
|
# `make test-shard SPLITS=4 GROUP=2` runs shard 2 of 4; a bare `make test-shard`
|
|
# runs the whole offline suite as a single split; `make test` runs all four shards.
|
|
SPLITS ?= 1
|
|
GROUP ?= 1
|
|
DURATIONS_FILE ?= .test_durations
|
|
test-shard:
|
|
@test -f "$(DURATIONS_FILE)" || \
|
|
(echo "error: $(DURATIONS_FILE) is missing; run 'make test-shard-durations' to regenerate the duration baseline" >&2; exit 1)
|
|
PYTHONPATH=. PYTHONIOENCODING=utf-8 PYTHONUTF8=1 uv run pytest -m "not live and not bundled_extension" --ignore=tests/blocking_io --splits $(SPLITS) --group $(GROUP) --splitting-algorithm least_duration --durations-path=$(DURATIONS_FILE) tests/ -q
|
|
|
|
# Regenerate .test_durations from the offline core suite (non-live,
|
|
# non-blocking-I/O, non-bundled-extension) so duration-aware sharding reflects
|
|
# real wall-clock cost. Run locally or in a periodic job, then commit the
|
|
# refreshed file.
|
|
test-shard-durations:
|
|
PYTHONPATH=. PYTHONIOENCODING=utf-8 PYTHONUTF8=1 uv run pytest -m "not live and not bundled_extension" --ignore=tests/blocking_io --store-durations --clean-durations --durations-path=$(DURATIONS_FILE) tests/ -q
|
|
|
|
# Bundled extension examples own their behavior suites; the core shards exclude
|
|
# them so an optional example cannot fail an unrelated core PR. The extension CI
|
|
# workflow runs this target when an example, the extension contract or the
|
|
# bundled tests themselves change.
|
|
test-bundled-extensions:
|
|
PYTHONPATH=. PYTHONIOENCODING=utf-8 PYTHONUTF8=1 uv run pytest -m "bundled_extension and not live" tests/ -q
|
|
|
|
lint:
|
|
uv run ruff check .
|
|
uv run ruff format --check .
|
|
|
|
format:
|
|
uv run ruff check . --fix && uv run ruff format .
|
|
|
|
detect-blocking-io:
|
|
@PYTHONPATH=. PYTHONIOENCODING=utf-8 PYTHONUTF8=1 uv run python ../scripts/detect_blocking_io_static.py --output ../.deer-flow/blocking-io-findings.json
|
|
|
|
# Generate a new alembic revision by autogenerating the diff against the live
|
|
# ORM models. Usage: make migrate-rev MSG="add foo column to runs"
|
|
# The Gateway runs `alembic upgrade head` automatically at startup via
|
|
# `bootstrap_schema`, so there is intentionally no `migrate` / `migrate-stamp`
|
|
# target -- the single execution path keeps ops mistakes off the table.
|
|
# The script builds a fresh temp SQLite at head, then diffs the live models
|
|
# against it, so a clean checkout does NOT need a pre-existing ./data/deerflow.db.
|
|
migrate-rev:
|
|
@if [ -z "$(MSG)" ]; then echo 'usage: make migrate-rev MSG="describe the change"'; exit 1; fi
|
|
PYTHONPATH=. PYTHONIOENCODING=utf-8 PYTHONUTF8=1 uv run python scripts/_autogen_revision.py "$(MSG)"
|