142 lines
5.1 KiB
Python
Executable File
142 lines
5.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
from __future__ import annotations
|
|
|
|
import configparser
|
|
import os
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
from typing import NamedTuple
|
|
|
|
import requests
|
|
|
|
os.chdir(os.path.dirname(__file__))
|
|
os.chdir('..')
|
|
|
|
# CUSTOM_COMPILE_COMMAND is a pip-compile option that tells users how to
|
|
# regenerate the constraints files
|
|
os.environ['CUSTOM_COMPILE_COMMAND'] = "bin/update_dependencies.py"
|
|
|
|
PYTHON_VERSIONS = ['27', '35', '36', '37', '38', '39']
|
|
|
|
if '--no-docker' in sys.argv:
|
|
for python_version in PYTHON_VERSIONS:
|
|
subprocess.run([
|
|
f'./env{python_version}/bin/pip-compile',
|
|
'--allow-unsafe',
|
|
'--upgrade',
|
|
'cibuildwheel/resources/constraints.in',
|
|
'--output-file=cibuildwheel/resources/constraints-python{python_version}.txt',
|
|
], check=True)
|
|
else:
|
|
# latest manylinux2010 image with cpython 2.7 support
|
|
image_runner = 'quay.io/pypa/manylinux2010_x86_64:2021-02-06-3d322a5'
|
|
subprocess.run(['docker', 'pull', image_runner], check=True)
|
|
for python_version in PYTHON_VERSIONS:
|
|
abi_flags = '' if int(python_version) >= 38 else 'm'
|
|
python_path = f'/opt/python/cp{python_version}-cp{python_version}{abi_flags}/bin/'
|
|
command = (
|
|
f'{python_path}pip install pip-tools && '
|
|
'{python_path}pip-compile --allow-unsafe --upgrade '
|
|
'cibuildwheel/resources/constraints.in '
|
|
f'--output-file cibuildwheel/resources/constraints-python{python_version}.txt'
|
|
)
|
|
subprocess.run([
|
|
'docker', 'run',
|
|
'--rm',
|
|
'--env=CUSTOM_COMPILE_COMMAND',
|
|
"--volume={os.getcwd()}:/volume",
|
|
'--workdir=/volume',
|
|
image_runner,
|
|
'bash', '-c',
|
|
command,
|
|
], check=True)
|
|
|
|
# default constraints.txt
|
|
shutil.copyfile(f'cibuildwheel/resources/constraints-python{PYTHON_VERSIONS[-1]}.txt', 'cibuildwheel/resources/constraints.txt',)
|
|
|
|
|
|
class Image(NamedTuple):
|
|
manylinux_version: str
|
|
platform: str
|
|
image_name: str
|
|
tag: str | None
|
|
|
|
|
|
images = [
|
|
Image('manylinux1', 'x86_64', 'quay.io/pypa/manylinux1_x86_64', None),
|
|
Image('manylinux1', 'i686', 'quay.io/pypa/manylinux1_i686', None),
|
|
|
|
# Images for manylinux2010 are pinned to the latest tag supporting cp27
|
|
Image('manylinux2010', 'x86_64', 'quay.io/pypa/manylinux2010_x86_64', '2021-02-06-3d322a5'),
|
|
Image('manylinux2010', 'i686', 'quay.io/pypa/manylinux2010_i686', '2021-02-06-3d322a5'),
|
|
|
|
Image('manylinux2010', 'pypy_x86_64', 'pypywheels/manylinux2010-pypy_x86_64', None),
|
|
|
|
# 2014 images
|
|
Image('manylinux2014', 'x86_64', 'quay.io/pypa/manylinux2014_x86_64', None),
|
|
Image('manylinux2014', 'i686', 'quay.io/pypa/manylinux2014_i686', None),
|
|
Image('manylinux2014', 'aarch64', 'quay.io/pypa/manylinux2014_aarch64', None),
|
|
Image('manylinux2014', 'ppc64le', 'quay.io/pypa/manylinux2014_ppc64le', None),
|
|
Image('manylinux2014', 's390x', 'quay.io/pypa/manylinux2014_s390x', None),
|
|
|
|
# 2_24 images
|
|
Image('manylinux_2_24', 'x86_64', 'quay.io/pypa/manylinux_2_24_x86_64', None),
|
|
Image('manylinux_2_24', 'i686', 'quay.io/pypa/manylinux_2_24_i686', None),
|
|
Image('manylinux_2_24', 'aarch64', 'quay.io/pypa/manylinux_2_24_aarch64', None),
|
|
Image('manylinux_2_24', 'ppc64le', 'quay.io/pypa/manylinux_2_24_ppc64le', None),
|
|
Image('manylinux_2_24', 's390x', 'quay.io/pypa/manylinux_2_24_s390x', None),
|
|
]
|
|
|
|
config = configparser.ConfigParser()
|
|
|
|
for image in images:
|
|
# get the tag name whose digest matches 'latest'
|
|
if image.tag is not None:
|
|
# image has been pinned, do not update
|
|
tag_name = image.tag
|
|
elif image.image_name.startswith('quay.io/'):
|
|
_, _, repository_name = image.image_name.partition('/')
|
|
response = requests.get(
|
|
f'https://quay.io/api/v1/repository/{repository_name}?includeTags=true'
|
|
)
|
|
response.raise_for_status()
|
|
repo_info = response.json()
|
|
tags_dict = repo_info['tags']
|
|
|
|
latest_tag = tags_dict.pop('latest')
|
|
# find the tag whose manifest matches 'latest'
|
|
tag_name = next(
|
|
name
|
|
for (name, info) in tags_dict.items()
|
|
if info['manifest_digest'] == latest_tag['manifest_digest']
|
|
)
|
|
else:
|
|
response = requests.get(
|
|
f'https://hub.docker.com/v2/repositories/{image.image_name}/tags'
|
|
)
|
|
response.raise_for_status()
|
|
tags = response.json()['results']
|
|
|
|
latest_tag = next(
|
|
tag for tag in tags if tag['name'] == 'latest'
|
|
)
|
|
# i don't know what it would mean to have multiple images per tag
|
|
assert len(latest_tag['images']) == 1
|
|
digest = latest_tag['images'][0]['digest']
|
|
|
|
pinned_tag = next(
|
|
tag
|
|
for tag in tags
|
|
if tag != latest_tag and tag['images'][0]['digest'] == digest
|
|
)
|
|
tag_name = pinned_tag['name']
|
|
|
|
if not config.has_section(image.platform):
|
|
config[image.platform] = {}
|
|
|
|
config[image.platform][image.manylinux_version] = f'{image.image_name}:{tag_name}'
|
|
|
|
with open('cibuildwheel/resources/pinned_docker_images.cfg', 'w') as f:
|
|
config.write(f)
|