From 7bfcab91ff83988aba7e80506c0574a38432dfca Mon Sep 17 00:00:00 2001 From: OpenIPC AI team Date: Tue, 25 Aug 2026 21:08:13 +0300 Subject: [PATCH] ci: stop a NOT_BUILT device widening the matrix to all of them (#127) NOT_BUILT is documented as the opt-out that narrows to nothing, and a change to one of those devices' defconfigs does exactly that. Anything else in the same directory did the opposite: targets_in() only ever returns devices CI builds, so a directory holding nothing but opted-out devices came back empty and fell through to the "is in no directory CI builds" widen. Touching a device CI deliberately skips cost a full 107-device run. $ echo devices/gk7205v200_rubyfpv_generic/br-ext-chip-goke/board/\ gk7205v200/gk7205v200.generic-fpv.config | python3 .github/scripts/ci-matrix.py --stdin ci-matrix: 107/107 devices (needs_build=True) --- ... is in no directory CI builds $ echo devices/gk7205v200_rubyfpv_generic/br-ext-chip-goke/configs/\ gk7205v200_rubyfpv_generic_defconfig | python3 .github/scripts/ci-matrix.py --stdin ci-matrix: 0/107 devices (needs_build=False) --- nothing that reaches a build Same device, same opt-out, opposite answers. #126 touches three NOT_BUILT devices and is building all 107 because of it. The empty result was carrying two meanings: "every device here is opted out" and "this directory is not one I know". Only the second should widen. devices_in() answers the second question -- it reads directory_of, which is built from every defconfig in the tree rather than the built subset -- so an unrecognised directory still widens, which is the half of the rule worth keeping. Three self-test cases, one per meaning: a kernel config and an overlay file in a NOT_BUILT device reach nothing, and a devices/ directory with no defconfig at all still widens. With this, #126's own file list narrows from 107 to 23. --- .github/scripts/ci-matrix.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/.github/scripts/ci-matrix.py b/.github/scripts/ci-matrix.py index a3f7626..201cdca 100644 --- a/.github/scripts/ci-matrix.py +++ b/.github/scripts/ci-matrix.py @@ -171,6 +171,15 @@ class Tree: """Every built target whose defconfig lives in devices//.""" return [t for t in self.built if self.directory_of[t] == directory] + def devices_in(self, directory): + """Every target in devices//, whether CI builds it or not. + + targets_in() answers "what would this build", which is what narrowing + needs. This answers "is this a directory we know", which is what telling + a deliberate opt-out apart from an unrecognised path needs. + """ + return [t for t in self.directory_of if self.directory_of[t] == directory] + def classify(tree, changed, labels=(), event="pull_request", draft=False): """Map a list of changed paths to {rows, needs_build, reason}.""" @@ -220,6 +229,14 @@ def classify(tree, changed, labels=(), event="pull_request", draft=False): if hits: targets.update(hits) continue + if tree.devices_in(f"devices/{device.group(1)}"): + # The directory is known -- every device in it is in NOT_BUILT. + # Reaching nothing is the whole point of that list, and their + # defconfigs already behave this way, so an overlay or kernel + # config beside one has to as well. Without this the opt-out + # inverts: touching a device CI deliberately skips widens to + # all of them. + continue return _decision(full, True, reason=f"{path} is in no directory CI builds") @@ -382,6 +399,17 @@ def self_test(): # A defconfig CI does not build contributes nothing. (["devices/t31_lite_tp-link-tapo-tc70-v3/br-ext-chip-ingenic/configs/" "t31_lite_tp-link-tapo-tc70-v3_defconfig"], 0, "an unbuilt device"), + # ...and so does anything else in that device's directory. Its kernel + # config is the case that regressed: OpenIPC/builder#126 touched three + # NOT_BUILT devices and got the full 107 for it. + (["devices/gk7205v200_rubyfpv_generic/br-ext-chip-goke/board/gk7205v200/" + "gk7205v200.generic-fpv.config"], 0, "a kernel config in an unbuilt device"), + (["devices/t31_lite_tp-link-tapo-tc70-v3/general/overlay/etc/inittab"], + 0, "an overlay file in an unbuilt device"), + # A directory with no defconfig at all is still unknown, and unknown + # still widens -- that is the half of this rule worth keeping. + (["devices/a-device-that-does-not-exist/br-ext-chip-goke/board/x.config"], + full, "a devices/ directory with no defconfig widens"), # Everything shared or unknown widens. (["builder.sh"], full, "the build script"), (["package/kc110-board-support/Config.in"],