summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhathach <[email protected]>2026-08-22 23:10:14 +0700
committerhathach <[email protected]>2026-08-22 23:10:14 +0700
commit050595d64f9f130783853a2342eb1114d32199e8 (patch)
tree4f4e06b386205185ea49e9af9586b6c7206c625a
parent6ff0ef97702c0e6b6d17b7a8fe856b31164efe57 (diff)
ci_select: address Copilot review - anchor _META_RE, cover rule 12b
Anchor the .github file alternatives. FUNDING.yml, labeler.yml and membrowse_pr_message.j2 sat inside a group whose only `$` belonged to the workflows/ branch, so they matched as prefixes: .github/labeler.yml.bak and .github/FUNDING.yml.old were classified as metadata and would have selected nothing. No such file exists today - the workflows/ alternative was already anchored and ISSUE_TEMPLATE/ is a directory prefix on purpose. Rule 12b had no test of its own: TestNoTrackedFileIsUnclassified only proved src/typec no longer reaches rule 17, not that the answer is right. TestTypecRule pins it - non-full, every selected example under typec/, all four src/typec files answering alike, no rig board, and the set derived from CFG_TUC_ENABLED rather than hardcoded, so it follows a new typec example on its own. Verified all four fail with rule 12b removed.
-rw-r--r--test/hil/test/test_ci_select.py42
-rwxr-xr-xtools/ci_select.py2
2 files changed, 43 insertions, 1 deletions
diff --git a/test/hil/test/test_ci_select.py b/test/hil/test/test_ci_select.py
index 9b2c61ef2..a19392bde 100644
--- a/test/hil/test/test_ci_select.py
+++ b/test/hil/test/test_ci_select.py
@@ -840,6 +840,48 @@ class TestRostersDoNotOverlap(unittest.TestCase):
seen[b['name']] = b.get('tests')
+class TestTypecRule(unittest.TestCase):
+ """Rule 12b. src/typec/usbc.c is listed unconditionally by src/CMakeLists.txt and
+ src/tinyusb.mk, but its whole body is `#if CFG_TUC_ENABLED`, which only
+ examples/typec/power_delivery sets - so it is parsed by every build and compiled by
+ one. Same shape as the class rule, same answer. Before this rule it matched nothing
+ and force-fulled 82 families and all 30 rig boards."""
+
+ def test_build_axis_selects_only_the_typec_examples(self):
+ s = ci_select.classify_build(['src/typec/usbc.c'], REPO)
+ self.assertFalse(s['full'])
+ self.assertTrue(s['families'], 'typec must be compiled somewhere')
+ self.assertTrue(s['family_examples'], 'and the examples must be named')
+ for fam, exs in s['family_examples'].items():
+ self.assertTrue(exs, fam)
+ for e in exs:
+ self.assertTrue(e.startswith('typec/'), f'{fam}: {e} is not a typec example')
+
+ def test_every_typec_file_answers_the_same(self):
+ for f in ('src/typec/usbc.c', 'src/typec/usbc.h', 'src/typec/tcd.h',
+ 'src/typec/pd_types.h'):
+ s = ci_select.classify_build([f], REPO)
+ self.assertFalse(s['full'], f)
+ self.assertTrue(s['families'], f)
+
+ def test_no_rig_board_runs_typec(self):
+ # typec is not a HIL role, so the rig cannot exercise it whatever it selects
+ s = sel(['src/typec/usbc.c'])
+ self.assertFalse(s['full'])
+ self.assertEqual(s['boards'], {})
+
+ def test_it_tracks_the_enabling_config_rather_than_a_hardcoded_list(self):
+ # the answer must come from CFG_TUC_ENABLED in the example configs, so it
+ # follows a new typec example (or an old one switched off) on its own
+ want = ci_select.examples_enabling(
+ ci_select.role_examples(REPO, ('typec',)), ('CFG_TUC_ENABLED',), REPO)
+ self.assertTrue(want, 'no example enables CFG_TUC_ENABLED - rule 12b is dead')
+ got = set()
+ for exs in ci_select.classify_build(['src/typec/usbc.c'], REPO)['family_examples'].values():
+ got |= set(exs)
+ self.assertEqual(got, want)
+
+
class TestCachesAreKeyedOnTheTree(unittest.TestCase):
"""build_utils caches on repo-RELATIVE paths while ci_select._in_repo() chdirs
between trees, so the cwd has to be part of every cache key. Without it a second
diff --git a/tools/ci_select.py b/tools/ci_select.py
index cf5a0da5b..89a0d214c 100755
--- a/tools/ci_select.py
+++ b/tools/ci_select.py
@@ -75,7 +75,7 @@ _META_RE = re.compile(
r'.*/[0-9]+-tinyusb[^/]*\.rules$|tools/usb_drivers/|tools/codespell/|'
r'test/(fuzz|unit-test)/|'
# .github, minus the build machinery named in _FULL_RE
- r'\.github/(FUNDING\.yml|labeler\.yml|membrowse_pr_message\.j2|ISSUE_TEMPLATE/|'
+ r'\.github/(FUNDING\.yml$|labeler\.yml$|membrowse_pr_message\.j2$|ISSUE_TEMPLATE/|'
r'workflows/(cifuzz|claude|claude-code-review|labeler|membrowse-comment|'
r'membrowse-onboard|pr_comment|pre-commit|static_analysis|trigger)\.yml$)|'
# tools/ scripts no build invokes (tools/build*.py and metrics are handled above)