Skip to content

Commit 0fca0c6

Browse files
committed
change(ci): Overhaul CI flow management
1 parent b20655a commit 0fca0c6

File tree

507 files changed

+2032
-1911
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

507 files changed

+2032
-1911
lines changed

.github/CODEOWNERS

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
/libraries/ESP_SR/ @me-no-dev
6060
/libraries/ESPmDNS/ @me-no-dev
6161
/libraries/Ethernet/ @me-no-dev
62+
/libraries/Hash/ @lucasssvaz
6263
/libraries/Matter/ @SuGlider
6364
/libraries/NetBIOS/ @me-no-dev
6465
/libraries/Network/ @me-no-dev
@@ -72,9 +73,9 @@
7273
/libraries/Wire/ @me-no-dev
7374
/libraries/Zigbee/ @P-R-O-C-H-Y
7475

75-
# CI JSON
76+
# CI YAML
7677
# Keep this after other libraries and tests to avoid being overridden.
77-
**/ci.json @lucasssvaz
78+
**/ci.yml @lucasssvaz
7879

7980
# The CODEOWNERS file should be owned by the developers of the ESP32 Arduino Core.
8081
# Leave this entry as the last one to avoid being overridden.

.github/scripts/get_affected.py

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
Build file patterns
6464
--------------------
6565
- **build_files**: Core Arduino build system files (platform.txt, variants/**, etc.)
66-
- **sketch_build_files**: Sketch-specific files (ci.json, *.csv in example directories)
66+
- **sketch_build_files**: Sketch-specific files (ci.yml, *.csv in example directories)
6767
- **idf_build_files**: Core IDF build system files (CMakeLists.txt, idf_component.yml, etc.)
6868
- **idf_project_files**: Project-specific IDF files (per-example CMakeLists.txt, sdkconfig, etc.)
6969
@@ -128,7 +128,7 @@
128128
# Files that are used by the sketch build system.
129129
# If any of these files change, the sketch should be recompiled.
130130
sketch_build_files = [
131-
"libraries/*/examples/**/ci.json",
131+
"libraries/*/examples/**/ci.yml",
132132
"libraries/*/examples/**/*.csv",
133133
]
134134

@@ -150,7 +150,7 @@
150150
# If any of these files change, the example that uses them should be recompiled.
151151
idf_project_files = [
152152
"idf_component_examples/*/CMakeLists.txt",
153-
"idf_component_examples/*/ci.json",
153+
"idf_component_examples/*/ci.yml",
154154
"idf_component_examples/*/*.csv",
155155
"idf_component_examples/*/sdkconfig*",
156156
"idf_component_examples/*/main/*",
@@ -358,6 +358,59 @@ def build_qname_from_tag(tag: dict) -> str:
358358
qname = "::".join([p for p in qparts if p])
359359
return f"{qname}{signature}"
360360

361+
def find_impl_files_for_qname(qname: str, defs_by_qname: dict[str, set[str]], header_path: str = None) -> set[str]:
362+
"""
363+
Find implementation files for a qualified name, handling namespace mismatches.
364+
365+
Ctags may capture different namespace scopes in headers vs implementations.
366+
For example:
367+
- Header: fs::SDFS::begin(...)
368+
- Implementation: SDFS::begin(...)
369+
370+
This happens when implementations use "using namespace" directives.
371+
372+
Strategy:
373+
1. Try exact match first
374+
2. If no match and qname has namespaces, try stripping ONLY outer namespace prefixes
375+
(keep at least Class::method structure intact)
376+
3. If header_path provided, prefer implementations from same directory
377+
"""
378+
# Try exact match first
379+
impl_files = defs_by_qname.get(qname, set())
380+
if impl_files:
381+
return impl_files
382+
383+
# If no exact match and the qname contains namespaces (::), try stripping them
384+
if "::" in qname:
385+
parts = qname.split("::")
386+
# Only strip outer namespaces, not the class/method structure
387+
# For "ns1::ns2::Class::method(...)", we want to try:
388+
# - "ns2::Class::method(...)" (strip 1 level)
389+
# - "Class::method(...)" (strip 2 levels)
390+
# But NOT "method(...)" alone (too ambiguous)
391+
392+
# Only allow stripping if we have more than 2 parts (namespace::Class::method)
393+
# If we only have 2 parts (Class::method), don't strip as it would leave just "method"
394+
if len(parts) > 2:
395+
# Keep at least 2 parts (Class::method) to avoid false positives
396+
max_strip = len(parts) - 2
397+
398+
for i in range(1, max_strip + 1):
399+
shorter_qname = "::".join(parts[i:])
400+
impl_files = defs_by_qname.get(shorter_qname, set())
401+
402+
if impl_files:
403+
# If we have the header path, prefer implementations from same directory
404+
if header_path:
405+
header_dir = os.path.dirname(header_path)
406+
same_dir_files = {f for f in impl_files if os.path.dirname(f) == header_dir}
407+
if same_dir_files:
408+
return same_dir_files
409+
410+
return impl_files
411+
412+
return set()
413+
361414
def run_ctags_and_index(paths: list[str]) -> tuple[dict[str, set[str]], dict[str, set[str]], str]:
362415
"""
363416
Run Universal Ctags over given paths (relative to project_root) and build:
@@ -582,8 +635,10 @@ def build_dependencies_graph() -> None:
582635
if qnames:
583636
impl_files = set()
584637
for qn in qnames:
585-
# For each qualified name, get the implementation files
586-
impl_files |= ctags_defs_by_qname.get(qn, set())
638+
# For each qualified name, find implementation files
639+
# This handles namespace mismatches (e.g., fs::SDFS vs SDFS)
640+
# Pass header_path to prefer implementations from same directory
641+
impl_files |= find_impl_files_for_qname(qn, ctags_defs_by_qname, header_path)
587642
for impl in impl_files:
588643
# Skip .ino files - they should never be dependencies of other files
589644
if impl.endswith('.ino'):

.github/scripts/on-push-idf.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ fi
1717

1818
for example in $affected_examples; do
1919
example_path="$PWD/components/arduino-esp32/$example"
20-
if [ -f "$example_path/ci.json" ]; then
20+
if [ -f "$example_path/ci.yml" ]; then
2121
# If the target is listed as false, skip the sketch. Otherwise, include it.
22-
is_target=$(jq -r --arg target "$IDF_TARGET" '.targets[$target]' "$example_path/ci.json")
22+
is_target=$(yq eval ".targets.${IDF_TARGET}" "$example_path/ci.yml" 2>/dev/null)
2323
if [[ "$is_target" == "false" ]]; then
2424
printf "\n\033[93mSkipping %s for target %s\033[0m\n\n" "$example" "$IDF_TARGET"
2525
continue

0 commit comments

Comments
 (0)