Skip to content

Commit e969bf7

Browse files
encukouzware
andauthored
Use a (smart) set of branches for branch selection (GH-752)
Co-authored-by: Zachary Ware <zachary.ware@gmail.com>
1 parent c785159 commit e969bf7

5 files changed

Lines changed: 162 additions & 85 deletions

File tree

master/custom/branches.py

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
1515
"""
1616

17+
import collections.abc
1718
import dataclasses
1819
from functools import total_ordering
1920
from typing import Any
@@ -64,13 +65,6 @@ def _maintenance_branch(major, minor, **kwargs):
6465
# need more time.
6566
result.monolithic_test_asyncio = True
6667

67-
if version_tuple < (3, 11):
68-
# WASM wasn't a supported platform until 3.11.
69-
result.wasm_tier = None
70-
elif version_tuple < (3, 13):
71-
# Tier 3 support is 3.11 & 3.12.
72-
result.wasm_tier = 3
73-
7468
if version_tuple < (3, 13):
7569
# Free-threaded builds are available since 3.13
7670
result.gil_only = True
@@ -96,7 +90,6 @@ class BranchInfo:
9690
# Defaults are for main (and PR), overrides are in _maintenance_branch.
9791
gil_only: bool = False
9892
monolithic_test_asyncio: bool = False
99-
wasm_tier: int | None = 2
10093

10194
def __str__(self):
10295
return self.name
@@ -108,6 +101,9 @@ def __eq__(self, other):
108101
return NotImplemented
109102
return self.sort_key == other.sort_key
110103

104+
def __hash__(self):
105+
return hash(self.sort_key)
106+
111107
def __lt__(self, other):
112108
try:
113109
other_key = other.sort_key
@@ -116,15 +112,58 @@ def __lt__(self, other):
116112
return self.sort_key < other.sort_key
117113

118114

119-
BRANCHES = list(generate_branches())
115+
class BranchSet(collections.abc.Set):
116+
"""An immutable set of BranchInfo objects, with some convenience API"""
117+
118+
def __init__(self, branches):
119+
self._branches = tuple(branches)
120+
121+
def __iter__(self):
122+
return iter(self._branches)
123+
124+
def __len__(self):
125+
return len(self._branches)
126+
127+
def __contains__(self, element):
128+
return element in self._branches
129+
130+
def __getitem__(self, version_tuple):
131+
"""branchset[3, x] -> BranchInfo for 3.x"""
132+
for branch in self._branches:
133+
if branch.version_tuple == version_tuple:
134+
return branch
135+
raise LookupError(f'version {version_tuple} not found')
136+
137+
def only_since(self, major, minor, include_pr=True):
138+
"""only_since(3, x) -> BranchSet with 3.x and later"""
139+
return BranchSet(
140+
b for b in self._branches if (
141+
include_pr if b.is_pr
142+
else b.version_tuple >= (major, minor)
143+
)
144+
)
145+
146+
def only_until(self, major, minor, include_pr=False):
147+
"""only_since(3, x) -> BranchSet with up to (and including) 3.x"""
148+
return BranchSet(
149+
b for b in self._branches if (
150+
include_pr if b.is_pr
151+
else b.version_tuple <= (major, minor)
152+
)
153+
)
154+
155+
156+
BRANCHES = BranchSet(generate_branches())
157+
[MAIN_BRANCH] = [b for b in BRANCHES if b.is_main]
158+
[PR_BRANCH] = [b for b in BRANCHES if b.is_pr]
120159

121-
# Verify that we've defined these in sort order
122-
assert BRANCHES == sorted(BRANCHES)
160+
# Verify that the (sort) keys are distinct
161+
assert len(set(BRANCHES)) == len(list(BRANCHES))
123162

124163
if __name__ == "__main__":
125164
# Print a table to the terminal
126165
cols = [[f.name + ':' for f in dataclasses.fields(BranchInfo)]]
127-
for branch in BRANCHES:
166+
for branch in sorted(BRANCHES):
128167
cols.append([repr(val) for val in dataclasses.astuple(branch)])
129168
column_sizes = [max(len(val) for val in col) for col in cols]
130169
column_sizes[-2] += 2 # PR is special, offset it a bit

master/custom/builders.py

Lines changed: 60 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from functools import cached_property
55

66
from custom import factories
7+
from custom.branches import BRANCHES, MAIN_BRANCH, PR_BRANCH
78
from custom.factories import (
89
UnixBuild,
910
UnixPerfBuild,
@@ -90,11 +91,18 @@ class BuilderDef:
9091
tags: frozenset[str]
9192
worker_name: str
9293

93-
def __init__(self, name, factory, *, tags, worker_name):
94+
def __init__(
95+
self, name, factory,
96+
*,
97+
tags,
98+
worker_name,
99+
branches=BRANCHES,
100+
):
94101
self.name = name
95102
self.factory = factory
96103
self.worker_name = worker_name
97104
self.tags = frozenset(tags)
105+
self.branches = branches
98106

99107
@cached_property
100108
def tier(self):
@@ -146,13 +154,23 @@ def get_tier_from_tags(tags):
146154
factories.Windows64PGOBuild,
147155
tags={STABLE, TIER_1},
148156
worker_name="bolen-windows10",
157+
branches={MAIN_BRANCH, PR_BRANCH},
149158
),
150159
]
151160

152-
def generate_builderdefs(tags, tuples):
161+
def generate_builderdefs(tags, entries):
153162
tags = frozenset(tags)
154-
for name, worker_name, factory in tuples:
155-
yield BuilderDef(name, factory, tags=tags, worker_name=worker_name)
163+
for entry in entries:
164+
if isinstance(entry, BuilderDef):
165+
if not (entry.tags <= tags):
166+
raise ValueError(
167+
f'{entry} is in the wrong generate_builderdefs call; '
168+
+ 'move it to the main BUILDER_DEFS list above',
169+
)
170+
yield entry
171+
else:
172+
name, worker_name, factory = entry
173+
yield BuilderDef(name, factory, tags=tags, worker_name=worker_name)
156174

157175

158176
# -- Stable Tier-1 builder ----------------------------------------------
@@ -181,9 +199,27 @@ def generate_builderdefs(tags, tuples):
181199
("AMD64 Windows11 Non-Debug", "ware-win11", Windows64ReleaseBuild),
182200
("AMD64 Windows11 Refleaks", "ware-win11", Windows64RefleakBuild),
183201
("AMD64 Windows Server 2022 NoGIL", "itamaro-win64-srv-22-aws", Windows64NoGilBuild),
184-
("AMD64 Windows PGO Tailcall", "itamaro-win64-srv-22-aws", Windows64PGOTailcallBuild),
185-
("AMD64 Windows PGO NoGIL", "itamaro-win64-srv-22-aws", Windows64PGONoGilBuild),
186-
("AMD64 Windows PGO NoGIL Tailcall", "itamaro-win64-srv-22-aws", Windows64PGONoGilTailcallBuild),
202+
BuilderDef(
203+
"AMD64 Windows PGO Tailcall",
204+
Windows64PGOTailcallBuild,
205+
tags={STABLE, TIER_1},
206+
worker_name="itamaro-win64-srv-22-aws",
207+
branches={MAIN_BRANCH, PR_BRANCH},
208+
),
209+
BuilderDef(
210+
"AMD64 Windows PGO NoGIL",
211+
Windows64PGONoGilBuild,
212+
tags={STABLE, TIER_1},
213+
worker_name="itamaro-win64-srv-22-aws",
214+
branches={MAIN_BRANCH, PR_BRANCH},
215+
),
216+
BuilderDef(
217+
"AMD64 Windows PGO NoGIL Tailcall",
218+
Windows64PGONoGilTailcallBuild,
219+
tags={STABLE, TIER_1},
220+
worker_name="itamaro-win64-srv-22-aws",
221+
branches={MAIN_BRANCH, PR_BRANCH},
222+
),
187223
]))
188224

189225

@@ -310,7 +346,13 @@ def generate_builderdefs(tags, tuples):
310346
("AMD64 Arch Linux Asan", "pablogsal-arch-x86_64", UnixAsanBuild),
311347
("AMD64 Arch Linux Asan Debug", "pablogsal-arch-x86_64", UnixAsanDebugBuild),
312348
("AMD64 Arch Linux TraceRefs", "pablogsal-arch-x86_64", UnixTraceRefsBuild),
313-
("AMD64 Arch Linux Perf", "pablogsal-arch-x86_64", UnixPerfBuild),
349+
BuilderDef(
350+
"AMD64 Arch Linux Perf",
351+
UnixPerfBuild,
352+
tags={STABLE},
353+
worker_name="pablogsal-arch-x86_64",
354+
branches={MAIN_BRANCH, PR_BRANCH},
355+
),
314356
# UBSAN with -fno-sanitize=function, without which we currently fail (as
315357
# tracked in gh-111178). The full "AMD64 Arch Linux Usan" is unstable, below
316358
("AMD64 Arch Linux Usan Function", "pablogsal-arch-x86_64", ClangUbsanFunctionLinuxBuild),
@@ -345,7 +387,13 @@ def generate_builderdefs(tags, tuples):
345387
("AMD64 CentOS9 FIPS Only Blake2 Builtin Hash", "cstratak-CentOS9-fips-x86_64", CentOS9NoBuiltinHashesUnixBuildExceptBlake2),
346388
("AMD64 CentOS9 FIPS No Builtin Hashes", "cstratak-CentOS9-fips-x86_64", CentOS9NoBuiltinHashesUnixBuild),
347389

348-
("AMD64 Arch Linux Valgrind", "pablogsal-arch-x86_64", ValgrindBuild),
390+
BuilderDef(
391+
"AMD64 Arch Linux Valgrind",
392+
ValgrindBuild,
393+
tags={UNSTABLE, TIER_1},
394+
worker_name="pablogsal-arch-x86_64",
395+
branches={MAIN_BRANCH, PR_BRANCH},
396+
),
349397
]))
350398

351399

@@ -467,15 +515,6 @@ def get_builder_defs(settings):
467515
return BUILDER_DEFS
468516

469517

470-
# Match builder name (excluding the branch name) of builders that should only
471-
# run on the main and PR branches.
472-
ONLY_MAIN_BRANCH = (
473-
"Windows PGO",
474-
"AMD64 Arch Linux Perf",
475-
"AMD64 Arch Linux Valgrind",
476-
)
477-
478-
479518
if __name__ == "__main__":
480519
# Print a list to the terminal
481520
import itertools
@@ -499,3 +538,6 @@ def key(builder_def):
499538
print(f'{NAME}{d.name}{END}')
500539
print(f' {d.factory.__name__} on {d.worker_name}')
501540
print(f' [{' '.join(sorted(d.tags))}]')
541+
if d.branches != BRANCHES:
542+
branchnames = ', '.join(b.name for b in sorted(d.branches))
543+
print(f' branches: {branchnames}')

master/custom/factories.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from buildbot.plugins import util
1111

1212
from . import JUNIT_FILENAME
13+
from .branches import BRANCHES
1314
from .steps import (
1415
Test,
1516
Clean,
@@ -57,6 +58,7 @@ class BaseBuild(factory.BuildFactory):
5758
test_timeout = TEST_TIMEOUT
5859
buildersuffix = ""
5960
tags = ()
61+
branches = BRANCHES
6062

6163
def __init__(self, source, *, extra_tags=[], **kwargs):
6264
super().__init__([source])
@@ -920,6 +922,9 @@ class Wasm32WasiCrossBuild(UnixCrossBuild):
920922
host = "wasm32-unknown-wasi"
921923
host_configure_cmd = ["../../Tools/wasm/wasi-env", "../../configure"]
922924

925+
# See comment in _Wasm32WasiPreview1Build.__init__
926+
branches = {BRANCHES[3, 11], BRANCHES[3, 12]}
927+
923928
def setup(self, branch, worker, test_with_PTY=False, **kwargs):
924929
self.addStep(
925930
SetPropertyFromCommand(
@@ -956,6 +961,14 @@ def __init__(self, source, *, extra_tags=[], **kwargs):
956961
if not self.pydebug:
957962
extra_tags.append("nondebug")
958963
self.buildersuffix += self.append_suffix
964+
if self.pydebug:
965+
# The debug WASI buildbot is meant for 3.11 and 3.12 only.
966+
# Don't use it on PRs; it's tier 3 only and getting it to
967+
# work on PRs against `main` is too much work.
968+
self.branches = {BRANCHES[3, 11], BRANCHES[3, 12]}
969+
else:
970+
# The non-debug buildbot is meant for 3.13+, where WASM is tier 2
971+
self.branches = BRANCHES.only_since(3, 13)
959972
super().__init__(source, extra_tags=extra_tags, **kwargs)
960973

961974
def setup(self, branch, worker, test_with_PTY=False, **kwargs):

0 commit comments

Comments
 (0)