Skip to content

Commit f963475

Browse files
sentrivanaclaude
andauthored
tests: Add -latest alias for each integration test suite (#5706)
## Summary - For every auto-generated integration, adds a tox environment that aliases the highest tested version (e.g. `tox -e py3.14-httpx-latest` = `tox -e py3.14-httpx-v0.28.1`) - Makes it easy to run tests against the latest version without looking up exact version strings ## Notes - The new latest env is NOT run in CI - The new latest env points to the highest non-prerelease env --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 715fd2b commit f963475

File tree

5 files changed

+190
-1
lines changed

5 files changed

+190
-1
lines changed

scripts/populate_tox/populate_tox.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,31 @@ def _render_dependencies(integration: str, releases: list[Version]) -> list[str]
724724
return rendered
725725

726726

727+
def _render_latest_dependencies(
728+
integration: str, latest_release: Version
729+
) -> list[str]:
730+
"""Render version-specific dependencies for the 'latest' alias.
731+
732+
Dependencies with "*" or "py3.*" constraints already match the latest
733+
env via tox factor matching, so only version-specific constraints need
734+
to be duplicated here.
735+
"""
736+
rendered = []
737+
738+
if TEST_SUITE_CONFIG[integration].get("deps") is None:
739+
return rendered
740+
741+
for constraint, deps in TEST_SUITE_CONFIG[integration]["deps"].items():
742+
if constraint == "*" or constraint.startswith("py3"):
743+
continue
744+
restriction = SpecifierSet(constraint, prereleases=True)
745+
if latest_release in restriction:
746+
for dep in deps:
747+
rendered.append(f"{integration}-latest: {dep}")
748+
749+
return rendered
750+
751+
727752
def write_tox_file(packages: dict) -> None:
728753
template = ENV.get_template("tox.jinja")
729754

@@ -735,15 +760,30 @@ def write_tox_file(packages: dict) -> None:
735760
for group, integrations in packages.items():
736761
context["groups"][group] = []
737762
for integration in integrations:
763+
# Find the highest stable (non-prerelease) release for the
764+
# -latest alias. Prereleases are always appended last by
765+
# pick_releases_to_test, so we walk backwards.
766+
latest_stable = None
767+
for rel in reversed(integration["releases"]):
768+
if not rel.is_prerelease:
769+
latest_stable = rel
770+
break
771+
738772
context["groups"][group].append(
739773
{
740774
"name": integration["name"],
741775
"package": integration["package"],
742776
"extra": integration["extra"],
743777
"releases": integration["releases"],
778+
"latest_stable": latest_stable,
744779
"dependencies": _render_dependencies(
745780
integration["name"], integration["releases"]
746781
),
782+
"latest_dependencies": _render_latest_dependencies(
783+
integration["name"], latest_stable
784+
)
785+
if latest_stable
786+
else [],
747787
}
748788
)
749789
context["testpaths"].append(

scripts/populate_tox/tox.jinja

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ envlist =
6161
{% for release in integration.releases %}
6262
{{ release.rendered_python_versions }}-{{ integration.name }}-v{{ release }}
6363
{% endfor %}
64+
{% if integration.latest_stable %}
65+
{{ integration.latest_stable.rendered_python_versions }}-{{ integration.name }}-latest
66+
{% endif %}
6467

6568
{% endfor %}
6669

@@ -143,9 +146,19 @@ deps =
143146
{{ integration.name }}-v{{ release }}: {{ integration.package }}=={{ release }}
144147
{% endif %}
145148
{% endfor %}
149+
{% if integration.latest_stable %}
150+
{% if integration.extra %}
151+
{{ integration.name }}-latest: {{ integration.package }}[{{ integration.extra }}]=={{ integration.latest_stable }}
152+
{% else %}
153+
{{ integration.name }}-latest: {{ integration.package }}=={{ integration.latest_stable }}
154+
{% endif %}
155+
{% endif %}
146156
{% for dep in integration.dependencies %}
147157
{{ dep }}
148158
{% endfor %}
159+
{% for dep in integration.latest_dependencies %}
160+
{{ dep }}
161+
{% endfor %}
149162
150163
{% endfor %}
151164

scripts/runtox.sh

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,12 @@ fi
1515

1616
searchstring="$1"
1717

18-
ENV="$($TOXPATH -l | grep -- "$searchstring" | tr $'\n' ',')"
18+
# Filter out -latest environments unless explicitly requested
19+
if [[ "$searchstring" == *-latest* ]]; then
20+
ENV="$($TOXPATH -l | grep -- "$searchstring" | tr $'\n' ',')"
21+
else
22+
ENV="$($TOXPATH -l | grep -- "$searchstring" | grep -v -- '-latest$' | tr $'\n' ',')"
23+
fi
1924

2025
if [ -z "${ENV}" ]; then
2126
echo "No targets found. Skipping."

scripts/split_tox_gh_actions/split_tox_gh_actions.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,11 @@ def parse_tox():
240240
raw_python_versions = groups["py_versions"]
241241
framework = groups["framework"]
242242

243+
# The -latest env is an alias for the highest version of the
244+
# same framework, so merge it with the base framework.
245+
if framework.endswith("-latest"):
246+
framework = framework[: -len("-latest")]
247+
243248
# collect python versions to test the framework in
244249
raw_python_versions = set(raw_python_versions.split(","))
245250
py_versions[framework] |= raw_python_versions

0 commit comments

Comments
 (0)