mirror of
https://github.com/pyenv/pyenv.git
synced 2026-01-20 03:27:29 +09:00
CI: automatically check for CPython releases (#3388)
* .gitignore local venv * Add alt GNU mirror support with <table> * Fix UnboundLocalError when no micro 0 releases * Cutoff for existing vetsions as well * add missing dependency more_itertools * workaround fake_useragent 2.0.0 falsely declaring 3.8 compatibility
This commit is contained in:
parent
4cf95be5ee
commit
d9182d6edc
45
.github/workflows/add_version.yml
vendored
Normal file
45
.github/workflows/add_version.yml
vendored
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
name: Add versions
|
||||||
|
|
||||||
|
on:
|
||||||
|
- workflow_dispatch
|
||||||
|
- schedule:
|
||||||
|
# Every N hours
|
||||||
|
- cron: '* */8 * * *'
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
add_cpython:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v6
|
||||||
|
- uses: actions/setup-python@v6
|
||||||
|
with:
|
||||||
|
python-version: 3
|
||||||
|
cache: 'pip'
|
||||||
|
cache-dependency-path: plugins/python-build/scripts/requirements.txt
|
||||||
|
- run: pip install -r plugins/python-build/scripts/requirements.txt
|
||||||
|
|
||||||
|
- name: check for a release
|
||||||
|
run: |
|
||||||
|
python plugins/python-build/scripts/add_cpython.py --verbose >added_versions.lst && rc=$? || rc=$?
|
||||||
|
echo "rc=$rc" >> $GITHUB_ENV
|
||||||
|
- name: set PR properties
|
||||||
|
shell: python
|
||||||
|
run: |
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
versions=[l.rstrip() for l in open("added_versions.lst")]
|
||||||
|
with open(os.environ['GITHUB_ENV'],'a') as f:
|
||||||
|
f.write(f'branch_name=auto_add_version/{"_".join(versions)}\n')
|
||||||
|
f.write(f'pr_name=Add {", ".join(versions)}\n')
|
||||||
|
os.remove("added_versions.lst")
|
||||||
|
|
||||||
|
- name: Create Pull Request
|
||||||
|
uses: peter-evans/create-pull-request@v8
|
||||||
|
if: env.rc == 0
|
||||||
|
with:
|
||||||
|
branch: ${{ env.branch_name }}
|
||||||
|
title: ${{ env.pr_name }}
|
||||||
1
plugins/python-build/scripts/.gitignore
vendored
Normal file
1
plugins/python-build/scripts/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/venv
|
||||||
@ -30,8 +30,6 @@ import tqdm
|
|||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
REPO = "https://www.python.org/ftp/python/"
|
|
||||||
|
|
||||||
CUTOFF_VERSION=packaging.version.Version('3.9')
|
CUTOFF_VERSION=packaging.version.Version('3.9')
|
||||||
EXCLUDED_VERSIONS= {
|
EXCLUDED_VERSIONS= {
|
||||||
packaging.version.Version("3.9.3") #recalled upstream
|
packaging.version.Version("3.9.3") #recalled upstream
|
||||||
@ -126,6 +124,7 @@ def add_version(version: packaging.version.Version):
|
|||||||
|
|
||||||
handle_t_thunks(version, previous_version, is_prerelease_upgrade)
|
handle_t_thunks(version, previous_version, is_prerelease_upgrade)
|
||||||
|
|
||||||
|
print(version)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
@ -170,7 +169,7 @@ def main():
|
|||||||
if v.micro == 0 and v not in VersionDirectory.existing):
|
if v.micro == 0 and v not in VersionDirectory.existing):
|
||||||
# may actually be a prerelease
|
# may actually be a prerelease
|
||||||
VersionDirectory.available.get_store_available_source_downloads(initial_release, True)
|
VersionDirectory.available.get_store_available_source_downloads(initial_release, True)
|
||||||
del initial_release
|
del initial_release
|
||||||
|
|
||||||
versions_to_add = sorted(VersionDirectory.available.keys() - VersionDirectory.existing.keys())
|
versions_to_add = sorted(VersionDirectory.available.keys() - VersionDirectory.existing.keys())
|
||||||
|
|
||||||
@ -294,12 +293,16 @@ class CPythonAvailableVersionsDirectory(KeyedList[_CPythonAvailableVersionInfo,
|
|||||||
super().__init__(seq)
|
super().__init__(seq)
|
||||||
self._session = session
|
self._session = session
|
||||||
|
|
||||||
def populate(self, url=REPO, pattern=r'^\d+'):
|
def populate(self):
|
||||||
"""
|
"""
|
||||||
Fetch remote versions
|
Fetch remote versions
|
||||||
"""
|
"""
|
||||||
logger.info("Fetching available CPython versions")
|
logger.info("Fetching available CPython versions")
|
||||||
for name, url in DownloadPage.enum_download_entries(url, pattern, self._session):
|
for name, url in DownloadPage.enum_download_entries(
|
||||||
|
"https://www.python.org/ftp/python/",
|
||||||
|
r'^(\d+.*)/$', self._session,
|
||||||
|
make_name= lambda m: m.group(1)
|
||||||
|
):
|
||||||
v = packaging.version.Version(name)
|
v = packaging.version.Version(name)
|
||||||
if v < CUTOFF_VERSION or v in EXCLUDED_VERSIONS:
|
if v < CUTOFF_VERSION or v in EXCLUDED_VERSIONS:
|
||||||
continue
|
continue
|
||||||
@ -341,11 +344,13 @@ class CPythonAvailableVersionsDirectory(KeyedList[_CPythonAvailableVersionInfo,
|
|||||||
))
|
))
|
||||||
|
|
||||||
if not exact_download_found:
|
if not exact_download_found:
|
||||||
|
actual_version = max(additional_versions_found.keys())
|
||||||
|
logger.debug(f"Refining available version {version} to {actual_version}")
|
||||||
del self[version]
|
del self[version]
|
||||||
|
|
||||||
self.append(
|
self.append(
|
||||||
additional_versions_found[
|
additional_versions_found[
|
||||||
max(additional_versions_found.keys())
|
actual_version
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
@ -368,6 +373,8 @@ class CPythonExistingScriptsDirectory(KeyedList[_CPythonExistingScriptInfo, pack
|
|||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
v = packaging.version.Version(entry_name)
|
v = packaging.version.Version(entry_name)
|
||||||
|
if v < CUTOFF_VERSION:
|
||||||
|
continue
|
||||||
# branch tip scrpts are different from release scripts and thus unusable as a pattern
|
# branch tip scrpts are different from release scripts and thus unusable as a pattern
|
||||||
if v.dev is not None:
|
if v.dev is not None:
|
||||||
continue
|
continue
|
||||||
@ -488,19 +495,34 @@ class DownloadPage:
|
|||||||
url: str
|
url: str
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def enum_download_entries(cls, url, pattern, session=None) -> typing.Generator[_DownloadPageEntry, None, None]:
|
def enum_download_entries(cls, url, pattern, session=None,
|
||||||
|
make_name = lambda m: m.string ) \
|
||||||
|
-> typing.Generator[_DownloadPageEntry, None, None]:
|
||||||
|
"""
|
||||||
|
Enum download entries in a standard Apache directory page
|
||||||
|
(incl. CPython download page https://www.python.org/ftp/python/)
|
||||||
|
or a GNU mirror directory page
|
||||||
|
(https://ftpmirror.gnu.org/<package>/ destinations)
|
||||||
|
"""
|
||||||
if session is None:
|
if session is None:
|
||||||
session = requests_html.HTMLSession()
|
session = requests_html.HTMLSession()
|
||||||
response = session.get(url)
|
response = session.get(url)
|
||||||
page = response.html
|
page = response.html
|
||||||
table = page.find("pre", first=True)
|
table = page.find("pre", first=True)
|
||||||
# the first entry is ".."
|
# some GNU mirrors format entries as a table
|
||||||
links = table.find("a")[1:]
|
# (e.g. https://mirrors.ibiblio.org/gnu/readline/)
|
||||||
|
if table is None:
|
||||||
|
table = page.find("table", first=True)
|
||||||
|
links = table.find("a")
|
||||||
for link in links:
|
for link in links:
|
||||||
name = link.text.rstrip('/')
|
href = link.attrs['href']
|
||||||
if not re.match(pattern, name):
|
# CPython entries are directories
|
||||||
|
name = link.text
|
||||||
|
# skip directory entries
|
||||||
|
if not (m:=re.match(pattern, name)):
|
||||||
continue
|
continue
|
||||||
yield cls._DownloadPageEntry(name, urllib.parse.urljoin(response.url, link.attrs['href']))
|
name = make_name(m)
|
||||||
|
yield cls._DownloadPageEntry(name, urllib.parse.urljoin(response.url, href))
|
||||||
|
|
||||||
|
|
||||||
class Re:
|
class Re:
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
|
more_itertools
|
||||||
requests-html
|
requests-html
|
||||||
|
fake_useragent<2
|
||||||
lxml[html_clean]
|
lxml[html_clean]
|
||||||
packaging
|
packaging
|
||||||
requests
|
requests
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user