mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-08 11:46:35 +00:00
fix(ci): narrow a row's architectures by what its variant deploys
row_architectures intersected the run's pool with the declarations of every role in the complexity closure. That closure follows every conditional provider flag through the base graph, so tor -> web-svc-mirror -> prometheus -> openwebui -> litellm -> lmstudio put the amd64-only lmstudio into the closure of 93 of 128 roles, including the minimal variants that never deploy it. A single amd64 pin would have withdrawn arm64 from nearly the whole matrix. The matrix now replaces a row's services with the include set that plan_dev_inventory_matrix, the planner the deploy step itself uses, resolves for that variant. Against CI run 35674334334 it matches every data point: lmstudio for zammad#2, moodle#2 and xwiki#2, which pulled it on arm64, and not for docs#0 or legal#0, which did not. With the pins of the next commit, 126 of 128 roles keep arm64 rows instead of 34. Without any architecture declaration the emitted matrix is byte-identical to before under a fixed discovery seed. The planner adds about 37 s per matrix build, and a role whose plan errors now stops the matrix instead of only its own deploy job. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
fa7eba3771
commit
c7fb6e60c5
5 files changed
+63
-10
No files matched your search
@@ -204,7 +204,7 @@ entity, next to `modes`:
|
||||
```
|
||||
|
||||
The row then draws from that intersection instead of the run's whole pool, and
|
||||
so does every row whose transitive service closure contains that role. A
|
||||
so does every row whose variant deploys that role, as the deploy planner resolves it. A
|
||||
role and a run that permit nothing in common abort the matrix rather than
|
||||
dropping the row.
|
||||
|
||||
|
||||
+32
-6
@@ -29,12 +29,17 @@ passing state between them.
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import functools
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
from cli.administration.deploy.development.inventory.planner import (
|
||||
plan_dev_inventory_matrix,
|
||||
)
|
||||
from cli.meta.ci import chunks, query, slots
|
||||
from utils.cache.applications import get_variants
|
||||
from utils.cache.files import PROJECT_ROOT
|
||||
from utils.github.variant import axes, instructions, pools, selection, tor
|
||||
from utils.roles.display import display_names
|
||||
|
||||
@@ -81,6 +86,24 @@ def candidates(
|
||||
return [{**row, "modes": query.row_modes(row, modes)} for row in rows]
|
||||
|
||||
|
||||
@functools.cache
|
||||
def deployed_rounds(app: str) -> tuple[tuple[str, ...], ...]:
|
||||
"""The apps each variant round of *app* deploys."""
|
||||
return tuple(
|
||||
include
|
||||
for _index, _dir, _variants, include, _purge in plan_dev_inventory_matrix(
|
||||
roles_dir=str(PROJECT_ROOT / "roles"),
|
||||
primary_apps=[app],
|
||||
base_inventory_dir="plan",
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def with_deployed_services(row: dict) -> dict:
|
||||
"""*row* with ``services`` narrowed to what its variant deploys."""
|
||||
return {**row, "services": deployed_rounds(row["name"])[row.get("variant") or 0]}
|
||||
|
||||
|
||||
def entries_of(
|
||||
*,
|
||||
modes: tuple[str, ...],
|
||||
@@ -95,12 +118,15 @@ def entries_of(
|
||||
) -> list[dict[str, str]]:
|
||||
"""Every candidate row of the sweep, axes assigned, in global order."""
|
||||
return axes.assign(
|
||||
candidates(
|
||||
modes=modes,
|
||||
whitelist=whitelist,
|
||||
priority=priority,
|
||||
lifecycles=lifecycles,
|
||||
),
|
||||
[
|
||||
with_deployed_services(row)
|
||||
for row in candidates(
|
||||
modes=modes,
|
||||
whitelist=whitelist,
|
||||
priority=priority,
|
||||
lifecycles=lifecycles,
|
||||
)
|
||||
],
|
||||
sweep=sweep,
|
||||
tor_mode=tor_mode,
|
||||
distros=distros,
|
||||
|
||||
@@ -58,8 +58,8 @@ machine, not just a value the job applies to itself.
|
||||
.architectures` lists what the role can run on, next to `modes`, because both
|
||||
state a capability rather than a testing preference. The row draws from the
|
||||
intersection of the run's pool with the declarations of the role and of every
|
||||
service in its transitive closure, because the deploy pulls those in too; an
|
||||
empty intersection aborts the matrix.
|
||||
role the deploy planner brings up for that variant, because the deploy pulls
|
||||
those in too; an empty intersection aborts the matrix.
|
||||
|
||||
- **CI images are built natively per architecture and published as one tag per
|
||||
distro.** Each architecture builds on its own runner, and
|
||||
|
||||
@@ -192,5 +192,32 @@ class TestCandidates(unittest.TestCase):
|
||||
self.assertEqual(discovered.call_args.kwargs["blacklist"], "web-app-b")
|
||||
|
||||
|
||||
class TestWithDeployedServices(unittest.TestCase):
|
||||
def setUp(self) -> None:
|
||||
matrix.deployed_rounds.cache_clear()
|
||||
self.addCleanup(matrix.deployed_rounds.cache_clear)
|
||||
|
||||
def test_each_variant_takes_the_apps_its_own_round_deploys(self) -> None:
|
||||
plan = [
|
||||
(0, "plan-0", {}, ("web-app-a", "svc-db-postgres"), ()),
|
||||
(1, "plan-1", {}, ("web-app-a", "svc-ai-lmstudio"), ()),
|
||||
]
|
||||
with mock.patch.object(
|
||||
matrix, "plan_dev_inventory_matrix", return_value=plan
|
||||
) as planner:
|
||||
rows = [
|
||||
matrix.with_deployed_services(
|
||||
{"name": "web-app-a", "variant": variant, "services": ["x"]}
|
||||
)
|
||||
for variant in (0, 1)
|
||||
]
|
||||
|
||||
self.assertEqual(
|
||||
[row["services"] for row in rows],
|
||||
[("web-app-a", "svc-db-postgres"), ("web-app-a", "svc-ai-lmstudio")],
|
||||
)
|
||||
planner.assert_called_once()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -209,7 +209,7 @@ def row_architectures(
|
||||
Args:
|
||||
app: role id, read for its ``meta/services.yml`` declaration.
|
||||
run_pool: what the run permits, already narrowed by its own input.
|
||||
services: the row's transitive service closure, each narrowing the
|
||||
services: the roles the row's variant deploys, each narrowing the
|
||||
row like the role's own declaration.
|
||||
|
||||
Raises:
|
||||
|
||||
Reference in new issue
Block a user