Skip to content
Merged
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
35 changes: 21 additions & 14 deletions .github/release/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,33 @@ The human-maintained release authorities are:
- `requirements/wheel-build.txt` and `requirements/wheel-runtime.txt`: exact
Python dependencies.

Each product selector is a literal Registry-tag keyword such as `0.27.1` or
`0.25.1rc`. A bare keyword expands every legal tag variant containing that
delimited keyword. It does not use PEP 440 normalization, so `0.25.1` does not
match `0.25.1rc` or `0.25.10`. An explicit `keyword@tag` binding such as
`0.25.1rc@nightly-releases-v0.25.1rc-a3` selects only that exact published Tag;
the Tag must contain the keyword. Exact bindings are reported as pinned and are
not expanded. Missing keywords, missing explicit Tags, and selector sets that
Each product selector is a canonical `X.Y` Minor range or an exact `X.Y.Z`
Patch range. Every range is resolved independently from parsed Registry tags:
the selector first chooses the highest available channel in `stable`, `rc`,
`nightly` order, then the highest complete version in that channel, and finally
expands every legal variant of only that version and channel. A newer RC never
displaces a stable version in the same range, and missing variants are never
backfilled from another version or channel.

An explicit `version@tag` binding such as
`0.25@nightly-releases-v0.25.1rc-a3` selects only that exact published Tag. The
Tag must satisfy the product grammar and its parsed version must be inside the
declared Minor or Patch range. The candidate records the Tag's complete version
and actual channel; the pin is not expanded. Overlapping selectors such as
`0.26,0.26.0`, missing ranges, missing explicit Tags, and selector sets that
produce no publishable Runtime fail the release. All four Release Profiles
consume the same selectors; Profiles no longer trim the Runtime matrix. 310P is
filtered and A5 is reported as blocked.
consume the same selectors. After a winning version is chosen, 310P is filtered
and A5 is reported as blocked; neither condition causes fallback.

This keyword rule applies only to `UCM_SUPPORTED_VLLM_VERSIONS` and
`UCM_SUPPORTED_VLLM_ASCEND_VERSIONS`. `UCM_VERSION` remains a canonical PEP
440 package version because it drives Wheel, Chart, and Release coordinates.
These range rules apply only to `UCM_SUPPORTED_VLLM_VERSIONS` and
`UCM_SUPPORTED_VLLM_ASCEND_VERSIONS`. `UCM_VERSION` remains a canonical PEP 440
`X.Y.Z` package version because it drives Wheel, Chart, and Release coordinates.

For example:

```ini
UCM_SUPPORTED_VLLM_VERSIONS=0.26.0,0.27.1,0.28.0
UCM_SUPPORTED_VLLM_ASCEND_VERSIONS=0.24.0rc,0.25.1rc,0.26.0rc
UCM_SUPPORTED_VLLM_VERSIONS=0.26,0.27,0.28
UCM_SUPPORTED_VLLM_ASCEND_VERSIONS=0.23,0.24,0.25,0.26
```

## Registry-only flow
Expand Down
241 changes: 188 additions & 53 deletions .github/release/tests/test_builders.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@
upstream = importlib.import_module("ucm_release.upstream")


def _selector(version: str, tag: str | None = None) -> dict[str, str | None]:
return {
"raw": version if tag is None else f"{version}@{tag}",
"version": version,
"tag": tag,
}


def _policy(release_type: str = "stable") -> dict[str, object]:
resolved = copy.deepcopy(
policy.resolve(
Expand All @@ -29,8 +37,8 @@ def _policy(release_type: str = "stable") -> dict[str, object]:
)
)
selectors = {
"vllm": [{"raw": "0.22.1", "keyword": "0.22.1", "tag": None}],
"vllm-ascend": [{"raw": "0.22.1rc1", "keyword": "0.22.1rc1", "tag": None}],
"vllm": [_selector("0.22.1")],
"vllm-ascend": [_selector("0.22.1")],
}
resolved["runtime_selectors"] = copy.deepcopy(selectors)
for product in resolved["products"]:
Expand Down Expand Up @@ -66,12 +74,12 @@ def _all_keys(value: object) -> set[str]:
return set()


def test_registry_tag_selection_uses_literal_keywords_and_all_variants() -> None:
def test_registry_tag_selection_uses_version_ranges_and_all_winner_variants() -> None:
product = {
"id": "vllm-ascend",
"runtime_selectors": [
{"raw": "0.23.0", "keyword": "0.23.0", "tag": None},
{"raw": "0.24.0rc", "keyword": "0.24.0rc", "tag": None},
_selector("0.23"),
_selector("0.24"),
],
}

Expand Down Expand Up @@ -102,43 +110,31 @@ def test_registry_tag_selection_uses_literal_keywords_and_all_variants() -> None
]


def test_explicit_runtime_tag_is_pinned_without_grammar_or_expansion() -> None:
def test_explicit_runtime_tag_is_range_checked_without_expansion() -> None:
product = {
"id": "vllm",
"runtime_selectors": [
{
"raw": "0.29.0rc@nightly-custom-v0.29.0rc-a3",
"keyword": "0.29.0rc",
"tag": "nightly-custom-v0.29.0rc-a3",
}
],
"runtime_selectors": [_selector("0.29", "v0.29.0rc1-cu129")],
}

