fix(ci): resolve Builder security and formatting checks

This commit is contained in:
twwu committed 2026-11-09 10:44:31 +08:00
1 parent 84abb5af06
commit 3ee45dff0d
12 files changed
+158 -128

No files matched your search

+3 -10
View File
@@ -9,14 +9,9 @@ import dify_agent
import pytest
# API-installed SDK must be this checkout, with the missing server extra pinned by its own lock.
assert (
Path(dify_agent.__file__).resolve().is_relative_to(Path("dify-agent/src").resolve())
)
assert Path(dify_agent.__file__).resolve().is_relative_to(Path("dify-agent/src").resolve())
packages = tomllib.loads(Path("dify-agent/uv.lock").read_text())["package"]
assert (
next(package["version"] for package in packages if package["name"] == "jwcrypto")
== "1.5.7"
)
assert next(package["version"] for package in packages if package["name"] == "jwcrypto") == "1.5.7"
EXPECTED = {
"tests.integration_tests.services.dify_builder.test_agent_recovery_postgres": {
@@ -103,9 +98,7 @@ else:
for module, functions in EXPECTED.items():
print(f"COLLECTED {module}: {sum(actual[module].values())} cases", flush=True)
if dict(actual[module]) != functions:
problems.append(
f"recovery case inventory mismatch {module}: {dict(actual[module])!r}"
)
problems.append(f"recovery case inventory mismatch {module}: {dict(actual[module])!r}")
for problem in problems:
print(f"COMPLETENESS {problem}", flush=True)
raise SystemExit(int(code) or (1 if problems else 0))
+28 -74
View File
@@ -138,19 +138,13 @@ FILES += [
]
FILES += [
path
for path in [
"api/tests/unit_tests/services/dify_builder/native_testing/test_confirmed_agent_completion.py"
]
for path in ["api/tests/unit_tests/services/dify_builder/native_testing/test_confirmed_agent_completion.py"]
if path not in FILES
]
FILES += [
"api/tests/unit_tests/services/dify_builder/native_testing/test_confirmed_agent_terminal_scan.py"
]
FILES += ["api/tests/unit_tests/services/dify_builder/native_testing/test_confirmed_agent_terminal_scan.py"]
FILES += [
path
for path in [
"api/tests/unit_tests/services/dify_builder/test_agent_model_result_canonical.py"
]
for path in ["api/tests/unit_tests/services/dify_builder/test_agent_model_result_canonical.py"]
if path not in FILES
]
FILES += ["api/tests/unit_tests/services/dify_builder/test_test_actions.py"]
@@ -264,10 +258,7 @@ code = pytest.main(
)
# Full module identity avoids silently merging same-basename owners.
module_paths = [*FILES, *(selection.split("::", 1)[0] for selection in SELECTED_GUARDS)]
modules = {
Path(path).with_suffix("").as_posix().removeprefix("api/").replace("/", "."): 0
for path in module_paths
}
modules = {Path(path).with_suffix("").as_posix().removeprefix("api/").replace("/", "."): 0 for path in module_paths}
identities = set()
problems = []
if not Path(JUNIT).is_file():
@@ -276,11 +267,7 @@ else:
for case in ElementTree.parse(JUNIT).getroot().iter("testcase"):
classname, name = case.get("classname") or "", case.get("name") or ""
normalized = classname.removeprefix("api.")
matching = [
module
for module in modules
if normalized == module or normalized.startswith(module + ".")
]
matching = [module for module in modules if normalized == module or normalized.startswith(module + ".")]
if len(matching) != 1:
problems.append(f"unexpected unit case {classname}::{name}")
continue
@@ -831,12 +818,8 @@ for module, functions in {
}.items():
a4_expected.setdefault(module, {}).update(functions)
# Candidate 3: frozen exact collection; retain every previously required function.
a4_expected.setdefault(
"tests.unit_tests.services.dify_builder.test_agent_model_result_canonical", {}
).update(
{
"test_model_receipt_matches_sdk_roundtrip_without_changing_stream_or_accepting_replacement": 2
}
a4_expected.setdefault("tests.unit_tests.services.dify_builder.test_agent_model_result_canonical", {}).update(
{"test_model_receipt_matches_sdk_roundtrip_without_changing_stream_or_accepting_replacement": 2}
)
a4_expected.setdefault(
"tests.unit_tests.services.dify_builder.native_testing.test_confirmed_agent_completion",
@@ -957,9 +940,7 @@ a4_expected["tests.unit_tests.core.dify_builder.test_ports"] = {
"test_mutation_intent_defaults_and_args_not_shared": 1,
}
# Exact collected Code failure-policy regression inventories (Local JUnit/AST checked).
a4_expected[
"tests.unit_tests.services.dify_builder.test_bound_resource_plan_reconciliation"
] = {
a4_expected["tests.unit_tests.services.dify_builder.test_bound_resource_plan_reconciliation"] = {
"test_confirmed_resource_reconciles_fallback_and_overview_before_approval": 1,
"test_unusable_reconciliation_keeps_resource_gate_and_does_not_offer_approval": 3,
"test_reconciliation_rereads_selected_facts_and_uses_one_model_reply": 1,
@@ -2139,9 +2120,7 @@ a4_expected["tests.unit_tests.services.dify_builder.test_test_actions"] = {
"test_standard_choice_envelope_can_submit_native_control": 1,
"test_earlier_action_identity_cannot_be_reused_after_another_command": 1,
}
a4_expected[
"tests.unit_tests.services.dify_builder.native_testing.test_confirmed_agent_completion"
].update(
a4_expected["tests.unit_tests.services.dify_builder.native_testing.test_confirmed_agent_completion"].update(
{
"test_native_control_only_commits_do_not_strand_successful_builder_run": 1,
"test_terminal_projection_crash_is_recovered_without_get_or_dispatch": 1,
@@ -2155,17 +2134,13 @@ a4_expected.setdefault(
"tests.unit_tests.services.dify_builder.native_testing.test_confirmed_agent_completion",
{},
).update({"test_expired_terminal_context_requires_actual_owned_terminal_workflow": 7})
a4_expected.setdefault(
"tests.unit_tests.services.dify_builder.test_agent_operation_owner", {}
).update(
a4_expected.setdefault("tests.unit_tests.services.dify_builder.test_agent_operation_owner", {}).update(
{"test_expired_completed_receipt_requires_exact_original_permit_and_result": 1}
)
a4_expected[
"tests.unit_tests.services.dify_builder.native_testing.test_confirmed_agent_terminal_scan"
] = {"test_terminal_scan_compares_input_ids_as_strings": 2}
a4_expected[
"tests.unit_tests.services.dify_builder.native_testing.test_confirmed_agent_completion"
].update(
a4_expected["tests.unit_tests.services.dify_builder.native_testing.test_confirmed_agent_terminal_scan"] = {
"test_terminal_scan_compares_input_ids_as_strings": 2
}
a4_expected["tests.unit_tests.services.dify_builder.native_testing.test_confirmed_agent_completion"].update(
{
"test_cancel_after_completed_effects_closes_original_parent": 2,
"test_resumed_saved_cancellation_projects_only_unchanged_terminal_proof": 17,
@@ -2227,15 +2202,12 @@ task_control_transport_expected = {
}
for function, count in task_control_transport_expected.items():
actual = sum(
classname.removeprefix("api.")
== "tests.unit_tests.controllers.console.test_dify_builder_routes"
classname.removeprefix("api.") == "tests.unit_tests.controllers.console.test_dify_builder_routes"
and name.split("[", 1)[0] == function
for classname, name in identities
)
if actual != count:
problems.append(
f"Task control transport inventory mismatch {function}: {actual} != {count}"
)
problems.append(f"Task control transport inventory mismatch {function}: {actual} != {count}")
# Current priority closeout: exact Local-collected regression inventory.
a4_expected["tests.unit_tests.core.dify_builder.test_handlers_build"] = {
"test_a_determinate_outcome_resets_the_unknown_outcome_count": 1,
@@ -2701,9 +2673,7 @@ a4_expected["tests.unit_tests.services.dify_builder.test_agent_operation_owner"]
"test_prepare_actual_call_freezes_builder_reasoning_without_business_or_oauth": 8,
}
)
a4_expected[
"tests.unit_tests.services.dify_builder.native_testing.test_agent_risk_assessor"
].update(
a4_expected["tests.unit_tests.services.dify_builder.native_testing.test_agent_risk_assessor"].update(
{
"test_risk_rubric_separates_observed_destruction_from_uncertain_side_effects": 1,
}
@@ -2885,20 +2855,16 @@ a4_expected.update(
)
# Exact first-phase P0 additions; retain all unrelated reviewed cases.
a4_expected["tests.unit_tests.services.dify_builder.test_agent_operation_owner"].update(
{
"test_native_model_permission_expiring_during_metadata_prevents_preparation_and_claim": 1
}
{"test_native_model_permission_expiring_during_metadata_prevents_preparation_and_claim": 1}
)
# The latest main merge adds transaction-lifetime witnesses to the existing owner.
a4_expected["tests.unit_tests.services.test_workflow_run_service"].update(
{"test_trace_assembly_uses_a_session_from_the_injected_factory": 2}
)
a4_expected[
"tests.unit_tests.core.workflow.generator.test_native_code_output_contract"
].update({"test_batch_code_contract_validates_identity_before_grouping": 3})
knowledge_cases = a4_expected[
"tests.unit_tests.services.dify_builder.test_knowledge_discovery"
]
a4_expected["tests.unit_tests.core.workflow.generator.test_native_code_output_contract"].update(
{"test_batch_code_contract_validates_identity_before_grouping": 3}
)
knowledge_cases = a4_expected["tests.unit_tests.services.dify_builder.test_knowledge_discovery"]
del knowledge_cases["test_refusing_goal_change_keeps_knowledge_wait_and_never_replans"]
knowledge_cases.update(
{
@@ -3140,9 +3106,7 @@ for module, functions in {
a4_expected.setdefault(module, {}).update(functions)
# ENG-1240: exact additions from affected module collection; retain prior inventories.
for module, functions in {
"tests.unit_tests.controllers.inner_api.agent.test_llm": {
"test_post_streams_plugin_compatible_envelope": 2
},
"tests.unit_tests.controllers.inner_api.agent.test_llm": {"test_post_streams_plugin_compatible_envelope": 2},
"tests.unit_tests.controllers.inner_api.test_agent_runtime_lineage": {
"test_actual_native_identity_with_all_body_markers_removed_refuses_before_services": 20,
"test_agent_bearer_refuses_equality_with_existing_enterprise_or_daemon_credential": 2,
@@ -3291,9 +3255,7 @@ for module, expected in {**a3_expected, **a4_expected}.items():
actual[function] = actual.get(function, 0) + 1
if actual != expected:
problems.append(f"A3 function inventory mismatch {module}: {actual}")
json_admission_module = (
"tests.unit_tests.services.dify_builder.test_json_tool_execution_admission"
)
json_admission_module = "tests.unit_tests.services.dify_builder.test_json_tool_execution_admission"
expected_json_admission = {
f"test_owned_json_parse_prepare_persists_restricted_request[{variant}]"
for variant in ("raw-true", "raw-false", "constant-true", "constant-false")
@@ -3305,14 +3267,10 @@ expected_json_admission.update(
}
)
actual_json_admission = {
name
for classname, name in identities
if classname.removeprefix("api.") == json_admission_module
name for classname, name in identities if classname.removeprefix("api.") == json_admission_module
}
if actual_json_admission != expected_json_admission:
problems.append(
"JSON admission case identities differ from the reviewed prepare variants and owner checks"
)
problems.append("JSON admission case identities differ from the reviewed prepare variants and owner checks")
json_policy_module = "tests.unit_tests.services.dify_builder.test_json_tool_execution"
json_policy_expected = {
"test_reviewed_pure_mixed_graph_admits_exact_native_chain": 1,
@@ -3494,9 +3452,7 @@ for module, functions in {
}.items():
json_contract_expected.setdefault(module, {}).update(functions)
# ENG-1417: value-free failed Code format facts and current failed-Run provenance.
json_contract_expected.setdefault(
"tests.unit_tests.services.dify_builder.test_condition_evidence", {}
).update(
json_contract_expected.setdefault("tests.unit_tests.services.dify_builder.test_condition_evidence", {}).update(
{
"test_failed_code_format_facts_reach_diagnosis_and_repair_without_values": 1,
"test_failed_code_format_classifies_only_observed_table_samples": 5,
@@ -3521,9 +3477,7 @@ for module, expected in {
for function, expected_count in expected.items():
if actual.get(function, 0) != expected_count:
problems.append(f"JSON case inventory mismatch {module}::{function}")
if (module == json_policy_module or module in json_runtime_expected) and set(
actual
) != set(expected):
if (module == json_policy_module or module in json_runtime_expected) and set(actual) != set(expected):
problems.append(f"unexpected JSON test functions {module}")
print(f"COLLECTED total: {len(identities)} unit cases", flush=True)
for problem in problems: