-
Notifications
You must be signed in to change notification settings - Fork 45
/
check_version.py
executable file
·106 lines (83 loc) · 3.62 KB
/
check_version.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#!/usr/bin/env python
# pylint: disable=line-too-long,missing-module-docstring,missing-function-docstring,import-error
# flake8: noqa
import logging
from typing import Dict, List, Optional, Tuple, Set
import requests
from packaging.version import Version, InvalidVersion
ANACONDA_PLATFORMS = {
"linux-64": "amd64",
"linux-aarch64": "arm64",
"linux-ppc64le": "ppc64le",
}
ARCHITECTURES = list(ANACONDA_PLATFORMS.values())
ANACONDA_API_URL = "https://api.anaconda.org/package/conda-forge/micromamba/files"
DOCKERHUB_API_URL = "https://hub.docker.com/v2/repositories/mambaorg/micromamba/tags/?page_size=25&page=1&ordering=last_updated"
ArchVersions = Dict[str, List[Version]]
def to_version(ver: str) -> Version:
"""Converts str to Version"""
return Version(ver)
def anaconda_versions(url: str) -> Dict[str, List[Version]]:
res = requests.get(url)
result = res.json()
out: ArchVersions = {arch: [] for arch in ARCHITECTURES}
for dist in result:
try:
arch = ANACONDA_PLATFORMS[dist["attrs"]["subdir"]]
out[arch].append(to_version(dist["version"]))
except KeyError:
pass
logging.debug("Anaconda versions=%s", out)
return out
def dockerhub_versions(url: str) -> ArchVersions:
dh_res = requests.get(url)
dh_result = dh_res.json()
out: ArchVersions = {arch: [] for arch in ARCHITECTURES}
for release in dh_result["results"]:
version_str = release["name"].split("-")[0]
for image in release["images"]:
arch = image["architecture"]
if arch in ARCHITECTURES:
try:
out[arch].append(to_version(version_str))
except InvalidVersion:
pass
logging.debug("Dockerhub versions=%s", out)
return out
def is_regular_version(ver: Version) -> bool:
"""Check if version is regular (not pre/post-release or dev)"""
return not (ver.is_prerelease or ver.is_postrelease or ver.is_devrelease)
def filter_out_irregular_versions(versions: Set[Version]) -> Set[Version]:
"""Filter out versions that pre/post-release or dev versions"""
return {ver for ver in versions if is_regular_version(ver)}
def max_version_available_for_all_arch(versions: ArchVersions) -> Optional[Version]:
set_per_arch = [set(v) for v in versions.values()]
all_arch_versions = set.intersection(*set_per_arch)
all_regular_arch_versions = filter_out_irregular_versions(all_arch_versions)
try:
return max(all_regular_arch_versions)
except ValueError:
return None
def combined_version_list(versions: ArchVersions) -> List[Version]:
"""Union of versions from all arch"""
set_per_arch = [set(v) for v in versions.values()]
return list(set.union(*set_per_arch))
def get_version_and_build_status() -> Tuple[Optional[Version], bool]:
logging.basicConfig(level=logging.DEBUG)
conda_versions = anaconda_versions(ANACONDA_API_URL)
conda_latest = max_version_available_for_all_arch(conda_versions)
if conda_latest is None:
build_required = False
else:
image_versions_by_arch = dockerhub_versions(DOCKERHUB_API_URL)
image_versions = combined_version_list(image_versions_by_arch)
if image_versions:
build_required = conda_latest not in image_versions and conda_latest > max(image_versions)
else:
build_required = True
logging.debug("conda_latest=%s", conda_latest)
logging.debug("build_required=%s", build_required)
return conda_latest, build_required
if __name__ == "__main__":
version, build = get_version_and_build_status()
print(f"{version},{build}")