assert upstream._select_runtime_tags( # noqa: SLF001
product, ["nightly-custom-v0.29.0rc-a3", "v0.29.0rc0"]
product, ["v0.29.0rc1-cu129", "v0.29.0rc2"]
) == [
{
"runtime_tag": "nightly-custom-v0.29.0rc-a3",
"version": "0.29.0rc",
"channel": "pinned",
"runtime_tag": "v0.29.0rc1-cu129",
"version": "0.29.0rc1",
"channel": "rc",
}
]


def test_explicit_runtime_tag_flows_through_candidate_contract() -> None:
release = _policy()
vllm = next(product for product in release["products"] if product["id"] == "vllm")
vllm["runtime_selectors"] = [
{
"raw": "0.29.0rc@nightly-custom-v0.29.0rc-a3",
"keyword": "0.29.0rc",
"tag": "nightly-custom-v0.29.0rc-a3",
}
]
vllm["runtime_selectors"] = [_selector("0.29", "v0.29.0rc1-cu129")]
tags = {
"docker.io/vllm/vllm-openai": [
"nightly-custom-v0.29.0rc-a3",
"v0.29.0rc0",
"v0.29.0rc1-cu129",
"v0.29.0rc2",
],
"quay.io/ascend/vllm-ascend": ["v0.22.1rc1"],
}
Expand All @@ -150,15 +146,15 @@ def test_explicit_runtime_tag_flows_through_candidate_contract() -> None:
pinned = next(
item for item in candidates["runtimes"] if item["product_id"] == "vllm"
)
assert pinned["runtime_tag"] == "nightly-custom-v0.29.0rc-a3"
assert pinned["version"] == "0.29.0rc"
assert pinned["channel"] == "pinned"
assert pinned["runtime_tag"] == "v0.29.0rc1-cu129"
assert pinned["version"] == "0.29.0rc1"
assert pinned["channel"] == "rc"


def test_keyword_boundaries_do_not_merge_stable_rc_or_patch_versions() -> None:
def test_patch_selector_does_not_merge_rc_or_other_patch_versions() -> None:
product = {
"id": "vllm-ascend",
"runtime_selectors": [{"raw": "0.25.1", "keyword": "0.25.1", "tag": None}],
"runtime_selectors": [_selector("0.25.1")],
}

assert upstream._select_runtime_tags( # noqa: SLF001
Expand All @@ -170,23 +166,111 @@ def test_keyword_boundaries_do_not_merge_stable_rc_or_patch_versions() -> None:
]


def test_minor_selector_prefers_channel_before_newer_version() -> None:
product = {
"id": "vllm-ascend",
"runtime_selectors": [_selector("0.27")],
}

assert upstream._select_runtime_tags( # noqa: SLF001
product,
[
"v0.27.0",
"v0.27.0-a3",
"v0.27.1rc2",
"nightly-releases-v0.27.2rc-a3",
],
) == [
{"runtime_tag": "v0.27.0", "version": "0.27.0", "channel": "stable"},
{
"runtime_tag": "v0.27.0-a3",
"version": "0.27.0",
"channel": "stable",
},
]


def test_minor_selector_uses_highest_rc_and_only_its_variants() -> None:
product = {
"id": "vllm-ascend",
"runtime_selectors": [_selector("0.26")],
}

assert upstream._select_runtime_tags( # noqa: SLF001
product,
[
"v0.26.0rc1",
"v0.26.0rc1-openeuler",
"v0.26.0rc2",
"v0.26.0rc2-a3",
"nightly-releases-v0.26.1rc-a3",
],
) == [
{"runtime_tag": "v0.26.0rc2", "version": "0.26.0rc2", "channel": "rc"},
{
"runtime_tag": "v0.26.0rc2-a3",
"version": "0.26.0rc2",
"channel": "rc",
},
]


def test_minor_selector_uses_highest_nightly_and_only_its_variants() -> None:
product = {
"id": "vllm-ascend",
"runtime_selectors": [_selector("0.25")],
}

assert upstream._select_runtime_tags( # noqa: SLF001
product,
[
"nightly-releases-v0.25.0rc",
"nightly-releases-v0.25.0rc-a3",
"nightly-releases-v0.25.1rc",
"nightly-releases-v0.25.1rc-a3",
"nightly-releases-v0.25.1rc-openeuler",
],
) == [
{
"runtime_tag": "nightly-releases-v0.25.1rc",
"version": "0.25.1rc",
"channel": "nightly",
},
{
"runtime_tag": "nightly-releases-v0.25.1rc-a3",
"version": "0.25.1rc",
"channel": "nightly",
},
{
"runtime_tag": "nightly-releases-v0.25.1rc-openeuler",
"version": "0.25.1rc",
"channel": "nightly",
},
]


@pytest.mark.parametrize(
("selector", "tags", "message"),
[
(
{"raw": "0.27.1", "keyword": "0.27.1", "tag": None},
_selector("0.27.1"),
[],
"contains the keyword",
"matches the version range",
),
(
{"raw": "0.27.1@custom", "keyword": "0.27.1", "tag": "custom"},
_selector("0.27.1", "v0.27.1"),
[],
"not published",
),
(
{"raw": "0.27.1@custom", "keyword": "0.27.1", "tag": "custom"},
_selector("0.27.1", "custom"),
["custom"],
"lacks its keyword",
"does not match product grammar",
),
(
_selector("0.27.1", "v0.28.0"),
["v0.28.0"],
"outside its version range",
),
],
)
Expand All @@ -209,6 +293,65 @@ def test_all_release_profiles_use_the_same_runtime_selectors() -> None:
}


def test_candidate_resolution_selects_each_minor_independently() -> None:
release = _policy()
selectors = {
"vllm": [_selector("0.26"), _selector("0.27")],
"vllm-ascend": [
_selector("0.24"),
_selector("0.25"),
_selector("0.26"),
],
}
for product in release["products"]:
product["runtime_selectors"] = selectors[product["id"]]
tags = {
"docker.io/vllm/vllm-openai": [
"v0.26.0",
"v0.26.1",
"v0.26.1-cu129",
"v0.27.0rc2",
"v0.27.1rc1",
],
"quay.io/ascend/vllm-ascend": [
"nightly-releases-v0.24.0rc",
"nightly-releases-v0.24.0rc-a3",
"nightly-releases-v0.25.0rc",
"nightly-releases-v0.25.1rc",
"nightly-releases-v0.25.1rc-a3",
"v0.26.0rc1",
"v0.26.0rc1-a3",
"nightly-releases-v0.26.1rc-a3",
],
}

candidates = upstream.resolve_runtime_candidates(
release, tag_loader=lambda repository: tags[repository]
)

assert candidates["references"] == [
"docker.io/vllm/vllm-openai:v0.26.1",
"docker.io/vllm/vllm-openai:v0.26.1-cu129",
"docker.io/vllm/vllm-openai:v0.27.1rc1",
"quay.io/ascend/vllm-ascend:nightly-releases-v0.24.0rc",
"quay.io/ascend/vllm-ascend:nightly-releases-v0.24.0rc-a3",
"quay.io/ascend/vllm-ascend:nightly-releases-v0.25.1rc",
"quay.io/ascend/vllm-ascend:nightly-releases-v0.25.1rc-a3",
"quay.io/ascend/vllm-ascend:v0.26.0rc1",
"quay.io/ascend/vllm-ascend:v0.26.0rc1-a3",
]
assert {
(item["product_id"], item["version"], item["channel"])
for item in candidates["runtimes"]
} == {
("vllm", "0.26.1", "stable"),
("vllm", "0.27.1rc1", "rc"),
("vllm-ascend", "0.24.0rc", "nightly"),
("vllm-ascend", "0.25.1rc", "nightly"),
("vllm-ascend", "0.26.0rc1", "rc"),
}


def test_candidates_are_real_registry_tags_and_filter_arch_310p_and_a5() -> None:
candidates = upstream.resolve_runtime_candidates(_policy(), tag_fixture=_fixture())

Expand Down Expand Up @@ -242,36 +385,28 @@ def test_excluded_variant_policy_is_the_runtime_filter_authority() -> None:
assert all("-310p" not in reference for reference in candidates["references"])


def test_newer_excluded_variant_does_not_shadow_supported_runtime() -> None:
def test_excluded_winner_does_not_fall_back_to_an_older_runtime() -> None:
release = _policy()
for product in release["products"]:
product["runtime_selectors"] = [
{"raw": "0.27.0", "keyword": "0.27.0", "tag": None}
]
product["runtime_selectors"] = [_selector("0.27")]
tags = {
"docker.io/vllm/vllm-openai": ["v0.27.0"],
"quay.io/ascend/vllm-ascend": ["v0.27.0", "v0.28.0-310p"],
"quay.io/ascend/vllm-ascend": ["v0.27.0", "v0.27.1-310p"],
}

candidates = upstream.resolve_runtime_candidates(
release, tag_loader=lambda repository: tags[repository]
)

assert candidates["references"] == [
"docker.io/vllm/vllm-openai:v0.27.0",
"quay.io/ascend/vllm-ascend:v0.27.0",
]
with pytest.raises(ValueError, match="winning Runtime version"):
upstream.resolve_runtime_candidates(
release, tag_loader=lambda repository: tags[repository]
)


def test_product_with_only_blocked_variants_fails_selection() -> None:
release = _policy()
for product in release["products"]:
product["runtime_selectors"] = [
{"raw": "0.27.0", "keyword": "0.27.0", "tag": None}
]
product["runtime_selectors"] = [_selector("0.27")]
tags = {
"docker.io/vllm/vllm-openai": ["v0.27.0"],
"quay.io/ascend/vllm-ascend": ["v0.27.0-a5"],
"quay.io/ascend/vllm-ascend": ["v0.27.0", "v0.27.1-a5"],
}

with pytest.raises(ValueError, match="vllm-ascend: no publishable Runtime"):
Expand Down
Loading
Loading