mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-11-12 14:00:35 +00:00
fix(ci): label every harness tree as backend (#8029)
* fix(ci): label every harness tree as backend `area:backend` enumerated the harness subdirectories that map to it instead of the trees that map elsewhere, so thirteen of the twenty-eight directories under `deerflow/` matched no area rule at all: community/, authz/, scheduler/, storage/, tui/ and eight more. A PR that only touched `deerflow/community/` therefore came out unlabelled, or with `area:docs` alone when it also edited a markdown file — #7482 (crawl4ai) and #7826 (jina) are merged examples. Match the harness as a whole and exclude the six trees that carry a more specific label (agents, subagents, reflection, sandbox, skills, mcp). Checked against all 28 directories: the 13 unlabelled ones now match `area:backend`, and the sandbox / skills / mcp / agents / frontend results are unchanged. * fix(ci): cover backend package paths in PR triage --------- Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
This commit is contained in:
parent
463361c5ba
commit
fb094984e3
8
.github/workflows/triage.yml
vendored
8
.github/workflows/triage.yml
vendored
@ -55,7 +55,13 @@ jobs:
|
||||
// ---- area: replaces .github/labeler.yml (path -> area) ----
|
||||
const AREA_RULES = [
|
||||
['area:frontend', [/^frontend\//]],
|
||||
['area:backend', [/^backend\/app\//, /^backend\/packages\/harness\/deerflow\/(runtime|persistence|config|tools|guardrails|tracing|models|utils|uploads)\//]],
|
||||
// Cover both backend packages. Keep the harness exclusions aligned
|
||||
// with the dedicated tree rules below; the offline replay checks this.
|
||||
['area:backend', [
|
||||
/^backend\/app\//,
|
||||
/^backend\/packages\/harness\/(?!deerflow\/(?:agents|subagents|reflection|sandbox|skills|mcp)\/)/,
|
||||
/^backend\/packages\/extension-api\//,
|
||||
]],
|
||||
['area:agents', [/^backend\/packages\/harness\/deerflow\/(agents|subagents|reflection)\//, /(^|\/)langgraph\.json$/, /^backend\/.*\/prompts\//]],
|
||||
['area:sandbox', [/^docker\//, /^backend\/packages\/harness\/deerflow\/sandbox\//, /(^|\/)Dockerfile$/]],
|
||||
['area:skills', [/^skills\//, /^backend\/packages\/harness\/deerflow\/skills\//, /^frontend\/src\/core\/skills\//]],
|
||||
|
||||
@ -1,8 +1,11 @@
|
||||
"""Offline checks of the triage workflow's literal label declarations."""
|
||||
"""Offline checks of the triage workflow's label declarations and area rules."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib.util
|
||||
import json
|
||||
import shutil
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
@ -193,3 +196,74 @@ def test_every_real_applied_label_is_enforced(files, capsys, label):
|
||||
triage.write_text((REPO_ROOT / ".github/workflows/triage.yml").read_text(encoding="utf-8"), encoding="utf-8")
|
||||
assert checker.main() == 1
|
||||
assert f" - {label}\n" in capsys.readouterr().err
|
||||
|
||||
|
||||
@pytest.mark.skipif(shutil.which("node") is None, reason="Workflow replay requires Node.js")
|
||||
def test_pr_area_labels_cover_backend_packages():
|
||||
harness = "backend/packages/harness"
|
||||
deerflow = REPO_ROOT / harness / "deerflow"
|
||||
specific_areas = {
|
||||
"agents": "area:agents",
|
||||
"subagents": "area:agents",
|
||||
"reflection": "area:agents",
|
||||
"sandbox": "area:sandbox",
|
||||
"skills": "area:skills",
|
||||
"mcp": "area:mcp",
|
||||
}
|
||||
cases = [
|
||||
([f"{harness}/pyproject.toml", "backend/uv.lock"], {"area:backend", "area:deps"}),
|
||||
(["backend/packages/extension-api/deerflow_extension_api/__init__.py"], {"area:backend"}),
|
||||
([f"{harness}/deerflow/__init__.py"], {"area:backend"}),
|
||||
([f"{harness}/deerflow/agents_extra/example.py"], {"area:backend"}),
|
||||
(
|
||||
["frontend/src/example.tsx", f"{harness}/deerflow/agents/example.py", f"{harness}/deerflow/community/README.md"],
|
||||
{"area:frontend", "area:agents", "area:backend", "area:docs"},
|
||||
),
|
||||
]
|
||||
for directory in sorted(deerflow.iterdir()):
|
||||
if directory.is_dir() and directory.name != "__pycache__":
|
||||
path = directory.relative_to(REPO_ROOT).as_posix()
|
||||
area = specific_areas.get(directory.name, "area:backend")
|
||||
cases.append(([f"{path}/example.py"], {area}))
|
||||
|
||||
scripts = checker.workflow_scripts(checker.TRIAGE_WORKFLOW.read_text(encoding="utf-8"))
|
||||
(script,) = (source for source in scripts if "const AREA_RULES =" in source)
|
||||
result = subprocess.run(
|
||||
[
|
||||
"node",
|
||||
"-e",
|
||||
"""
|
||||
const { readFileSync } = require('node:fs');
|
||||
const { script, changes } = JSON.parse(readFileSync(0, 'utf8'));
|
||||
const AsyncFunction = Object.getPrototypeOf(async function () {}).constructor;
|
||||
const applyLabels = new AsyncFunction('github', 'context', 'core', script);
|
||||
|
||||
async function replay(paths) {
|
||||
const labels = [];
|
||||
const github = {
|
||||
paginate: (list) => list(),
|
||||
rest: {
|
||||
pulls: { listFiles: () => paths.map(filename => ({ filename })) },
|
||||
issues: {
|
||||
listLabelsOnIssue: () => [],
|
||||
addLabels: (request) => { labels.push(...request.labels); },
|
||||
},
|
||||
},
|
||||
};
|
||||
const context = { repo: { owner: 'test', repo: 'test' }, payload: { pull_request: { number: 1 }, action: 'synchronize' } };
|
||||
await applyLabels(github, context, { info() {} });
|
||||
return labels.filter(label => label.startsWith('area:'));
|
||||
}
|
||||
|
||||
Promise.all(changes.map(replay)).then(labels => console.log(JSON.stringify(labels)));
|
||||
""",
|
||||
],
|
||||
input=json.dumps({"script": script, "changes": [paths for paths, _ in cases]}),
|
||||
capture_output=True,
|
||||
encoding="utf-8",
|
||||
check=False,
|
||||
timeout=10,
|
||||
)
|
||||
assert result.returncode == 0, result.stderr
|
||||
for (paths, expected), labels in zip(cases, json.loads(result.stdout), strict=True):
|
||||
assert sorted(labels) == sorted(expected), paths
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user