Skip to content

Commit 6fc1f49

Browse files
ci: Add --skip-version-update option to populate_tox.py (#6675)
Add an option to hold versions back in test suites for a set of integrations. This lets us merge PRs that need `tox.ini` updates even when a version incompatibility would otherwise be pulled in.
1 parent 7ce81ec commit 6fc1f49

1 file changed

Lines changed: 79 additions & 22 deletions

File tree

scripts/populate_tox/populate_tox.py

Lines changed: 79 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
See scripts/populate_tox/README.md for more info.
55
"""
66

7+
import argparse
78
import functools
89
import hashlib
910
import json
@@ -1165,6 +1166,74 @@ def _exit_if_pip_unavailable():
11651166
raise exc
11661167

11671168

1169+
def parse_rendered_python_versions(rendered: str) -> list[ThreadedVersion]:
1170+
rendered = rendered.strip("{}")
1171+
return [
1172+
ThreadedVersion(
1173+
version.removeprefix("py").removesuffix("t"), no_gil=version.endswith("t")
1174+
)
1175+
for version in rendered.split(",")
1176+
]
1177+
1178+
1179+
def get_existing_releases_to_test(integration: str) -> list[PackageVersion]:
1180+
version_pattern = re.compile(
1181+
rf"^\s*(?P<python_versions>\{{[^}}]+\}})-{re.escape(integration)}-v(?P<version>\S+)\s*$"
1182+
)
1183+
releases = {}
1184+
with open(TOX_FILE) as tox_file:
1185+
for line in tox_file:
1186+
match = version_pattern.match(line)
1187+
if match is None:
1188+
continue
1189+
release = PackageVersion(match["version"])
1190+
release.python_versions = parse_rendered_python_versions(
1191+
match["python_versions"]
1192+
)
1193+
release.rendered_python_versions = match["python_versions"]
1194+
releases[release] = release
1195+
1196+
return sorted(releases.values())
1197+
1198+
1199+
def get_releases_to_test(integration, package) -> list[Version] | None:
1200+
# Fetch data for the main package
1201+
pypi_data = fetch_package(package)
1202+
if pypi_data is None:
1203+
print("Failed to fetch necessary data from PyPI. Aborting.")
1204+
sys.exit(1)
1205+
1206+
# Get the list of all supported releases
1207+
releases, latest_prerelease = get_supported_releases(integration, pypi_data)
1208+
1209+
if not releases:
1210+
print(" Found no supported releases.")
1211+
return None
1212+
1213+
_compare_min_version_with_defined(integration, releases)
1214+
1215+
# Pick a handful of the supported releases to actually test against
1216+
# and fetch the PyPI data for each to determine which Python versions
1217+
# to test it on
1218+
test_releases = pick_releases_to_test(integration, releases, latest_prerelease)
1219+
1220+
for release in test_releases:
1221+
_add_python_versions_to_release(integration, package, release)
1222+
1223+
return test_releases
1224+
1225+
1226+
def parse_args() -> argparse.Namespace:
1227+
parser = argparse.ArgumentParser()
1228+
parser.add_argument(
1229+
"--skip-version-update",
1230+
nargs="*",
1231+
default=[],
1232+
help="Integrations to skip version updates for.",
1233+
)
1234+
return parser.parse_args()
1235+
1236+
11681237
def main() -> dict[str, list]:
11691238
"""
11701239
Generate tox.ini from the tox.jinja template.
@@ -1226,6 +1295,9 @@ def main() -> dict[str, list]:
12261295
"_accessed": False,
12271296
}
12281297

1298+
args = parse_args()
1299+
skip_version_updates = set(args.skip_version_update)
1300+
12291301
# Process packages
12301302
packages = defaultdict(list)
12311303

@@ -1236,34 +1308,19 @@ def main() -> dict[str, list]:
12361308

12371309
print(f"Processing {integration}...")
12381310

1239-
# Figure out the actual main package
12401311
package, extra = _get_package_name(integration)
12411312

1242-
# Fetch data for the main package
1243-
pypi_data = fetch_package(package)
1244-
if pypi_data is None:
1245-
print("Failed to fetch necessary data from PyPI. Aborting.")
1246-
sys.exit(1)
1247-
1248-
# Get the list of all supported releases
1249-
1250-
releases, latest_prerelease = get_supported_releases(integration, pypi_data)
1313+
test_releases = None
1314+
if integration in skip_version_updates:
1315+
test_releases = get_existing_releases_to_test(integration)
1316+
else:
1317+
test_releases = get_releases_to_test(integration, package)
12511318

1252-
if not releases:
1253-
print(" Found no supported releases.")
1319+
if test_releases is None:
12541320
continue
12551321

1256-
_compare_min_version_with_defined(integration, releases)
1257-
1258-
# Pick a handful of the supported releases to actually test against
1259-
# and fetch the PyPI data for each to determine which Python versions
1260-
# to test it on
1261-
test_releases = pick_releases_to_test(
1262-
integration, releases, latest_prerelease
1263-
)
1264-
1322+
# Only reads from cache when `integration in skip_version_updates`
12651323
for release in test_releases:
1266-
_add_python_versions_to_release(integration, package, release)
12671324
if not release.python_versions:
12681325
print(f" Release {release} has no Python versions, skipping.")
12691326
continue

0 commit comments

Comments
 (0)