CI: add_cpython: Support prereleases for non-initial CPython releases (#3443)

* CI: add_version: correctly handle exceptions

exit code 1 is used as a signal that no new version is found -- so have to use a different exit code for unhandled exceptions

* CI: add_version: support prereleases for non-initial releases

They unexpectedly made a prerelease 3.14.5rc1

* clarify confusing error message
This commit is contained in:
native-api 2026-05-08 20:20:32 +03:00 committed by GitHub
commit f6a5b409e9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 22 additions and 7 deletions

View File

@ -25,6 +25,8 @@ jobs:
- name: check for a release - name: check for a release
run: | run: |
python plugins/python-build/scripts/add_cpython.py --verbose >added_versions.lst && rc=$? || rc=$? python plugins/python-build/scripts/add_cpython.py --verbose >added_versions.lst && rc=$? || rc=$?
#0 means new version found, 1 not found, 2 another error
[[ $rc -gt 1 ]] && false
echo "rc=$rc" >> $GITHUB_ENV echo "rc=$rc" >> $GITHUB_ENV
- name: set PR properties - name: set PR properties
if: env.rc == 0 if: env.rc == 0

View File

@ -30,6 +30,13 @@ import requests_html
import sortedcontainers import sortedcontainers
import tqdm import tqdm
#CI uses exit code 1 as a signal that no new version is found
#so have to produce a different exit code on an exception
def _excepthook(type,value,traceback):
logging.error("Unhandled exception occured",exc_info=(type,value,traceback))
sys.exit(2)
sys.excepthook = _excepthook
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
CUTOFF_VERSION=packaging.version.Version('3.10') CUTOFF_VERSION=packaging.version.Version('3.10')
@ -192,11 +199,17 @@ def main():
VersionDirectory.existing.populate() VersionDirectory.existing.populate()
VersionDirectory.available.populate() VersionDirectory.available.populate()
for initial_release in (v for v in frozenset(VersionDirectory.available.keys()) # Prereleases are placed under the same directory as the corresponding release.
if v.micro == 0 and v not in VersionDirectory.existing): # So until we know the release is out, its directory is a potential prerelease directory.
# may actually be a prerelease # Normally, prereleases are only made for initial releases (x.y.0) --
VersionDirectory.available.get_store_available_source_downloads(initial_release, True) # but rarely, they may make them for other releases (e.g. 3.14.5).
del initial_release for release in (v for v in frozenset(VersionDirectory.available.keys()) #refining changes the
#corresponding directory key
#which breaks iteration
#so have to iterate over a copy
if v not in VersionDirectory.existing):
VersionDirectory.available.get_store_available_source_downloads(release, True)
del release
versions_to_add = sorted(VersionDirectory.available.keys() - VersionDirectory.existing.keys()) versions_to_add = sorted(VersionDirectory.available.keys() - VersionDirectory.existing.keys())
@ -356,8 +369,8 @@ class CPythonAvailableVersionsDirectory(KeyedList[_CPythonAvailableVersionInfo,
download_version = packaging.version.Version(m.group("version")) download_version = packaging.version.Version(m.group("version"))
if download_version != version: if download_version != version:
if not refine_mode: if not refine_mode:
raise ValueError(f"Unexpectedly found a download {name} for {download_version} " raise ValueError(f"Unexpectedly found a download {name} ({download_version}) "
f"at page {entry.download_page_url} for {version}") f"for {version} at page {entry.download_page_url}")
entry_to_fill = additional_versions_found.get_or_create( entry_to_fill = additional_versions_found.get_or_create(
download_version, download_version,
download_page_url=entry.download_page_url download_page_url=entry.download_page_url