Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion tests/rig/selection.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
The literal ``all`` expands to every group in the manifest. When the result is
empty, callers should treat that as "do nothing" rather than silently running
everything — the CLI surfaces a clear error.

With ``--tier``, dep expansion never reaches outside that tier: each tier runs as
its own CI leg, so a cross-tier ``depends_on`` would otherwise re-run the same
group in every leg that transitively depends on it.
"""

from __future__ import annotations
Expand Down Expand Up @@ -66,7 +70,18 @@ def resolve(
if changed_only:
selected.update(_groups_for_changed_paths(manifest, base=changed_base))

return manifest.expand(sorted(selected)) if selected else []
if not selected:
return []

requested = sorted(selected)
expanded = manifest.expand(requested)
if tier is not None:
# A tier run never pulls in another tier's groups. Tiers run as separate
# legs, so a cross-tier `depends_on` would re-run the same group once per
# leg; the owning tier's leg covers it. Explicitly requested groups stay.
keep = set(requested)
expanded = [n for n in expanded if n in keep or manifest.get(n).tier == tier]
return expanded


def _groups_for_changed_paths(manifest: GroupManifest, *, base: str) -> set[str]:
Expand Down
48 changes: 48 additions & 0 deletions tests/rig/tests/test_selection.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,51 @@ def test_tier_only_selects_that_tier_and_deps(tmp_path: Path) -> None:
manifest = load_groups(_manifest(tmp_path))
ordered = resolve(manifest, positional=[], tier="unit")
assert set(ordered) == {"unit-a", "unit-b"}


def _cross_tier_manifest(tmp_path: Path) -> Path:
p = tmp_path / "groups.yaml"
p.write_text(
"""
version: 1
groups:
unit-a:
tier: unit
paths: [x]
optional: true
e2e-smoke:
tier: e2e
paths: [x]
requires_platform: true
optional: true
e2e-cross:
tier: e2e
paths: [x]
requires_platform: true
depends_on: [e2e-smoke, unit-a]
optional: true
"""
)
return p


def test_tier_run_does_not_pull_in_other_tiers(tmp_path: Path) -> None:
"""Each tier is its own CI leg; a cross-tier dep must not re-run there."""
manifest = load_groups(_cross_tier_manifest(tmp_path))
ordered = resolve(manifest, positional=[], tier="e2e")
assert set(ordered) == {"e2e-smoke", "e2e-cross"}
# Intra-tier ordering still holds.
assert ordered.index("e2e-smoke") < ordered.index("e2e-cross")


def test_explicitly_named_group_survives_tier_filter(tmp_path: Path) -> None:
"""The filter only drops dep-expanded groups, never an explicit request."""
manifest = load_groups(_cross_tier_manifest(tmp_path))
ordered = resolve(manifest, positional=["unit-a"], tier="e2e")
assert set(ordered) == {"unit-a", "e2e-smoke", "e2e-cross"}


def test_cross_tier_dep_still_expands_without_tier_filter(tmp_path: Path) -> None:
manifest = load_groups(_cross_tier_manifest(tmp_path))
ordered = resolve(manifest, positional=["e2e-cross"])
assert set(ordered) == {"unit-a", "e2e-smoke", "e2e-cross"}