Skip to content

Commit 1723499

Browse files
committed
Keep tagged schema-2 registries readable after backport retirement
Signed-off-by: Ralf W. Grosse-Kunstleve <rgrossekunst@nvidia.com>
1 parent bdb5239 commit 1723499

2 files changed

Lines changed: 93 additions & 1 deletion

File tree

‎ci/tools/bindings_config.py‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,14 +188,25 @@ def _validate_release_statuses(packages: tuple[BindingsPackage, ...]) -> None:
188188

189189

190190
def validate_config(raw: Any) -> BindingsConfig:
191-
root = _mapping(raw, "versions configuration", {"schema_version", "cuda", "python"})
191+
root = _mapping(raw, "versions configuration")
192+
root_keys = {"schema_version", "cuda", "python"}
193+
# Earlier schema-2 release tags retain this field; keep reading their
194+
# registries after the active backport workflow stops using it.
195+
if "backport_branch" in root:
196+
root_keys.add("backport_branch")
197+
_mapping(root, "versions configuration", root_keys)
192198
if type(root["schema_version"]) is not int or root["schema_version"] != SCHEMA_VERSION:
193199
raise BindingsConfigError(f"schema_version must be {SCHEMA_VERSION}")
194200
cuda = _mapping(root["cuda"], "cuda", {"bindings"})
195201
bindings = _mapping(cuda["bindings"], "cuda.bindings", {"package_roots"})
196202
raw_package_roots = _mapping(bindings["package_roots"], "cuda.bindings.package_roots")
197203
packages = tuple(_package(package_root, value) for package_root, value in raw_package_roots.items())
198204
_validate_release_statuses(packages)
205+
if "backport_branch" in root:
206+
maintenance = next(package for package in packages if package.release_status == "maintenance")
207+
expected_branch = f"{maintenance.ctk_target}.x"
208+
if root["backport_branch"] != expected_branch:
209+
raise BindingsConfigError(f"backport_branch must match maintenance CUDA line {expected_branch!r}")
199210
cuda_majors = [package.cuda_major for package in packages]
200211
if len(set(cuda_majors)) != len(cuda_majors):
201212
raise BindingsConfigError("CUDA bindings cuda_major values must be unique")

‎ci/tools/tests/test_bindings_config.py‎

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,47 @@ def test_registry_validation_rejects_invalid_schema_and_release_layout(change, m
133133
validate_config(data)
134134

135135

136+
@pytest.mark.parametrize("toolkit_version", ("12.9.1", "12.8.4"))
137+
@pytest.mark.agent_authored(model="gpt-6.1-sol")
138+
def test_backport_branch_agrees_with_the_maintenance_toolkit_line(toolkit_version):
139+
data = _registry()
140+
data["cuda"]["bindings"]["package_roots"]["cuda_bindings_12"]["toolkit_version"] = toolkit_version
141+
data["backport_branch"] = ".".join(toolkit_version.split(".")[:2]) + ".x"
142+
143+
config = validate_config(data)
144+
145+
assert data["backport_branch"] == f"{config.package_for_release_status('maintenance').ctk_target}.x"
146+
147+
148+
@pytest.mark.parametrize("branch", ("13.4.x", "12.8.x", "12.9", "", None, True))
149+
@pytest.mark.agent_authored(model="gpt-6.1-sol")
150+
def test_registry_rejects_backport_branches_outside_the_maintenance_line(branch):
151+
data = _registry()
152+
data["backport_branch"] = branch
153+
154+
with pytest.raises(BindingsConfigError, match="backport_branch must match maintenance CUDA line '12.9.x'"):
155+
validate_config(data)
156+
157+
158+
@pytest.mark.agent_authored(model="gpt-6.1-sol")
159+
def test_registry_accepts_no_legacy_backport_branch():
160+
data = _registry()
161+
162+
config = validate_config(data)
163+
164+
assert config.package_for_release_status("maintenance").ctk_target == "12.9"
165+
166+
167+
@pytest.mark.agent_authored(model="gpt-6.1-sol")
168+
def test_registry_rejects_unknown_root_fields():
169+
data = _registry()
170+
data["backport_branch"] = "12.9.x"
171+
data["unexpected"] = True
172+
173+
with pytest.raises(BindingsConfigError, match="must contain exactly"):
174+
validate_config(data)
175+
176+
136177
@pytest.mark.agent_authored(model="gpt-6-sol")
137178
def test_registry_rejects_unknown_package_fields():
138179
data = _registry()
@@ -258,6 +299,46 @@ def test_bindings_release_uses_registry_from_its_tag_tree(
258299
}
259300

260301

302+
@pytest.mark.parametrize(
303+
("tag", "package_root", "toolkit_version", "release_version"),
304+
(
305+
("v12.9.8", "tag-maintenance", "12.9.1", "12.9.8"),
306+
("v13.4.2rc1", "tag-current", "13.4.1", "13.4.2rc1"),
307+
("cuda-core-v1.2.0", "tag-current", "13.4.1", None),
308+
("cuda-pathfinder-v1.1.0", "tag-current", "13.4.1", None),
309+
),
310+
)
311+
@pytest.mark.agent_authored(model="gpt-6.1-sol")
312+
def test_release_cli_accepts_tagged_schema_two_registry_with_legacy_backport_branch(
313+
tmp_path, capsys, tag, package_root, toolkit_version, release_version
314+
):
315+
release_root = tmp_path / "release"
316+
registry = _registry("tag-maintenance", "tag-current")
317+
registry["backport_branch"] = "12.9.x"
318+
_write_config(release_root, registry)
319+
control_root = tmp_path / "control"
320+
_write_config(control_root, _registry("control-maintenance", "control-current"))
321+
322+
assert (
323+
main(
324+
[
325+
"--config",
326+
str(control_root / "ci" / "versions.yml"),
327+
"--release-tag",
328+
tag,
329+
"--release-source-root",
330+
str(release_root),
331+
]
332+
)
333+
== 0
334+
)
335+
336+
expected = {"package_root": package_root, "toolkit_version": toolkit_version}
337+
if release_version is not None:
338+
expected["release_version"] = release_version
339+
assert json.loads(capsys.readouterr().out) == expected
340+
341+
261342
@pytest.mark.parametrize("tag", ("cuda-core-v1.2.0", "cuda-pathfinder-v1.1.0"))
262343
@pytest.mark.agent_authored(model="gpt-6-sol")
263344
def test_component_release_uses_current_bindings_from_its_tag_tree(tmp_path, tag):

0 commit comments

Comments
 (0)