From f7be5180a8157ebaf91274fe84b9e862565e115a Mon Sep 17 00:00:00 2001 From: Max Pfeiffer Date: Sun, 2 Jul 2023 02:03:14 +0200 Subject: [PATCH 01/13] Added a working build config with buildx bake --- build/constants.py | 4 + build/docker-bake.hcl | 35 +++ build/images.py | 32 +- build/publish.py | 2 +- build/utils.py | 10 + poetry.lock | 372 ++++++++++++++++++++--- pyproject.toml | 4 + tests/build_image/conftest.py | 83 ++++- tests/build_image/test_build_version.py | 9 +- tests/build_image/test_poetry_version.py | 29 +- tests/build_image/test_python_version.py | 29 +- tests/conftest.py | 21 +- tests/constants.py | 14 + tests/publish_image/test_cli.py | 20 +- tests/publish_image/test_env.py | 20 +- tests/utils.py | 61 +++- 16 files changed, 598 insertions(+), 147 deletions(-) create mode 100644 build/docker-bake.hcl create mode 100644 build/utils.py diff --git a/build/constants.py b/build/constants.py index e2d6ac7..def8b91 100644 --- a/build/constants.py +++ b/build/constants.py @@ -115,3 +115,7 @@ TARGET_ARCHITECTURES[16]: "1.5.0", TARGET_ARCHITECTURES[17]: "1.5.0", } +PLATFORMS: list[str] = [ + "linux/amd64", + "linux/arm64", +] diff --git a/build/docker-bake.hcl b/build/docker-bake.hcl new file mode 100644 index 0000000..96dcd93 --- /dev/null +++ b/build/docker-bake.hcl @@ -0,0 +1,35 @@ +variable "REGISTRY" { + default = null +} + +variable "IMAGE_VERSION" { + default = null +} + +variable "IMAGE_NAME" { + default = "pfeiffermax/python-poetry" +} + +variable "CONTEXT" { + default = "." +} + +target "python-poetry" { + name = "poetry${replace(poetry_version, ".", "-")}-python${replace(python_version, ".", "-")}-${os_variant}" + context = CONTEXT + + matrix = { + python_version = ["3.9.16", "3.10.11", "3.11.3"] + os_variant = ["bullseye", "slim-bullseye"] + poetry_version = ["1.3.2", "1.4.2", "1.5.1"] + } + + args = { + POETRY_VERSION = poetry_version + OFFICIAL_PYTHON_IMAGE = "python:${python_version}-${os_variant}" + } + + platforms = ["linux/amd64", "linux/arm64"] + + tags = ["${REGISTRY}/${IMAGE_NAME}:${IMAGE_VERSION}-poetry${poetry_version}-python${python_version}-${os_variant}"] +} \ No newline at end of file diff --git a/build/images.py b/build/images.py index 6baaaeb..60dfb4e 100644 --- a/build/images.py +++ b/build/images.py @@ -1,9 +1,9 @@ from pathlib import Path from typing import Optional -from docker.models.images import Image -from docker.client import DockerClient +from python_on_whales import DockerClient, Builder, Image from build.constants import ( + PLATFORMS, PYTHON_POETRY_IMAGE_NAME, BASE_IMAGES, POETRY_VERSIONS, @@ -14,10 +14,12 @@ class DockerImage: def __init__( self, docker_client: DockerClient, + builder: Builder, target_architecture: str, version: str, ): self.docker_client: DockerClient = docker_client + self.builder: Builder = builder self.dockerfile_name: str = "Dockerfile" self.image_name: Optional[str] = None self.image_tag: Optional[str] = None @@ -29,17 +31,18 @@ class PythonPoetryImage(DockerImage): def __init__( self, docker_client: DockerClient, + builder: Builder, target_architecture: str, version: str, ): - super().__init__(docker_client, target_architecture, version) + super().__init__(docker_client, builder, target_architecture, version) self.dockerfile_directory: Path = Path(__file__).parent.resolve() # An image name is made up of slash-separated name components, optionally prefixed by a registry hostname. # see: https://docs.docker.com/engine/reference/commandline/tag/ self.image_name = PYTHON_POETRY_IMAGE_NAME - def build(self) -> Image: + def build(self) -> Optional[Image]: self.image_tag = f"{self.version}-{self.target_architecture}" buildargs: dict[str, str] = { @@ -47,10 +50,19 @@ def build(self) -> Image: "POETRY_VERSION": POETRY_VERSIONS[self.target_architecture], } - image: Image = self.docker_client.images.build( - path=str(self.dockerfile_directory), - dockerfile=self.dockerfile_name, - tag=f"{self.image_name}:{self.image_tag}", - buildargs=buildargs, - )[0] + # image: Image = self.docker_client.images.build( + # path=str(self.dockerfile_directory), + # dockerfile=self.dockerfile_name, + # tag=f"{self.image_name}:{self.image_tag}", + # buildargs=buildargs, + # )[0] + + image: Image = self.docker_client.buildx.build( + context_path=str(self.dockerfile_directory), + tags=f"{self.image_name}:{self.image_tag}", + build_args=buildargs, + platforms=PLATFORMS, + builder=self.builder, + ) + return image diff --git a/build/publish.py b/build/publish.py index 5110934..d8200b6 100644 --- a/build/publish.py +++ b/build/publish.py @@ -34,7 +34,7 @@ def main( for target_architecture in TARGET_ARCHITECTURES: new_python_poetry_image: PythonPoetryImage = PythonPoetryImage( - docker_client, target_architecture, version_tag + docker_client, None, target_architecture, version_tag ) # Delete old existing images diff --git a/build/utils.py b/build/utils.py new file mode 100644 index 0000000..d4dddc8 --- /dev/null +++ b/build/utils.py @@ -0,0 +1,10 @@ +from pathlib import Path + + +def get_context() -> Path: + return Path(__file__).parent.resolve() + + +def get_docker_bake_file() -> Path: + docker_bake_file: Path = Path(__file__).parent.resolve() / "docker-bake.hcl" + return docker_bake_file diff --git a/poetry.lock b/poetry.lock index 9849aa8..baeba1b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,9 +1,10 @@ -# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand. [[package]] name = "astroid" version = "2.15.5" description = "An abstract syntax tree for Python with inference support." +category = "dev" optional = false python-versions = ">=3.7.2" files = [ @@ -20,6 +21,7 @@ wrapt = {version = ">=1.11,<2", markers = "python_version < \"3.11\""} name = "bcrypt" version = "4.0.1" description = "Modern password hashing for your software and your servers" +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -54,6 +56,7 @@ typecheck = ["mypy"] name = "black" version = "23.3.0" description = "The uncompromising code formatter." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -103,6 +106,7 @@ uvloop = ["uvloop (>=0.15.2)"] name = "certifi" version = "2023.5.7" description = "Python package for providing Mozilla's CA Bundle." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -114,6 +118,7 @@ files = [ name = "cfgv" version = "3.3.1" description = "Validate configuration and produce human readable error messages." +category = "dev" optional = false python-versions = ">=3.6.1" files = [ @@ -125,6 +130,7 @@ files = [ name = "charset-normalizer" version = "3.1.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -209,6 +215,7 @@ files = [ name = "click" version = "8.1.3" description = "Composable command line interface toolkit" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -223,6 +230,7 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -234,6 +242,7 @@ files = [ name = "coverage" version = "7.2.7" description = "Code coverage measurement for Python" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -309,6 +318,7 @@ toml = ["tomli"] name = "deprecation" version = "2.1.0" description = "A library to handle automated deprecations" +category = "dev" optional = false python-versions = "*" files = [ @@ -323,6 +333,7 @@ packaging = "*" name = "dill" version = "0.3.6" description = "serialize all of python" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -337,6 +348,7 @@ graph = ["objgraph (>=1.7.2)"] name = "distlib" version = "0.3.6" description = "Distribution utilities" +category = "dev" optional = false python-versions = "*" files = [ @@ -348,6 +360,7 @@ files = [ name = "docker" version = "6.1.3" description = "A Python library for the Docker Engine API." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -365,10 +378,26 @@ websocket-client = ">=0.32.0" [package.extras] ssh = ["paramiko (>=2.4.3)"] +[[package]] +name = "docker-image-py" +version = "0.1.12" +description = "Parse docker image as distribution does." +category = "dev" +optional = false +python-versions = "*" +files = [ + {file = "docker-image-py-0.1.12.tar.gz", hash = "sha256:c0eebb6c25714b2a4f91a1462183e70252fa34fb189496d3c54711a64f12f96e"}, + {file = "docker_image_py-0.1.12-py2-none-any.whl", hash = "sha256:44e18e8000aaaddbd2e02d40050dca850acd071c4780cbe2b3366cb5dc1a6d62"}, +] + +[package.dependencies] +regex = ">=2019.4.14" + [[package]] name = "exceptiongroup" version = "1.1.1" description = "Backport of PEP 654 (exception groups)" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -381,23 +410,25 @@ test = ["pytest (>=6)"] [[package]] name = "filelock" -version = "3.12.0" +version = "3.12.2" description = "A platform independent file lock." +category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "filelock-3.12.0-py3-none-any.whl", hash = "sha256:ad98852315c2ab702aeb628412cbf7e95b7ce8c3bf9565670b4eaecf1db370a9"}, - {file = "filelock-3.12.0.tar.gz", hash = "sha256:fc03ae43288c013d2ea83c8597001b1129db351aad9c57fe2409327916b8e718"}, + {file = "filelock-3.12.2-py3-none-any.whl", hash = "sha256:cbb791cdea2a72f23da6ac5b5269ab0a0d161e9ef0100e653b69049a7706d1ec"}, + {file = "filelock-3.12.2.tar.gz", hash = "sha256:002740518d8aa59a26b0c76e10fb8c6e15eae825d34b6fdf670333fd7b938d81"}, ] [package.extras] -docs = ["furo (>=2023.3.27)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.2.3)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"] +docs = ["furo (>=2023.5.20)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"] [[package]] name = "identify" version = "2.5.24" description = "File identification library for Python" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -412,6 +443,7 @@ license = ["ukkonen"] name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -423,6 +455,7 @@ files = [ name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -434,6 +467,7 @@ files = [ name = "isort" version = "5.12.0" description = "A Python utility / library to sort Python imports." +category = "dev" optional = false python-versions = ">=3.8.0" files = [ @@ -451,6 +485,7 @@ requirements-deprecated-finder = ["pip-api", "pipreqs"] name = "lazy-object-proxy" version = "1.9.0" description = "A fast and thorough lazy object proxy." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -496,6 +531,7 @@ files = [ name = "mccabe" version = "0.7.0" description = "McCabe checker, plugin for flake8" +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -507,6 +543,7 @@ files = [ name = "mypy-extensions" version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." +category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -518,6 +555,7 @@ files = [ name = "nodeenv" version = "1.8.0" description = "Node.js virtual environment builder" +category = "dev" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" files = [ @@ -532,6 +570,7 @@ setuptools = "*" name = "packaging" version = "23.1" description = "Core utilities for Python packages" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -543,6 +582,7 @@ files = [ name = "pathspec" version = "0.11.1" description = "Utility library for gitignore style pattern matching of file paths." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -552,28 +592,30 @@ files = [ [[package]] name = "platformdirs" -version = "3.5.1" +version = "3.8.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "platformdirs-3.5.1-py3-none-any.whl", hash = "sha256:e2378146f1964972c03c085bb5662ae80b2b8c06226c54b2ff4aa9483e8a13a5"}, - {file = "platformdirs-3.5.1.tar.gz", hash = "sha256:412dae91f52a6f84830f39a8078cecd0e866cb72294a5c66808e74d5e88d251f"}, + {file = "platformdirs-3.8.0-py3-none-any.whl", hash = "sha256:ca9ed98ce73076ba72e092b23d3c93ea6c4e186b3f1c3dad6edd98ff6ffcca2e"}, + {file = "platformdirs-3.8.0.tar.gz", hash = "sha256:b0cabcb11063d21a0b261d557acb0a9d2126350e63b70cdf7db6347baea456dc"}, ] [package.extras] -docs = ["furo (>=2023.3.27)", "proselint (>=0.13)", "sphinx (>=6.2.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] +docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)"] [[package]] name = "pluggy" -version = "1.0.0" +version = "1.2.0" description = "plugin and hook calling mechanisms for python" +category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, - {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, + {file = "pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849"}, + {file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"}, ] [package.extras] @@ -584,6 +626,7 @@ testing = ["pytest", "pytest-benchmark"] name = "pre-commit" version = "3.3.2" description = "A framework for managing and maintaining multi-language pre-commit hooks." +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -598,10 +641,64 @@ nodeenv = ">=0.11.1" pyyaml = ">=5.1" virtualenv = ">=20.10.0" +[[package]] +name = "pydantic" +version = "1.10.10" +description = "Data validation and settings management using python type hints" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pydantic-1.10.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:adad1ee4ab9888f12dac2529276704e719efcf472e38df7813f5284db699b4ec"}, + {file = "pydantic-1.10.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7a7db03339893feef2092ff7b1afc9497beed15ebd4af84c3042a74abce02d48"}, + {file = "pydantic-1.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67b3714b97ff84b2689654851c2426389bcabfac9080617bcf4306c69db606f6"}, + {file = "pydantic-1.10.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edfdf0a5abc5c9bf2052ebaec20e67abd52e92d257e4f2d30e02c354ed3e6030"}, + {file = "pydantic-1.10.10-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:20a3b30fd255eeeb63caa9483502ba96b7795ce5bf895c6a179b3d909d9f53a6"}, + {file = "pydantic-1.10.10-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:db4c7f7e60ca6f7d6c1785070f3e5771fcb9b2d88546e334d2f2c3934d949028"}, + {file = "pydantic-1.10.10-cp310-cp310-win_amd64.whl", hash = "sha256:a2d5be50ac4a0976817144c7d653e34df2f9436d15555189f5b6f61161d64183"}, + {file = "pydantic-1.10.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:566a04ba755e8f701b074ffb134ddb4d429f75d5dced3fbd829a527aafe74c71"}, + {file = "pydantic-1.10.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f79db3652ed743309f116ba863dae0c974a41b688242482638b892246b7db21d"}, + {file = "pydantic-1.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c62376890b819bebe3c717a9ac841a532988372b7e600e76f75c9f7c128219d5"}, + {file = "pydantic-1.10.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4870f13a4fafd5bc3e93cff3169222534fad867918b188e83ee0496452978437"}, + {file = "pydantic-1.10.10-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:990027e77cda6072a566e433b6962ca3b96b4f3ae8bd54748e9d62a58284d9d7"}, + {file = "pydantic-1.10.10-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8c40964596809eb616d94f9c7944511f620a1103d63d5510440ed2908fc410af"}, + {file = "pydantic-1.10.10-cp311-cp311-win_amd64.whl", hash = "sha256:ea9eebc2ebcba3717e77cdeee3f6203ffc0e78db5f7482c68b1293e8cc156e5e"}, + {file = "pydantic-1.10.10-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:762aa598f79b4cac2f275d13336b2dd8662febee2a9c450a49a2ab3bec4b385f"}, + {file = "pydantic-1.10.10-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6dab5219659f95e357d98d70577b361383057fb4414cfdb587014a5f5c595f7b"}, + {file = "pydantic-1.10.10-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3d4ee957a727ccb5a36f1b0a6dbd9fad5dedd2a41eada99a8df55c12896e18d"}, + {file = "pydantic-1.10.10-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b69f9138dec566962ec65623c9d57bee44412d2fc71065a5f3ebb3820bdeee96"}, + {file = "pydantic-1.10.10-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7aa75d1bd9cc275cf9782f50f60cddaf74cbaae19b6ada2a28e737edac420312"}, + {file = "pydantic-1.10.10-cp37-cp37m-win_amd64.whl", hash = "sha256:9f62a727f5c590c78c2d12fda302d1895141b767c6488fe623098f8792255fe5"}, + {file = "pydantic-1.10.10-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:aac218feb4af73db8417ca7518fb3bade4534fcca6e3fb00f84966811dd94450"}, + {file = "pydantic-1.10.10-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:88546dc10a40b5b52cae87d64666787aeb2878f9a9b37825aedc2f362e7ae1da"}, + {file = "pydantic-1.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c41bbaae89e32fc582448e71974de738c055aef5ab474fb25692981a08df808a"}, + {file = "pydantic-1.10.10-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b71bd504d1573b0b722ae536e8ffb796bedeef978979d076bf206e77dcc55a5"}, + {file = "pydantic-1.10.10-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e088e3865a2270ecbc369924cd7d9fbc565667d9158e7f304e4097ebb9cf98dd"}, + {file = "pydantic-1.10.10-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3403a090db45d4027d2344859d86eb797484dfda0706cf87af79ace6a35274ef"}, + {file = "pydantic-1.10.10-cp38-cp38-win_amd64.whl", hash = "sha256:e0014e29637125f4997c174dd6167407162d7af0da73414a9340461ea8573252"}, + {file = "pydantic-1.10.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9965e49c6905840e526e5429b09e4c154355b6ecc0a2f05492eda2928190311d"}, + {file = "pydantic-1.10.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:748d10ab6089c5d196e1c8be9de48274f71457b01e59736f7a09c9dc34f51887"}, + {file = "pydantic-1.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86936c383f7c38fd26d35107eb669c85d8f46dfceae873264d9bab46fe1c7dde"}, + {file = "pydantic-1.10.10-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7a26841be620309a9697f5b1ffc47dce74909e350c5315ccdac7a853484d468a"}, + {file = "pydantic-1.10.10-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:409b810f387610cc7405ab2fa6f62bdf7ea485311845a242ebc0bd0496e7e5ac"}, + {file = "pydantic-1.10.10-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ce937a2a2c020bcad1c9fde02892392a1123de6dda906ddba62bfe8f3e5989a2"}, + {file = "pydantic-1.10.10-cp39-cp39-win_amd64.whl", hash = "sha256:37ebddef68370e6f26243acc94de56d291e01227a67b2ace26ea3543cf53dd5f"}, + {file = "pydantic-1.10.10-py3-none-any.whl", hash = "sha256:a5939ec826f7faec434e2d406ff5e4eaf1716eb1f247d68cd3d0b3612f7b4c8a"}, + {file = "pydantic-1.10.10.tar.gz", hash = "sha256:3b8d5bd97886f9eb59260594207c9f57dce14a6f869c6ceea90188715d29921a"}, +] + +[package.dependencies] +typing-extensions = ">=4.2.0" + +[package.extras] +dotenv = ["python-dotenv (>=0.10.4)"] +email = ["email-validator (>=1.0.3)"] + [[package]] name = "pylint" version = "2.17.4" description = "python code static checker" +category = "dev" optional = false python-versions = ">=3.7.2" files = [ @@ -628,6 +725,7 @@ testutils = ["gitpython (>3)"] name = "pytest" version = "7.3.1" description = "pytest: simple powerful testing with Python" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -650,6 +748,7 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no name = "pytest-cov" version = "4.1.0" description = "Pytest plugin for measuring coverage." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -664,10 +763,48 @@ pytest = ">=4.6" [package.extras] testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] +[[package]] +name = "python-on-whales" +version = "0.62.0" +description = "A Docker client for Python, designed to be fun and intuitive!" +category = "main" +optional = false +python-versions = ">=3.8, <4" +files = [ + {file = "python-on-whales-0.62.0.tar.gz", hash = "sha256:7c735739f7b3b78e80d6aacd0c47eb0608ba4bdfa82819a9340becdc4815aa71"}, + {file = "python_on_whales-0.62.0-py3-none-any.whl", hash = "sha256:7b876aed5ad44305ac2cd48c728df6e316ebb59de2247a08bea522cabba73b73"}, +] + +[package.dependencies] +pydantic = ">=1.5,<2" +requests = "*" +tqdm = "*" +typer = ">=0.4.1" +typing-extensions = "*" + +[[package]] +name = "python-slugify" +version = "8.0.1" +description = "A Python slugify application that also handles Unicode" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "python-slugify-8.0.1.tar.gz", hash = "sha256:ce0d46ddb668b3be82f4ed5e503dbc33dd815d83e2eb6824211310d3fb172a27"}, + {file = "python_slugify-8.0.1-py2.py3-none-any.whl", hash = "sha256:70ca6ea68fe63ecc8fa4fcf00ae651fc8a5d02d93dcd12ae6d4fc7ca46c4d395"}, +] + +[package.dependencies] +text-unidecode = ">=1.3" + +[package.extras] +unidecode = ["Unidecode (>=1.1.1)"] + [[package]] name = "pywin32" version = "306" description = "Python for Window Extensions" +category = "main" optional = false python-versions = "*" files = [ @@ -691,6 +828,7 @@ files = [ name = "pyyaml" version = "6.0" description = "YAML parser and emitter for Python" +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -736,10 +874,109 @@ files = [ {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, ] +[[package]] +name = "regex" +version = "2023.6.3" +description = "Alternative regular expression module, to replace re." +category = "dev" +optional = false +python-versions = ">=3.6" +files = [ + {file = "regex-2023.6.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:824bf3ac11001849aec3fa1d69abcb67aac3e150a933963fb12bda5151fe1bfd"}, + {file = "regex-2023.6.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:05ed27acdf4465c95826962528f9e8d41dbf9b1aa8531a387dee6ed215a3e9ef"}, + {file = "regex-2023.6.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b49c764f88a79160fa64f9a7b425620e87c9f46095ef9c9920542ab2495c8bc"}, + {file = "regex-2023.6.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8e3f1316c2293e5469f8f09dc2d76efb6c3982d3da91ba95061a7e69489a14ef"}, + {file = "regex-2023.6.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:43e1dd9d12df9004246bacb79a0e5886b3b6071b32e41f83b0acbf293f820ee8"}, + {file = "regex-2023.6.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4959e8bcbfda5146477d21c3a8ad81b185cd252f3d0d6e4724a5ef11c012fb06"}, + {file = "regex-2023.6.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:af4dd387354dc83a3bff67127a124c21116feb0d2ef536805c454721c5d7993d"}, + {file = "regex-2023.6.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2239d95d8e243658b8dbb36b12bd10c33ad6e6933a54d36ff053713f129aa536"}, + {file = "regex-2023.6.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:890e5a11c97cf0d0c550eb661b937a1e45431ffa79803b942a057c4fb12a2da2"}, + {file = "regex-2023.6.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a8105e9af3b029f243ab11ad47c19b566482c150c754e4c717900a798806b222"}, + {file = "regex-2023.6.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:25be746a8ec7bc7b082783216de8e9473803706723b3f6bef34b3d0ed03d57e2"}, + {file = "regex-2023.6.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:3676f1dd082be28b1266c93f618ee07741b704ab7b68501a173ce7d8d0d0ca18"}, + {file = "regex-2023.6.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:10cb847aeb1728412c666ab2e2000ba6f174f25b2bdc7292e7dd71b16db07568"}, + {file = "regex-2023.6.3-cp310-cp310-win32.whl", hash = "sha256:dbbbfce33cd98f97f6bffb17801b0576e653f4fdb1d399b2ea89638bc8d08ae1"}, + {file = "regex-2023.6.3-cp310-cp310-win_amd64.whl", hash = "sha256:c5f8037000eb21e4823aa485149f2299eb589f8d1fe4b448036d230c3f4e68e0"}, + {file = "regex-2023.6.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c123f662be8ec5ab4ea72ea300359023a5d1df095b7ead76fedcd8babbedf969"}, + {file = "regex-2023.6.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9edcbad1f8a407e450fbac88d89e04e0b99a08473f666a3f3de0fd292badb6aa"}, + {file = "regex-2023.6.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcba6dae7de533c876255317c11f3abe4907ba7d9aa15d13e3d9710d4315ec0e"}, + {file = "regex-2023.6.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29cdd471ebf9e0f2fb3cac165efedc3c58db841d83a518b082077e612d3ee5df"}, + {file = "regex-2023.6.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:12b74fbbf6cbbf9dbce20eb9b5879469e97aeeaa874145517563cca4029db65c"}, + {file = "regex-2023.6.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c29ca1bd61b16b67be247be87390ef1d1ef702800f91fbd1991f5c4421ebae8"}, + {file = "regex-2023.6.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d77f09bc4b55d4bf7cc5eba785d87001d6757b7c9eec237fe2af57aba1a071d9"}, + {file = "regex-2023.6.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ea353ecb6ab5f7e7d2f4372b1e779796ebd7b37352d290096978fea83c4dba0c"}, + {file = "regex-2023.6.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:10590510780b7541969287512d1b43f19f965c2ece6c9b1c00fc367b29d8dce7"}, + {file = "regex-2023.6.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:e2fbd6236aae3b7f9d514312cdb58e6494ee1c76a9948adde6eba33eb1c4264f"}, + {file = "regex-2023.6.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:6b2675068c8b56f6bfd5a2bda55b8accbb96c02fd563704732fd1c95e2083461"}, + {file = "regex-2023.6.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:74419d2b50ecb98360cfaa2974da8689cb3b45b9deff0dcf489c0d333bcc1477"}, + {file = "regex-2023.6.3-cp311-cp311-win32.whl", hash = "sha256:fb5ec16523dc573a4b277663a2b5a364e2099902d3944c9419a40ebd56a118f9"}, + {file = "regex-2023.6.3-cp311-cp311-win_amd64.whl", hash = "sha256:09e4a1a6acc39294a36b7338819b10baceb227f7f7dbbea0506d419b5a1dd8af"}, + {file = "regex-2023.6.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:0654bca0cdf28a5956c83839162692725159f4cda8d63e0911a2c0dc76166525"}, + {file = "regex-2023.6.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:463b6a3ceb5ca952e66550a4532cef94c9a0c80dc156c4cc343041951aec1697"}, + {file = "regex-2023.6.3-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:87b2a5bb5e78ee0ad1de71c664d6eb536dc3947a46a69182a90f4410f5e3f7dd"}, + {file = "regex-2023.6.3-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6343c6928282c1f6a9db41f5fd551662310e8774c0e5ebccb767002fcf663ca9"}, + {file = "regex-2023.6.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6192d5af2ccd2a38877bfef086d35e6659566a335b1492786ff254c168b1693"}, + {file = "regex-2023.6.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:74390d18c75054947e4194019077e243c06fbb62e541d8817a0fa822ea310c14"}, + {file = "regex-2023.6.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:742e19a90d9bb2f4a6cf2862b8b06dea5e09b96c9f2df1779e53432d7275331f"}, + {file = "regex-2023.6.3-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:8abbc5d54ea0ee80e37fef009e3cec5dafd722ed3c829126253d3e22f3846f1e"}, + {file = "regex-2023.6.3-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:c2b867c17a7a7ae44c43ebbeb1b5ff406b3e8d5b3e14662683e5e66e6cc868d3"}, + {file = "regex-2023.6.3-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:d831c2f8ff278179705ca59f7e8524069c1a989e716a1874d6d1aab6119d91d1"}, + {file = "regex-2023.6.3-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:ee2d1a9a253b1729bb2de27d41f696ae893507c7db224436abe83ee25356f5c1"}, + {file = "regex-2023.6.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:61474f0b41fe1a80e8dfa70f70ea1e047387b7cd01c85ec88fa44f5d7561d787"}, + {file = "regex-2023.6.3-cp36-cp36m-win32.whl", hash = "sha256:0b71e63226e393b534105fcbdd8740410dc6b0854c2bfa39bbda6b0d40e59a54"}, + {file = "regex-2023.6.3-cp36-cp36m-win_amd64.whl", hash = "sha256:bbb02fd4462f37060122e5acacec78e49c0fbb303c30dd49c7f493cf21fc5b27"}, + {file = "regex-2023.6.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b862c2b9d5ae38a68b92e215b93f98d4c5e9454fa36aae4450f61dd33ff48487"}, + {file = "regex-2023.6.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:976d7a304b59ede34ca2921305b57356694f9e6879db323fd90a80f865d355a3"}, + {file = "regex-2023.6.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:83320a09188e0e6c39088355d423aa9d056ad57a0b6c6381b300ec1a04ec3d16"}, + {file = "regex-2023.6.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9427a399501818a7564f8c90eced1e9e20709ece36be701f394ada99890ea4b3"}, + {file = "regex-2023.6.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7178bbc1b2ec40eaca599d13c092079bf529679bf0371c602edaa555e10b41c3"}, + {file = "regex-2023.6.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:837328d14cde912af625d5f303ec29f7e28cdab588674897baafaf505341f2fc"}, + {file = "regex-2023.6.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2d44dc13229905ae96dd2ae2dd7cebf824ee92bc52e8cf03dcead37d926da019"}, + {file = "regex-2023.6.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d54af539295392611e7efbe94e827311eb8b29668e2b3f4cadcfe6f46df9c777"}, + {file = "regex-2023.6.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:7117d10690c38a622e54c432dfbbd3cbd92f09401d622902c32f6d377e2300ee"}, + {file = "regex-2023.6.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bb60b503ec8a6e4e3e03a681072fa3a5adcbfa5479fa2d898ae2b4a8e24c4591"}, + {file = "regex-2023.6.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:65ba8603753cec91c71de423a943ba506363b0e5c3fdb913ef8f9caa14b2c7e0"}, + {file = "regex-2023.6.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:271f0bdba3c70b58e6f500b205d10a36fb4b58bd06ac61381b68de66442efddb"}, + {file = "regex-2023.6.3-cp37-cp37m-win32.whl", hash = "sha256:9beb322958aaca059f34975b0df135181f2e5d7a13b84d3e0e45434749cb20f7"}, + {file = "regex-2023.6.3-cp37-cp37m-win_amd64.whl", hash = "sha256:fea75c3710d4f31389eed3c02f62d0b66a9da282521075061ce875eb5300cf23"}, + {file = "regex-2023.6.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8f56fcb7ff7bf7404becdfc60b1e81a6d0561807051fd2f1860b0d0348156a07"}, + {file = "regex-2023.6.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d2da3abc88711bce7557412310dfa50327d5769a31d1c894b58eb256459dc289"}, + {file = "regex-2023.6.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a99b50300df5add73d307cf66abea093304a07eb017bce94f01e795090dea87c"}, + {file = "regex-2023.6.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5708089ed5b40a7b2dc561e0c8baa9535b77771b64a8330b684823cfd5116036"}, + {file = "regex-2023.6.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:687ea9d78a4b1cf82f8479cab23678aff723108df3edeac098e5b2498879f4a7"}, + {file = "regex-2023.6.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d3850beab9f527f06ccc94b446c864059c57651b3f911fddb8d9d3ec1d1b25d"}, + {file = "regex-2023.6.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8915cc96abeb8983cea1df3c939e3c6e1ac778340c17732eb63bb96247b91d2"}, + {file = "regex-2023.6.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:841d6e0e5663d4c7b4c8099c9997be748677d46cbf43f9f471150e560791f7ff"}, + {file = "regex-2023.6.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9edce5281f965cf135e19840f4d93d55b3835122aa76ccacfd389e880ba4cf82"}, + {file = "regex-2023.6.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b956231ebdc45f5b7a2e1f90f66a12be9610ce775fe1b1d50414aac1e9206c06"}, + {file = "regex-2023.6.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:36efeba71c6539d23c4643be88295ce8c82c88bbd7c65e8a24081d2ca123da3f"}, + {file = "regex-2023.6.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:cf67ca618b4fd34aee78740bea954d7c69fdda419eb208c2c0c7060bb822d747"}, + {file = "regex-2023.6.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b4598b1897837067a57b08147a68ac026c1e73b31ef6e36deeeb1fa60b2933c9"}, + {file = "regex-2023.6.3-cp38-cp38-win32.whl", hash = "sha256:f415f802fbcafed5dcc694c13b1292f07fe0befdb94aa8a52905bd115ff41e88"}, + {file = "regex-2023.6.3-cp38-cp38-win_amd64.whl", hash = "sha256:d4f03bb71d482f979bda92e1427f3ec9b220e62a7dd337af0aa6b47bf4498f72"}, + {file = "regex-2023.6.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ccf91346b7bd20c790310c4147eee6ed495a54ddb6737162a36ce9dbef3e4751"}, + {file = "regex-2023.6.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b28f5024a3a041009eb4c333863d7894d191215b39576535c6734cd88b0fcb68"}, + {file = "regex-2023.6.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0bb18053dfcfed432cc3ac632b5e5e5c5b7e55fb3f8090e867bfd9b054dbcbf"}, + {file = "regex-2023.6.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a5bfb3004f2144a084a16ce19ca56b8ac46e6fd0651f54269fc9e230edb5e4a"}, + {file = "regex-2023.6.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c6b48d0fa50d8f4df3daf451be7f9689c2bde1a52b1225c5926e3f54b6a9ed1"}, + {file = "regex-2023.6.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:051da80e6eeb6e239e394ae60704d2b566aa6a7aed6f2890a7967307267a5dc6"}, + {file = "regex-2023.6.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a4c3b7fa4cdaa69268748665a1a6ff70c014d39bb69c50fda64b396c9116cf77"}, + {file = "regex-2023.6.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:457b6cce21bee41ac292d6753d5e94dcbc5c9e3e3a834da285b0bde7aa4a11e9"}, + {file = "regex-2023.6.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:aad51907d74fc183033ad796dd4c2e080d1adcc4fd3c0fd4fd499f30c03011cd"}, + {file = "regex-2023.6.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:0385e73da22363778ef2324950e08b689abdf0b108a7d8decb403ad7f5191938"}, + {file = "regex-2023.6.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c6a57b742133830eec44d9b2290daf5cbe0a2f1d6acee1b3c7b1c7b2f3606df7"}, + {file = "regex-2023.6.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:3e5219bf9e75993d73ab3d25985c857c77e614525fac9ae02b1bebd92f7cecac"}, + {file = "regex-2023.6.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e5087a3c59eef624a4591ef9eaa6e9a8d8a94c779dade95d27c0bc24650261cd"}, + {file = "regex-2023.6.3-cp39-cp39-win32.whl", hash = "sha256:20326216cc2afe69b6e98528160b225d72f85ab080cbdf0b11528cbbaba2248f"}, + {file = "regex-2023.6.3-cp39-cp39-win_amd64.whl", hash = "sha256:bdff5eab10e59cf26bc479f565e25ed71a7d041d1ded04ccf9aee1d9f208487a"}, + {file = "regex-2023.6.3.tar.gz", hash = "sha256:72d1a25bf36d2050ceb35b517afe13864865268dfb45910e2e17a84be6cbfeb0"}, +] + [[package]] name = "requests" version = "2.31.0" description = "Python HTTP for Humans." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -761,6 +998,7 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "semver" version = "3.0.0" description = "Python helper for Semantic Versioning (https://semver.org)" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -770,13 +1008,14 @@ files = [ [[package]] name = "setuptools" -version = "67.8.0" +version = "68.0.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" +category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "setuptools-67.8.0-py3-none-any.whl", hash = "sha256:5df61bf30bb10c6f756eb19e7c9f3b473051f48db77fddbe06ff2ca307df9a6f"}, - {file = "setuptools-67.8.0.tar.gz", hash = "sha256:62642358adc77ffa87233bc4d2354c4b2682d214048f500964dbe760ccedf102"}, + {file = "setuptools-68.0.0-py3-none-any.whl", hash = "sha256:11e52c67415a381d10d6b462ced9cfb97066179f0e871399e006c4ab101fc85f"}, + {file = "setuptools-68.0.0.tar.gz", hash = "sha256:baf1fdb41c6da4cd2eae722e135500da913332ab3f2f5c7d33af9b492acb5235"}, ] [package.extras] @@ -788,6 +1027,7 @@ testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs ( name = "testcontainers" version = "3.7.1" description = "Library provides lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -817,10 +1057,23 @@ rabbitmq = ["pika"] redis = ["redis"] selenium = ["selenium"] +[[package]] +name = "text-unidecode" +version = "1.3" +description = "The most basic Text::Unidecode port" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"}, + {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"}, +] + [[package]] name = "tomli" version = "2.0.1" description = "A lil' TOML parser" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -832,6 +1085,7 @@ files = [ name = "tomlkit" version = "0.11.8" description = "Style preserving TOML library" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -839,26 +1093,71 @@ files = [ {file = "tomlkit-0.11.8.tar.gz", hash = "sha256:9330fc7faa1db67b541b28e62018c17d20be733177d290a13b24c62d1614e0c3"}, ] +[[package]] +name = "tqdm" +version = "4.65.0" +description = "Fast, Extensible Progress Meter" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tqdm-4.65.0-py3-none-any.whl", hash = "sha256:c4f53a17fe37e132815abceec022631be8ffe1b9381c2e6e30aa70edc99e9671"}, + {file = "tqdm-4.65.0.tar.gz", hash = "sha256:1871fb68a86b8fb3b59ca4cdd3dcccbc7e6d613eeed31f4c332531977b89beb5"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +dev = ["py-make (>=0.1.0)", "twine", "wheel"] +notebook = ["ipywidgets (>=6)"] +slack = ["slack-sdk"] +telegram = ["requests"] + +[[package]] +name = "typer" +version = "0.9.0" +description = "Typer, build great CLIs. Easy to code. Based on Python type hints." +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "typer-0.9.0-py3-none-any.whl", hash = "sha256:5d96d986a21493606a358cae4461bd8cdf83cbf33a5aa950ae629ca3b51467ee"}, + {file = "typer-0.9.0.tar.gz", hash = "sha256:50922fd79aea2f4751a8e0408ff10d2662bd0c8bbfa84755a699f3bada2978b2"}, +] + +[package.dependencies] +click = ">=7.1.1,<9.0.0" +typing-extensions = ">=3.7.4.3" + +[package.extras] +all = ["colorama (>=0.4.3,<0.5.0)", "rich (>=10.11.0,<14.0.0)", "shellingham (>=1.3.0,<2.0.0)"] +dev = ["autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)", "pre-commit (>=2.17.0,<3.0.0)"] +doc = ["cairosvg (>=2.5.2,<3.0.0)", "mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=8.1.4,<9.0.0)", "pillow (>=9.3.0,<10.0.0)"] +test = ["black (>=22.3.0,<23.0.0)", "coverage (>=6.2,<7.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.910)", "pytest (>=4.4.0,<8.0.0)", "pytest-cov (>=2.10.0,<5.0.0)", "pytest-sugar (>=0.9.4,<0.10.0)", "pytest-xdist (>=1.32.0,<4.0.0)", "rich (>=10.11.0,<14.0.0)", "shellingham (>=1.3.0,<2.0.0)"] + [[package]] name = "typing-extensions" -version = "4.6.0" +version = "4.7.0" description = "Backported and Experimental Type Hints for Python 3.7+" +category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "typing_extensions-4.6.0-py3-none-any.whl", hash = "sha256:6ad00b63f849b7dcc313b70b6b304ed67b2b2963b3098a33efe18056b1a9a223"}, - {file = "typing_extensions-4.6.0.tar.gz", hash = "sha256:ff6b238610c747e44c268aa4bb23c8c735d665a63726df3f9431ce707f2aa768"}, + {file = "typing_extensions-4.7.0-py3-none-any.whl", hash = "sha256:5d8c9dac95c27d20df12fb1d97b9793ab8b2af8a3a525e68c80e21060c161771"}, + {file = "typing_extensions-4.7.0.tar.gz", hash = "sha256:935ccf31549830cda708b42289d44b6f74084d616a00be651601a4f968e77c82"}, ] [[package]] name = "urllib3" -version = "2.0.2" +version = "2.0.3" description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "urllib3-2.0.2-py3-none-any.whl", hash = "sha256:d055c2f9d38dc53c808f6fdc8eab7360b6fdbbde02340ed25cfbcd817c62469e"}, - {file = "urllib3-2.0.2.tar.gz", hash = "sha256:61717a1095d7e155cdb737ac7bb2f4324a858a1e2e6466f6d03ff630ca68d3cc"}, + {file = "urllib3-2.0.3-py3-none-any.whl", hash = "sha256:48e7fafa40319d358848e1bc6809b208340fafe2096f1725d05d67443d0483d1"}, + {file = "urllib3-2.0.3.tar.gz", hash = "sha256:bee28b5e56addb8226c96f7f13ac28cb4c301dd5ea8a6ca179c0b9835e032825"}, ] [package.extras] @@ -869,33 +1168,35 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "virtualenv" -version = "20.23.0" +version = "20.23.1" description = "Virtual Python Environment builder" +category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "virtualenv-20.23.0-py3-none-any.whl", hash = "sha256:6abec7670e5802a528357fdc75b26b9f57d5d92f29c5462ba0fbe45feacc685e"}, - {file = "virtualenv-20.23.0.tar.gz", hash = "sha256:a85caa554ced0c0afbd0d638e7e2d7b5f92d23478d05d17a76daeac8f279f924"}, + {file = "virtualenv-20.23.1-py3-none-any.whl", hash = "sha256:34da10f14fea9be20e0fd7f04aba9732f84e593dac291b757ce42e3368a39419"}, + {file = "virtualenv-20.23.1.tar.gz", hash = "sha256:8ff19a38c1021c742148edc4f81cb43d7f8c6816d2ede2ab72af5b84c749ade1"}, ] [package.dependencies] distlib = ">=0.3.6,<1" -filelock = ">=3.11,<4" -platformdirs = ">=3.2,<4" +filelock = ">=3.12,<4" +platformdirs = ">=3.5.1,<4" [package.extras] -docs = ["furo (>=2023.3.27)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=22.12)"] -test = ["covdefaults (>=2.3)", "coverage (>=7.2.3)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.3.1)", "pytest-env (>=0.8.1)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.10)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=67.7.1)", "time-machine (>=2.9)"] +docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] +test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.3.1)", "pytest-env (>=0.8.1)", "pytest-freezer (>=0.4.6)", "pytest-mock (>=3.10)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=67.8)", "time-machine (>=2.9)"] [[package]] name = "websocket-client" -version = "1.5.2" +version = "1.6.1" description = "WebSocket client for Python with low level API options" +category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "websocket-client-1.5.2.tar.gz", hash = "sha256:c7d67c13b928645f259d9b847ab5b57fd2d127213ca41ebd880de1f553b7c23b"}, - {file = "websocket_client-1.5.2-py3-none-any.whl", hash = "sha256:f8c64e28cd700e7ba1f04350d66422b6833b82a796b525a51e740b8cc8dab4b1"}, + {file = "websocket-client-1.6.1.tar.gz", hash = "sha256:c951af98631d24f8df89ab1019fc365f2227c0892f12fd150e935607c79dd0dd"}, + {file = "websocket_client-1.6.1-py3-none-any.whl", hash = "sha256:f1f9f2ad5291f0225a49efad77abf9e700b6fef553900623060dad6e26503b9d"}, ] [package.extras] @@ -907,6 +1208,7 @@ test = ["websockets"] name = "wrapt" version = "1.15.0" description = "Module for decorators, wrappers and monkey patching." +category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" files = [ @@ -990,4 +1292,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "3.9.*" -content-hash = "32e23f71841b2ab1fa2cbbac99c5eaa412d8cb80d3d96413d4dc31af1cf4762f" +content-hash = "018ebcb1ee2e18c8b5b0d51c6a96f0c288d70f0fde8411806332074ee42bd823" diff --git a/pyproject.toml b/pyproject.toml index 83b7db8..355d1e1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,6 +9,8 @@ license = "MIT" python = "3.9.*" click = "8.1.3" docker = "6.1.3" +python-on-whales = "0.62.0" + [tool.poetry.dev-dependencies] pylint = "2.17.4" @@ -20,6 +22,8 @@ pre-commit = "3.3.2" semver = "3.0.0" testcontainers = "3.7.1" bcrypt = "4.0.1" +docker-image-py = "0.1.12" +python-slugify = "8.0.1" # https://docs.pytest.org/en/latest/reference/customize.html [tool.pytest.ini_options] diff --git a/tests/build_image/conftest.py b/tests/build_image/conftest.py index 17b9399..3fef723 100644 --- a/tests/build_image/conftest.py +++ b/tests/build_image/conftest.py @@ -4,26 +4,79 @@ from build.constants import TARGET_ARCHITECTURES from build.images import PythonPoetryImage +from tests.registry_container import DockerRegistryContainer +from python_on_whales import Builder +from python_on_whales import DockerClient as PowDockerClient +from tests.constants import VERSION, CONTEXT, BAKE_FILE, SLEEP_TIME +from tests.utils import extract_image_tags_from_build_config +from docker.models.containers import Container +from time import sleep +from slugify import slugify -@pytest.fixture(scope="package", params=TARGET_ARCHITECTURES) -def python_poetry_image( - docker_client: DockerClient, version: str, request -) -> str: - target_architecture: str = request.param +@pytest.fixture(scope="package") +def registry_container() -> DockerRegistryContainer: + registry_container = DockerRegistryContainer().with_bind_ports(5000, 5000) + registry_container.start() + yield registry_container + registry_container.stop() - python_poetry_image: Image = PythonPoetryImage( - docker_client, target_architecture, version - ).build() - image_tag: str = python_poetry_image.tags[0] - yield image_tag - docker_client.images.remove(image_tag, force=True) + +@pytest.fixture(scope="package") +def images( + pow_docker_client: PowDockerClient, + pow_buildx_builder: Builder, + registry_container: DockerRegistryContainer, +): + build_config: dict = pow_docker_client.buildx.bake( + targets=["python-poetry"], + builder=pow_buildx_builder, + files=[BAKE_FILE], + variables=dict( + REGISTRY=registry_container.get_registry(), + CONTEXT=CONTEXT, + IMAGE_VERSION=VERSION, + ), + push=True, + ) + image_tags: list[str] = extract_image_tags_from_build_config(build_config) + yield image_tags @pytest.fixture(scope="function") -def cleaned_up_test_container(docker_client: DockerClient, request) -> None: - test_container_name: str = request.param - yield test_container_name - test_container = docker_client.containers.get(test_container_name) +def test_container(docker_client: DockerClient, request): + image_tag: str = request.param + image_name: str = slugify(image_tag) + test_container: Container = docker_client.containers.run( + image_tag, + name=image_name, + detach=True, + tty=True, + ) + sleep(SLEEP_TIME) + yield test_container test_container.stop() test_container.remove() + + +# @pytest.fixture(scope="package", params=TARGET_ARCHITECTURES) +# def python_poetry_image( +# docker_client: DockerClient, version: str, request +# ) -> str: +# target_architecture: str = request.param + +# python_poetry_image: Image = PythonPoetryImage( +# docker_client, target_architecture, version +# ).build() +# image_tag: str = python_poetry_image.tags[0] +# yield image_tag +# docker_client.images.remove(image_tag, force=True) + + +# @pytest.fixture(scope="function") +# def cleaned_up_test_container(docker_client: DockerClient, request) -> None: +# test_container_name: str = request.param +# yield test_container_name +# test_container = docker_client.containers.get(test_container_name) +# test_container.stop() +# test_container.remove() diff --git a/tests/build_image/test_build_version.py b/tests/build_image/test_build_version.py index 74e674a..9b1ba1f 100644 --- a/tests/build_image/test_build_version.py +++ b/tests/build_image/test_build_version.py @@ -1,8 +1,11 @@ from tests.utils import ImageTagComponents +from tests.constants import VERSION, IMAGE_TAGS +import pytest -def test_build_version(python_poetry_image, version) -> None: +@pytest.mark.parametrize("image_tag", IMAGE_TAGS) +def test_build_version(image_tag) -> None: components: ImageTagComponents = ImageTagComponents.create_from_tag( - python_poetry_image + image_tag ) - assert components.version == version + assert components.version == VERSION diff --git a/tests/build_image/test_poetry_version.py b/tests/build_image/test_poetry_version.py index d59f998..d2819e3 100644 --- a/tests/build_image/test_poetry_version.py +++ b/tests/build_image/test_poetry_version.py @@ -1,36 +1,19 @@ -from time import sleep -from uuid import uuid4 - import pytest from docker.models.containers import Container from build.constants import POETRY_VERSIONS -from tests.constants import SLEEP_TIME +from tests.constants import IMAGE_TAGS from tests.utils import ImageTagComponents -@pytest.mark.parametrize( - "cleaned_up_test_container", [str(uuid4())], indirect=True -) -def test_poetry_configuration( - docker_client, python_poetry_image, cleaned_up_test_container -) -> None: +@pytest.mark.parametrize("test_container", IMAGE_TAGS, indirect=True) +@pytest.mark.usefixtures("images") +def test_poetry_configuration(test_container: Container) -> None: image_tag_components: ImageTagComponents = ( - ImageTagComponents.create_from_tag(python_poetry_image) - ) - - test_container: Container = docker_client.containers.run( - python_poetry_image, - name=cleaned_up_test_container, - detach=True, - tty=True, + ImageTagComponents.create_from_tag(test_container.image.tags[0]) ) - sleep(SLEEP_TIME) (exit_code, output) = test_container.exec_run(["poetry", "--version"]) assert exit_code == 0 - poetry_version: str = POETRY_VERSIONS[ - image_tag_components.target_architecture - ] - assert poetry_version in output.decode("utf-8") + assert image_tag_components.poetry_version in output.decode("utf-8") diff --git a/tests/build_image/test_python_version.py b/tests/build_image/test_python_version.py index 10f252f..fc37f7a 100644 --- a/tests/build_image/test_python_version.py +++ b/tests/build_image/test_python_version.py @@ -1,40 +1,23 @@ -from time import sleep -from uuid import uuid4 - import pytest from docker.models.containers import Container from build.constants import ( PYTHON_VERSIONS, ) -from tests.constants import SLEEP_TIME +from tests.constants import IMAGE_TAGS from tests.utils import ImageTagComponents -@pytest.mark.parametrize( - "cleaned_up_test_container", [str(uuid4())], indirect=True -) +@pytest.mark.parametrize("test_container", IMAGE_TAGS, indirect=True) +@pytest.mark.usefixtures("images") def test_python_version( - docker_client, - python_poetry_image, - cleaned_up_test_container, + test_container: Container, ) -> None: image_tag_components: ImageTagComponents = ( - ImageTagComponents.create_from_tag(python_poetry_image) + ImageTagComponents.create_from_tag(test_container.image.tags[0]) ) - test_container: Container = docker_client.containers.run( - python_poetry_image, - name=cleaned_up_test_container, - detach=True, - tty=True, - ) - sleep(SLEEP_TIME) - (exit_code, output) = test_container.exec_run(["python", "--version"]) assert exit_code == 0 - version_string: str = ( - f"Python {PYTHON_VERSIONS[image_tag_components.target_architecture]}" - ) - assert version_string in output.decode("utf-8") + assert image_tag_components.python_version in output.decode("utf-8") diff --git a/tests/conftest.py b/tests/conftest.py index 615b336..136b065 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,9 +1,8 @@ -from random import randrange - import docker import pytest from docker.client import DockerClient -from semver import VersionInfo +from python_on_whales import Builder +from python_on_whales import DockerClient as PowDockerClient @pytest.fixture(scope="session") @@ -12,9 +11,15 @@ def docker_client() -> DockerClient: @pytest.fixture(scope="session") -def version() -> str: - version: VersionInfo = VersionInfo( - major=randrange(100), minor=randrange(100), patch=randrange(100) +def pow_docker_client() -> PowDockerClient: + return PowDockerClient() + + +@pytest.fixture(scope="session") +def pow_buildx_builder(pow_docker_client: PowDockerClient) -> Builder: + builder: Builder = pow_docker_client.buildx.create( + driver="docker-container", driver_options=dict(network="host") ) - version_string: str = str(version) - return version_string + yield builder + pow_docker_client.buildx.stop(builder) + pow_docker_client.buildx.remove(builder) diff --git a/tests/constants.py b/tests/constants.py index aab9a85..c95e8ba 100644 --- a/tests/constants.py +++ b/tests/constants.py @@ -1,3 +1,17 @@ +from random import randrange +from semver import VersionInfo +from build.utils import get_docker_bake_file, get_context +from pathlib import Path +from tests.utils import generate_image_tags + SLEEP_TIME: float = 3.0 REGISTRY_USERNAME: str = "foo" REGISTRY_PASSWORD: str = "bar" +VERSION: str = str( + VersionInfo( + major=randrange(100), minor=randrange(100), patch=randrange(100) + ) +) +BAKE_FILE: Path = get_docker_bake_file() +CONTEXT: Path = get_context() +IMAGE_TAGS: list[str] = generate_image_tags(BAKE_FILE, CONTEXT, VERSION) diff --git a/tests/publish_image/test_cli.py b/tests/publish_image/test_cli.py index 31addff..3ca2420 100644 --- a/tests/publish_image/test_cli.py +++ b/tests/publish_image/test_cli.py @@ -2,13 +2,13 @@ from docker.errors import APIError from build.publish import main -from tests.constants import REGISTRY_USERNAME, REGISTRY_PASSWORD +from tests.constants import REGISTRY_USERNAME, REGISTRY_PASSWORD, VERSION from tests.registry_container import DockerRegistryContainer import pytest @pytest.mark.usefixtures("cleanup_images") -def test_registry(cli_runner: CliRunner, version: str): +def test_registry(cli_runner: CliRunner): with DockerRegistryContainer().with_bind_ports( 5000, 5000 ) as docker_registry: @@ -16,7 +16,7 @@ def test_registry(cli_runner: CliRunner, version: str): main, args=[ "--version-tag", - version, + VERSION, "--registry", docker_registry.get_registry(), ], @@ -25,9 +25,7 @@ def test_registry(cli_runner: CliRunner, version: str): @pytest.mark.usefixtures("cleanup_images") -def test_registry_with_unnecessary_credentials( - cli_runner: CliRunner, version: str -): +def test_registry_with_unnecessary_credentials(cli_runner: CliRunner): with DockerRegistryContainer().with_bind_ports( 5000, 5000 ) as docker_registry: @@ -39,7 +37,7 @@ def test_registry_with_unnecessary_credentials( "--docker-hub-password", "boom", "--version-tag", - version, + VERSION, "--registry", docker_registry.get_registry(), ], @@ -48,7 +46,7 @@ def test_registry_with_unnecessary_credentials( @pytest.mark.usefixtures("cleanup_images") -def test_registry_with_credentials(cli_runner: CliRunner, version: str): +def test_registry_with_credentials(cli_runner: CliRunner): with DockerRegistryContainer( username=REGISTRY_USERNAME, password=REGISTRY_PASSWORD ).with_bind_ports(5000, 5000) as docker_registry: @@ -60,7 +58,7 @@ def test_registry_with_credentials(cli_runner: CliRunner, version: str): "--docker-hub-password", REGISTRY_PASSWORD, "--version-tag", - version, + VERSION, "--registry", docker_registry.get_registry(), ], @@ -69,7 +67,7 @@ def test_registry_with_credentials(cli_runner: CliRunner, version: str): @pytest.mark.usefixtures("cleanup_images") -def test_registry_with_wrong_credentials(cli_runner: CliRunner, version: str): +def test_registry_with_wrong_credentials(cli_runner: CliRunner): with DockerRegistryContainer( username=REGISTRY_USERNAME, password=REGISTRY_PASSWORD ).with_bind_ports(5000, 5000) as docker_registry: @@ -81,7 +79,7 @@ def test_registry_with_wrong_credentials(cli_runner: CliRunner, version: str): "--docker-hub-password", "boom", "--version-tag", - version, + VERSION, "--registry", docker_registry.get_registry(), ], diff --git a/tests/publish_image/test_env.py b/tests/publish_image/test_env.py index cbf0a18..734429d 100644 --- a/tests/publish_image/test_env.py +++ b/tests/publish_image/test_env.py @@ -3,19 +3,19 @@ from docker.errors import APIError from build.publish import main -from tests.constants import REGISTRY_USERNAME, REGISTRY_PASSWORD +from tests.constants import REGISTRY_USERNAME, REGISTRY_PASSWORD, VERSION from tests.registry_container import DockerRegistryContainer @pytest.mark.usefixtures("cleanup_images") -def test_registry(cli_runner: CliRunner, version: str): +def test_registry(cli_runner: CliRunner): with DockerRegistryContainer().with_bind_ports( 5000, 5000 ) as docker_registry: result: Result = cli_runner.invoke( main, env={ - "GIT_TAG_NAME": version, + "GIT_TAG_NAME": VERSION, "REGISTRY": docker_registry.get_registry(), }, ) @@ -23,9 +23,7 @@ def test_registry(cli_runner: CliRunner, version: str): @pytest.mark.usefixtures("cleanup_images") -def test_registry_with_unnecessary_credentials( - cli_runner: CliRunner, version: str -): +def test_registry_with_unnecessary_credentials(cli_runner: CliRunner): with DockerRegistryContainer().with_bind_ports( 5000, 5000 ) as docker_registry: @@ -34,7 +32,7 @@ def test_registry_with_unnecessary_credentials( env={ "DOCKER_HUB_USERNAME": REGISTRY_USERNAME, "DOCKER_HUB_PASSWORD": REGISTRY_PASSWORD, - "GIT_TAG_NAME": version, + "GIT_TAG_NAME": VERSION, "REGISTRY": docker_registry.get_registry(), }, ) @@ -42,7 +40,7 @@ def test_registry_with_unnecessary_credentials( @pytest.mark.usefixtures("cleanup_images") -def test_registry_with_credentials(cli_runner: CliRunner, version: str): +def test_registry_with_credentials(cli_runner: CliRunner): with DockerRegistryContainer( username=REGISTRY_USERNAME, password=REGISTRY_PASSWORD ).with_bind_ports(5000, 5000) as docker_registry: @@ -51,7 +49,7 @@ def test_registry_with_credentials(cli_runner: CliRunner, version: str): env={ "DOCKER_HUB_USERNAME": REGISTRY_USERNAME, "DOCKER_HUB_PASSWORD": REGISTRY_PASSWORD, - "GIT_TAG_NAME": version, + "GIT_TAG_NAME": VERSION, "REGISTRY": docker_registry.get_registry(), }, ) @@ -59,7 +57,7 @@ def test_registry_with_credentials(cli_runner: CliRunner, version: str): @pytest.mark.usefixtures("cleanup_images") -def test_registry_with_wrong_credentials(cli_runner: CliRunner, version: str): +def test_registry_with_wrong_credentials(cli_runner: CliRunner): with DockerRegistryContainer( username=REGISTRY_USERNAME, password=REGISTRY_PASSWORD ).with_bind_ports(5000, 5000) as docker_registry: @@ -68,7 +66,7 @@ def test_registry_with_wrong_credentials(cli_runner: CliRunner, version: str): env={ "DOCKER_HUB_USERNAME": "boom", "DOCKER_HUB_PASSWORD": "bang", - "GIT_TAG_NAME": version, + "GIT_TAG_NAME": VERSION, "REGISTRY": docker_registry.get_registry(), }, ) diff --git a/tests/utils.py b/tests/utils.py index 66ce46c..1d22e3d 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -1,36 +1,83 @@ from dataclasses import dataclass +from python_on_whales import DockerClient +from pathlib import Path +from docker_image import reference @dataclass class ImageTagComponents: + registry: str image_name: str + tag: str version: str target_architecture: str + poetry_version: str + python_version: str @classmethod def create_from_tag(cls, tag: str): - tag_parts: list[str] = tag.split(":") - image_name: str = tag_parts[0] - image_tag: str = tag_parts[1] + ref = reference.Reference.parse(tag) + registry: str = ref.repository["domain"] + image_name: str = ref.repository["path"] + tag: str = ref["tag"] - image_tag_parts: list[str] = image_tag.split("-") + tag_parts: list[str] = tag.split("-") target_architecture_index = [ index - for index, tag_part in enumerate(image_tag_parts) + for index, tag_part in enumerate(tag_parts) if tag_part.startswith("poetry") ][0] + python_version_index = [ + index + for index, tag_part in enumerate(tag_parts) + if tag_part.startswith("python") + ][0] - version: str = "-".join(image_tag_parts[:target_architecture_index]) + version: str = "-".join(tag_parts[:target_architecture_index]) target_architecture: str = "-".join( - image_tag_parts[target_architecture_index:] + tag_parts[target_architecture_index:] ) + poetry_version: str = tag_parts[target_architecture_index].lstrip( + "poetry" + ) + python_version: str = tag_parts[python_version_index].lstrip("python") return cls( + registry=registry, image_name=image_name, + tag=tag, version=version, target_architecture=target_architecture, + poetry_version=poetry_version, + python_version=python_version, ) def create_version_tag_for_example_images(version: str, target: str) -> str: version_tag: str = f"{version}-{target}" return version_tag + + +def extract_image_tags_from_build_config(build_config: dict) -> list[str]: + image_tags: list[str] = [] + targets: dict = build_config["target"] + for value in targets.values(): + image_tags.extend(value["tags"]) + return image_tags + + +def generate_image_tags( + bake_file: Path, context: Path, version: str +) -> list[str]: + pow_docker_client: DockerClient = DockerClient() + build_config: dict = pow_docker_client.buildx.bake( + targets=["python-poetry"], + files=[bake_file], + variables=dict( + REGISTRY="localhost:5000", + CONTEXT=str(context), + IMAGE_VERSION=version, + ), + print=True, + ) + images_tags = extract_image_tags_from_build_config(build_config) + return images_tags From aa435e18c00aeac15a855ebd2b5e6d36b799dbc6 Mon Sep 17 00:00:00 2001 From: Max Pfeiffer Date: Sun, 2 Jul 2023 12:45:51 +0200 Subject: [PATCH 02/13] Refactored image publishing and tests --- build/docker-bake.hcl | 8 +-- build/publish.py | 77 ++++++++++-------------- build/utils.py | 27 +++++++++ tests/build_image/conftest.py | 55 +++++++---------- tests/build_image/test_build_version.py | 5 +- tests/build_image/test_poetry_version.py | 1 - tests/build_image/test_python_version.py | 3 - tests/constants.py | 7 ++- tests/publish_image/test_cli.py | 46 ++------------ tests/publish_image/test_env.py | 38 +----------- tests/utils.py | 29 +-------- 11 files changed, 97 insertions(+), 199 deletions(-) diff --git a/build/docker-bake.hcl b/build/docker-bake.hcl index 96dcd93..6019400 100644 --- a/build/docker-bake.hcl +++ b/build/docker-bake.hcl @@ -1,15 +1,11 @@ variable "REGISTRY" { - default = null + default = "docker.io" } variable "IMAGE_VERSION" { default = null } -variable "IMAGE_NAME" { - default = "pfeiffermax/python-poetry" -} - variable "CONTEXT" { default = "." } @@ -31,5 +27,5 @@ target "python-poetry" { platforms = ["linux/amd64", "linux/arm64"] - tags = ["${REGISTRY}/${IMAGE_NAME}:${IMAGE_VERSION}-poetry${poetry_version}-python${python_version}-${os_variant}"] + tags = ["${REGISTRY}/pfeiffermax/python-poetry:${IMAGE_VERSION}-poetry${poetry_version}-python${python_version}-${os_variant}"] } \ No newline at end of file diff --git a/build/publish.py b/build/publish.py index d8200b6..c6a5d65 100644 --- a/build/publish.py +++ b/build/publish.py @@ -1,12 +1,8 @@ import click -import docker -from build.constants import ( - TARGET_ARCHITECTURES, - PYTHON_POETRY_IMAGE_NAME, -) -from build.images import PythonPoetryImage -from docker.client import DockerClient +from build.utils import get_docker_bake_file, get_context +from pathlib import Path +from python_on_whales import DockerClient, Builder @click.command() @@ -30,48 +26,37 @@ def main( version_tag: str, registry: str, ) -> None: - docker_client: DockerClient = docker.from_env() - - for target_architecture in TARGET_ARCHITECTURES: - new_python_poetry_image: PythonPoetryImage = PythonPoetryImage( - docker_client, None, target_architecture, version_tag - ) - - # Delete old existing images - for old_image in docker_client.images.list( - new_python_poetry_image.image_name - ): - for tag in old_image.tags: - docker_client.images.remove(tag, force=True) - - new_python_poetry_image.build() - - # https://docs.docker.com/engine/reference/commandline/push/ - # https://docs.docker.com/engine/reference/commandline/tag/ - # https://docs.docker.com/engine/reference/commandline/image_tag/ - if docker_hub_username and docker_hub_password: - login_kwargs: dict = { - "username": docker_hub_username, - "password": docker_hub_password, - } - if registry: - login_kwargs["registry"] = registry + context: Path = get_context() + bake_file: Path = get_docker_bake_file() + variables: dict = { + "CONTEXT": str(context), + "IMAGE_VERSION": version_tag, + } + if registry: + variables["REGISTRY"] = registry - docker_client.login(**login_kwargs) + docker_client: DockerClient = DockerClient() + builder: Builder = docker_client.buildx.create( + driver="docker-container", driver_options=dict(network="host") + ) - if registry: - repository: str = f"{registry}/{new_python_poetry_image.image_name}" - else: - repository: str = new_python_poetry_image.image_name + docker_client.login( + server=registry, + username=docker_hub_username, + password=docker_hub_password, + ) + build_config: dict = docker_client.buildx.bake( + targets=["python-poetry"], + builder=builder, + files=[bake_file], + variables=variables, + push=True, + ) + print(build_config) - for line in docker_client.images.push( - repository, - tag=new_python_poetry_image.image_tag, - stream=True, - decode=True, - ): - print(line) - docker_client.close() + # Cleanup + docker_client.buildx.stop(builder) + docker_client.buildx.remove(builder) if __name__ == "__main__": diff --git a/build/utils.py b/build/utils.py index d4dddc8..a275194 100644 --- a/build/utils.py +++ b/build/utils.py @@ -1,4 +1,5 @@ from pathlib import Path +from python_on_whales import DockerClient def get_context() -> Path: @@ -8,3 +9,29 @@ def get_context() -> Path: def get_docker_bake_file() -> Path: docker_bake_file: Path = Path(__file__).parent.resolve() / "docker-bake.hcl" return docker_bake_file + + +def extract_image_tags_from_build_config(build_config: dict) -> list[str]: + image_tags: list[str] = [] + targets: dict = build_config["target"] + for value in targets.values(): + image_tags.extend(value["tags"]) + return image_tags + + +def generate_image_tags( + bake_file: Path, context: Path, version: str +) -> list[str]: + pow_docker_client: DockerClient = DockerClient() + build_config: dict = pow_docker_client.buildx.bake( + targets=["python-poetry"], + files=[bake_file], + variables=dict( + REGISTRY="localhost:5000", + CONTEXT=str(context), + IMAGE_VERSION=version, + ), + print=True, + ) + images_tags = extract_image_tags_from_build_config(build_config) + return images_tags diff --git a/tests/build_image/conftest.py b/tests/build_image/conftest.py index 3fef723..40e2de4 100644 --- a/tests/build_image/conftest.py +++ b/tests/build_image/conftest.py @@ -1,22 +1,29 @@ +from time import sleep + import pytest from docker.client import DockerClient -from docker.models.images import Image - -from build.constants import TARGET_ARCHITECTURES -from build.images import PythonPoetryImage -from tests.registry_container import DockerRegistryContainer +from docker.models.containers import Container from python_on_whales import Builder from python_on_whales import DockerClient as PowDockerClient -from tests.constants import VERSION, CONTEXT, BAKE_FILE, SLEEP_TIME -from tests.utils import extract_image_tags_from_build_config -from docker.models.containers import Container -from time import sleep from slugify import slugify +from build.utils import extract_image_tags_from_build_config +from tests.constants import ( + BAKE_FILE, + CONTEXT, + REGISTRY_PASSWORD, + REGISTRY_USERNAME, + SLEEP_TIME, + VERSION, +) +from tests.registry_container import DockerRegistryContainer + @pytest.fixture(scope="package") def registry_container() -> DockerRegistryContainer: - registry_container = DockerRegistryContainer().with_bind_ports(5000, 5000) + registry_container = DockerRegistryContainer( + username=REGISTRY_USERNAME, password=REGISTRY_PASSWORD + ).with_bind_ports(5000, 5000) registry_container.start() yield registry_container registry_container.stop() @@ -28,6 +35,11 @@ def images( pow_buildx_builder: Builder, registry_container: DockerRegistryContainer, ): + pow_docker_client.login( + server=registry_container.get_registry(), + username=REGISTRY_USERNAME, + password=REGISTRY_PASSWORD, + ) build_config: dict = pow_docker_client.buildx.bake( targets=["python-poetry"], builder=pow_buildx_builder, @@ -57,26 +69,3 @@ def test_container(docker_client: DockerClient, request): yield test_container test_container.stop() test_container.remove() - - -# @pytest.fixture(scope="package", params=TARGET_ARCHITECTURES) -# def python_poetry_image( -# docker_client: DockerClient, version: str, request -# ) -> str: -# target_architecture: str = request.param - -# python_poetry_image: Image = PythonPoetryImage( -# docker_client, target_architecture, version -# ).build() -# image_tag: str = python_poetry_image.tags[0] -# yield image_tag -# docker_client.images.remove(image_tag, force=True) - - -# @pytest.fixture(scope="function") -# def cleaned_up_test_container(docker_client: DockerClient, request) -> None: -# test_container_name: str = request.param -# yield test_container_name -# test_container = docker_client.containers.get(test_container_name) -# test_container.stop() -# test_container.remove() diff --git a/tests/build_image/test_build_version.py b/tests/build_image/test_build_version.py index 9b1ba1f..9d44982 100644 --- a/tests/build_image/test_build_version.py +++ b/tests/build_image/test_build_version.py @@ -1,7 +1,8 @@ -from tests.utils import ImageTagComponents -from tests.constants import VERSION, IMAGE_TAGS import pytest +from tests.constants import IMAGE_TAGS, VERSION +from tests.utils import ImageTagComponents + @pytest.mark.parametrize("image_tag", IMAGE_TAGS) def test_build_version(image_tag) -> None: diff --git a/tests/build_image/test_poetry_version.py b/tests/build_image/test_poetry_version.py index d2819e3..667eb96 100644 --- a/tests/build_image/test_poetry_version.py +++ b/tests/build_image/test_poetry_version.py @@ -1,7 +1,6 @@ import pytest from docker.models.containers import Container -from build.constants import POETRY_VERSIONS from tests.constants import IMAGE_TAGS from tests.utils import ImageTagComponents diff --git a/tests/build_image/test_python_version.py b/tests/build_image/test_python_version.py index fc37f7a..fb9a631 100644 --- a/tests/build_image/test_python_version.py +++ b/tests/build_image/test_python_version.py @@ -1,9 +1,6 @@ import pytest from docker.models.containers import Container -from build.constants import ( - PYTHON_VERSIONS, -) from tests.constants import IMAGE_TAGS from tests.utils import ImageTagComponents diff --git a/tests/constants.py b/tests/constants.py index c95e8ba..9dcdf56 100644 --- a/tests/constants.py +++ b/tests/constants.py @@ -1,8 +1,9 @@ +from pathlib import Path from random import randrange + from semver import VersionInfo -from build.utils import get_docker_bake_file, get_context -from pathlib import Path -from tests.utils import generate_image_tags + +from build.utils import generate_image_tags, get_context, get_docker_bake_file SLEEP_TIME: float = 3.0 REGISTRY_USERNAME: str = "foo" diff --git a/tests/publish_image/test_cli.py b/tests/publish_image/test_cli.py index 3ca2420..e2d97fe 100644 --- a/tests/publish_image/test_cli.py +++ b/tests/publish_image/test_cli.py @@ -1,48 +1,10 @@ +import pytest from click.testing import CliRunner, Result -from docker.errors import APIError +from python_on_whales import DockerException from build.publish import main -from tests.constants import REGISTRY_USERNAME, REGISTRY_PASSWORD, VERSION +from tests.constants import REGISTRY_PASSWORD, REGISTRY_USERNAME, VERSION from tests.registry_container import DockerRegistryContainer -import pytest - - -@pytest.mark.usefixtures("cleanup_images") -def test_registry(cli_runner: CliRunner): - with DockerRegistryContainer().with_bind_ports( - 5000, 5000 - ) as docker_registry: - result: Result = cli_runner.invoke( - main, - args=[ - "--version-tag", - VERSION, - "--registry", - docker_registry.get_registry(), - ], - ) - assert result.exit_code == 0 - - -@pytest.mark.usefixtures("cleanup_images") -def test_registry_with_unnecessary_credentials(cli_runner: CliRunner): - with DockerRegistryContainer().with_bind_ports( - 5000, 5000 - ) as docker_registry: - result: Result = cli_runner.invoke( - main, - args=[ - "--docker-hub-username", - "bang", - "--docker-hub-password", - "boom", - "--version-tag", - VERSION, - "--registry", - docker_registry.get_registry(), - ], - ) - assert result.exit_code == 0 @pytest.mark.usefixtures("cleanup_images") @@ -85,4 +47,4 @@ def test_registry_with_wrong_credentials(cli_runner: CliRunner): ], ) assert result.exit_code == 1 - assert isinstance(result.exception, APIError) + assert isinstance(result.exception, DockerException) diff --git a/tests/publish_image/test_env.py b/tests/publish_image/test_env.py index 734429d..5a46355 100644 --- a/tests/publish_image/test_env.py +++ b/tests/publish_image/test_env.py @@ -1,44 +1,12 @@ import pytest from click.testing import CliRunner, Result -from docker.errors import APIError +from python_on_whales import DockerException from build.publish import main -from tests.constants import REGISTRY_USERNAME, REGISTRY_PASSWORD, VERSION +from tests.constants import REGISTRY_PASSWORD, REGISTRY_USERNAME, VERSION from tests.registry_container import DockerRegistryContainer -@pytest.mark.usefixtures("cleanup_images") -def test_registry(cli_runner: CliRunner): - with DockerRegistryContainer().with_bind_ports( - 5000, 5000 - ) as docker_registry: - result: Result = cli_runner.invoke( - main, - env={ - "GIT_TAG_NAME": VERSION, - "REGISTRY": docker_registry.get_registry(), - }, - ) - assert result.exit_code == 0 - - -@pytest.mark.usefixtures("cleanup_images") -def test_registry_with_unnecessary_credentials(cli_runner: CliRunner): - with DockerRegistryContainer().with_bind_ports( - 5000, 5000 - ) as docker_registry: - result: Result = cli_runner.invoke( - main, - env={ - "DOCKER_HUB_USERNAME": REGISTRY_USERNAME, - "DOCKER_HUB_PASSWORD": REGISTRY_PASSWORD, - "GIT_TAG_NAME": VERSION, - "REGISTRY": docker_registry.get_registry(), - }, - ) - assert result.exit_code == 0 - - @pytest.mark.usefixtures("cleanup_images") def test_registry_with_credentials(cli_runner: CliRunner): with DockerRegistryContainer( @@ -71,4 +39,4 @@ def test_registry_with_wrong_credentials(cli_runner: CliRunner): }, ) assert result.exit_code == 1 - assert isinstance(result.exception, APIError) + assert isinstance(result.exception, DockerException) diff --git a/tests/utils.py b/tests/utils.py index 1d22e3d..35242ff 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -1,6 +1,5 @@ from dataclasses import dataclass -from python_on_whales import DockerClient -from pathlib import Path + from docker_image import reference @@ -55,29 +54,3 @@ def create_from_tag(cls, tag: str): def create_version_tag_for_example_images(version: str, target: str) -> str: version_tag: str = f"{version}-{target}" return version_tag - - -def extract_image_tags_from_build_config(build_config: dict) -> list[str]: - image_tags: list[str] = [] - targets: dict = build_config["target"] - for value in targets.values(): - image_tags.extend(value["tags"]) - return image_tags - - -def generate_image_tags( - bake_file: Path, context: Path, version: str -) -> list[str]: - pow_docker_client: DockerClient = DockerClient() - build_config: dict = pow_docker_client.buildx.bake( - targets=["python-poetry"], - files=[bake_file], - variables=dict( - REGISTRY="localhost:5000", - CONTEXT=str(context), - IMAGE_VERSION=version, - ), - print=True, - ) - images_tags = extract_image_tags_from_build_config(build_config) - return images_tags From 66d9db0953530fd3ffb2e0c6f8d3024ff5fa6fde Mon Sep 17 00:00:00 2001 From: Max Pfeiffer Date: Sun, 2 Jul 2023 16:44:30 +0200 Subject: [PATCH 03/13] Added tests for registry, removed obsolet code, updated docs --- .github/workflows/pipeline.yml | 4 - README.md | 8 +- build/constants.py | 121 ----------------------------- build/images.py | 68 ---------------- poetry.lock | 49 +++++++++++- pyproject.toml | 2 +- tests/build_image/test_registry.py | 51 ++++++++++++ 7 files changed, 105 insertions(+), 198 deletions(-) delete mode 100644 build/constants.py delete mode 100644 build/images.py create mode 100644 tests/build_image/test_registry.py diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index b4f21ea..1a89a27 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -39,8 +39,6 @@ jobs: steps: - name: Checkout Repository uses: actions/checkout@v3 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - name: Setup Python uses: actions/setup-python@v4 with: @@ -79,8 +77,6 @@ jobs: uses: actions/checkout@v3 - name: Get Git Commit Tag Name uses: olegtarasov/get-tag@v2.1 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - name: Setup Python uses: actions/setup-python@v4 with: diff --git a/README.md b/README.md index ea63d9e..4c3d000 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ management. Basis of this image are the [official Python](https://hub.docker.com/_/python) and [Debian images](https://hub.docker.com/_/debian). +This multiarch image supports AMD64 and ARM64 architectures. + **Docker Hub:** [pfeiffermax/python-poetry](https://hub.docker.com/r/pfeiffermax/python-poetry) **GitHub Repository:** [https://github.com/max-pfeiffer/python-poetry](https://github.com/max-pfeiffer/python-poetry) @@ -19,7 +21,7 @@ and [Debian images](https://hub.docker.com/_/debian). **Poetry versions:** * v1.3.2 * v1.4.2 -* v1.5.0 +* v1.5.1 **Python versions:** * v3.9 @@ -29,3 +31,7 @@ and [Debian images](https://hub.docker.com/_/debian). **Operating system:** * [Debian Bullseye v10.13](https://www.debian.org/releases/bullseye/) * [Debian Bullseye slim v10.13](https://www.debian.org/releases/bullseye/) + +**CPU architectures** +* linux/amd64 +* linux/arm64 diff --git a/build/constants.py b/build/constants.py deleted file mode 100644 index def8b91..0000000 --- a/build/constants.py +++ /dev/null @@ -1,121 +0,0 @@ -PYTHON_POETRY_IMAGE_NAME: str = "pfeiffermax/python-poetry" -TARGET_ARCHITECTURES: list[str] = [ - "poetry1.3.2-python3.9.16-bullseye", - "poetry1.3.2-python3.9.16-slim-bullseye", - "poetry1.3.2-python3.10.11-bullseye", - "poetry1.3.2-python3.10.11-slim-bullseye", - "poetry1.3.2-python3.11.3-bullseye", - "poetry1.3.2-python3.11.3-slim-bullseye", - "poetry1.4.2-python3.9.16-bullseye", - "poetry1.4.2-python3.9.16-slim-bullseye", - "poetry1.4.2-python3.10.11-bullseye", - "poetry1.4.2-python3.10.11-slim-bullseye", - "poetry1.4.2-python3.11.3-bullseye", - "poetry1.4.2-python3.11.3-slim-bullseye", - "poetry1.5.0-python3.9.16-bullseye", - "poetry1.5.0-python3.9.16-slim-bullseye", - "poetry1.5.0-python3.10.11-bullseye", - "poetry1.5.0-python3.10.11-slim-bullseye", - "poetry1.5.0-python3.11.3-bullseye", - "poetry1.5.0-python3.11.3-slim-bullseye", -] -BASE_IMAGES: dict = { - TARGET_ARCHITECTURES[ - 0 - ]: "python:3.9.16-bullseye@sha256:b8ddeb68904299c09a39aff59d4a713862253b137fdd7ace3a3b7ba0391971b1", - TARGET_ARCHITECTURES[ - 1 - ]: "python:3.9.16-slim-bullseye@sha256:9e0b4391fc41bc35c16caef4740736b6b349f6626fd14eba32793ae3c7b01908", - TARGET_ARCHITECTURES[ - 2 - ]: "python:3.10.11-bullseye@sha256:7f8f3cf6668c563e44a2285ce2eca9f8b82f96038449f07183126c95979f7d21", - TARGET_ARCHITECTURES[ - 3 - ]: "python:3.10.11-slim-bullseye@sha256:12af6fa557c55d85754107e59d0e21530d7a253757e128b3682d138e58712e54", - TARGET_ARCHITECTURES[ - 4 - ]: "python:3.11.3-bullseye@sha256:89cbc1829d74f72436c96302c49218291eb464705c726cc27d71c32fec1d9082", - TARGET_ARCHITECTURES[ - 5 - ]: "python:3.11.3-slim-bullseye@sha256:551c9529e77896518ac5693d7e98ee5e12051d625de450ac2a68da1eae15ec87", - TARGET_ARCHITECTURES[ - 6 - ]: "python:3.9.16-bullseye@sha256:b8ddeb68904299c09a39aff59d4a713862253b137fdd7ace3a3b7ba0391971b1", - TARGET_ARCHITECTURES[ - 7 - ]: "python:3.9.16-slim-bullseye@sha256:9e0b4391fc41bc35c16caef4740736b6b349f6626fd14eba32793ae3c7b01908", - TARGET_ARCHITECTURES[ - 8 - ]: "python:3.10.11-bullseye@sha256:7f8f3cf6668c563e44a2285ce2eca9f8b82f96038449f07183126c95979f7d21", - TARGET_ARCHITECTURES[ - 9 - ]: "python:3.10.11-slim-bullseye@sha256:12af6fa557c55d85754107e59d0e21530d7a253757e128b3682d138e58712e54", - TARGET_ARCHITECTURES[ - 10 - ]: "python:3.11.3-bullseye@sha256:89cbc1829d74f72436c96302c49218291eb464705c726cc27d71c32fec1d9082", - TARGET_ARCHITECTURES[ - 11 - ]: "python:3.11.3-slim-bullseye@sha256:551c9529e77896518ac5693d7e98ee5e12051d625de450ac2a68da1eae15ec87", - TARGET_ARCHITECTURES[ - 12 - ]: "python:3.9.16-bullseye@sha256:b8ddeb68904299c09a39aff59d4a713862253b137fdd7ace3a3b7ba0391971b1", - TARGET_ARCHITECTURES[ - 13 - ]: "python:3.9.16-slim-bullseye@sha256:9e0b4391fc41bc35c16caef4740736b6b349f6626fd14eba32793ae3c7b01908", - TARGET_ARCHITECTURES[ - 14 - ]: "python:3.10.11-bullseye@sha256:7f8f3cf6668c563e44a2285ce2eca9f8b82f96038449f07183126c95979f7d21", - TARGET_ARCHITECTURES[ - 15 - ]: "python:3.10.11-slim-bullseye@sha256:12af6fa557c55d85754107e59d0e21530d7a253757e128b3682d138e58712e54", - TARGET_ARCHITECTURES[ - 16 - ]: "python:3.11.3-bullseye@sha256:89cbc1829d74f72436c96302c49218291eb464705c726cc27d71c32fec1d9082", - TARGET_ARCHITECTURES[ - 17 - ]: "python:3.11.3-slim-bullseye@sha256:551c9529e77896518ac5693d7e98ee5e12051d625de450ac2a68da1eae15ec87", -} -PYTHON_VERSIONS: dict = { - TARGET_ARCHITECTURES[0]: "3.9.16", - TARGET_ARCHITECTURES[1]: "3.9.16", - TARGET_ARCHITECTURES[2]: "3.10.11", - TARGET_ARCHITECTURES[3]: "3.10.11", - TARGET_ARCHITECTURES[4]: "3.11.3", - TARGET_ARCHITECTURES[5]: "3.11.3", - TARGET_ARCHITECTURES[6]: "3.9.16", - TARGET_ARCHITECTURES[7]: "3.9.16", - TARGET_ARCHITECTURES[8]: "3.10.11", - TARGET_ARCHITECTURES[9]: "3.10.11", - TARGET_ARCHITECTURES[10]: "3.11.3", - TARGET_ARCHITECTURES[11]: "3.11.3", - TARGET_ARCHITECTURES[12]: "3.9.16", - TARGET_ARCHITECTURES[13]: "3.9.16", - TARGET_ARCHITECTURES[14]: "3.10.11", - TARGET_ARCHITECTURES[15]: "3.10.11", - TARGET_ARCHITECTURES[16]: "3.11.3", - TARGET_ARCHITECTURES[17]: "3.11.3", -} -POETRY_VERSIONS: dict = { - TARGET_ARCHITECTURES[0]: "1.3.2", - TARGET_ARCHITECTURES[1]: "1.3.2", - TARGET_ARCHITECTURES[2]: "1.3.2", - TARGET_ARCHITECTURES[3]: "1.3.2", - TARGET_ARCHITECTURES[4]: "1.3.2", - TARGET_ARCHITECTURES[5]: "1.3.2", - TARGET_ARCHITECTURES[6]: "1.4.2", - TARGET_ARCHITECTURES[7]: "1.4.2", - TARGET_ARCHITECTURES[8]: "1.4.2", - TARGET_ARCHITECTURES[9]: "1.4.2", - TARGET_ARCHITECTURES[10]: "1.4.2", - TARGET_ARCHITECTURES[11]: "1.4.2", - TARGET_ARCHITECTURES[12]: "1.5.0", - TARGET_ARCHITECTURES[13]: "1.5.0", - TARGET_ARCHITECTURES[14]: "1.5.0", - TARGET_ARCHITECTURES[15]: "1.5.0", - TARGET_ARCHITECTURES[16]: "1.5.0", - TARGET_ARCHITECTURES[17]: "1.5.0", -} -PLATFORMS: list[str] = [ - "linux/amd64", - "linux/arm64", -] diff --git a/build/images.py b/build/images.py deleted file mode 100644 index 60dfb4e..0000000 --- a/build/images.py +++ /dev/null @@ -1,68 +0,0 @@ -from pathlib import Path -from typing import Optional - -from python_on_whales import DockerClient, Builder, Image -from build.constants import ( - PLATFORMS, - PYTHON_POETRY_IMAGE_NAME, - BASE_IMAGES, - POETRY_VERSIONS, -) - - -class DockerImage: - def __init__( - self, - docker_client: DockerClient, - builder: Builder, - target_architecture: str, - version: str, - ): - self.docker_client: DockerClient = docker_client - self.builder: Builder = builder - self.dockerfile_name: str = "Dockerfile" - self.image_name: Optional[str] = None - self.image_tag: Optional[str] = None - self.version: Optional[str] = version - self.target_architecture: str = target_architecture - - -class PythonPoetryImage(DockerImage): - def __init__( - self, - docker_client: DockerClient, - builder: Builder, - target_architecture: str, - version: str, - ): - super().__init__(docker_client, builder, target_architecture, version) - self.dockerfile_directory: Path = Path(__file__).parent.resolve() - - # An image name is made up of slash-separated name components, optionally prefixed by a registry hostname. - # see: https://docs.docker.com/engine/reference/commandline/tag/ - self.image_name = PYTHON_POETRY_IMAGE_NAME - - def build(self) -> Optional[Image]: - self.image_tag = f"{self.version}-{self.target_architecture}" - - buildargs: dict[str, str] = { - "OFFICIAL_PYTHON_IMAGE": BASE_IMAGES[self.target_architecture], - "POETRY_VERSION": POETRY_VERSIONS[self.target_architecture], - } - - # image: Image = self.docker_client.images.build( - # path=str(self.dockerfile_directory), - # dockerfile=self.dockerfile_name, - # tag=f"{self.image_name}:{self.image_tag}", - # buildargs=buildargs, - # )[0] - - image: Image = self.docker_client.buildx.build( - context_path=str(self.dockerfile_directory), - tags=f"{self.image_name}:{self.image_tag}", - build_args=buildargs, - platforms=PLATFORMS, - builder=self.builder, - ) - - return image diff --git a/poetry.lock b/poetry.lock index baeba1b..f0ef2e1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -424,6 +424,22 @@ files = [ docs = ["furo (>=2023.5.20)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"] +[[package]] +name = "furl" +version = "2.1.3" +description = "URL manipulation made simple." +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "furl-2.1.3-py2.py3-none-any.whl", hash = "sha256:9ab425062c4217f9802508e45feb4a83e54324273ac4b202f1850363309666c0"}, + {file = "furl-2.1.3.tar.gz", hash = "sha256:5a6188fe2666c484a12159c18be97a1977a71d632ef5bb867ef15f54af39cc4e"}, +] + +[package.dependencies] +orderedmultidict = ">=1.0.1" +six = ">=1.8.0" + [[package]] name = "identify" version = "2.5.24" @@ -566,6 +582,21 @@ files = [ [package.dependencies] setuptools = "*" +[[package]] +name = "orderedmultidict" +version = "1.0.1" +description = "Ordered Multivalue Dictionary" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "orderedmultidict-1.0.1-py2.py3-none-any.whl", hash = "sha256:43c839a17ee3cdd62234c47deca1a8508a3f2ca1d0678a3bf791c87cf84adbf3"}, + {file = "orderedmultidict-1.0.1.tar.gz", hash = "sha256:04070bbb5e87291cc9bfa51df413677faf2141c73c61d2a5f7b26bea3cd882ad"}, +] + +[package.dependencies] +six = ">=1.8.0" + [[package]] name = "packaging" version = "23.1" @@ -786,7 +817,7 @@ typing-extensions = "*" name = "python-slugify" version = "8.0.1" description = "A Python slugify application that also handles Unicode" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1023,6 +1054,18 @@ docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-g testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + [[package]] name = "testcontainers" version = "3.7.1" @@ -1061,7 +1104,7 @@ selenium = ["selenium"] name = "text-unidecode" version = "1.3" description = "The most basic Text::Unidecode port" -category = "main" +category = "dev" optional = false python-versions = "*" files = [ @@ -1292,4 +1335,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "3.9.*" -content-hash = "018ebcb1ee2e18c8b5b0d51c6a96f0c288d70f0fde8411806332074ee42bd823" +content-hash = "62a40d4549e06ef6effd68ede59472919fa921eaac5590d12ed215dc596aae0f" diff --git a/pyproject.toml b/pyproject.toml index 355d1e1..607b548 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,6 @@ click = "8.1.3" docker = "6.1.3" python-on-whales = "0.62.0" - [tool.poetry.dev-dependencies] pylint = "2.17.4" pytest = "7.3.1" @@ -24,6 +23,7 @@ testcontainers = "3.7.1" bcrypt = "4.0.1" docker-image-py = "0.1.12" python-slugify = "8.0.1" +furl = "2.1.3" # https://docs.pytest.org/en/latest/reference/customize.html [tool.pytest.ini_options] diff --git a/tests/build_image/test_registry.py b/tests/build_image/test_registry.py new file mode 100644 index 0000000..1e141a4 --- /dev/null +++ b/tests/build_image/test_registry.py @@ -0,0 +1,51 @@ +from time import sleep + +from furl import furl +from requests import Response, get +from requests.auth import HTTPBasicAuth + +from tests.constants import REGISTRY_PASSWORD, REGISTRY_USERNAME +from tests.registry_container import DockerRegistryContainer +from tests.utils import ImageTagComponents + +BASIC_AUTH: HTTPBasicAuth = HTTPBasicAuth(REGISTRY_USERNAME, REGISTRY_PASSWORD) + + +def test_registry(registry_container: DockerRegistryContainer): + # Wait for the registry container to come up + sleep(1.0) + + furl_item: furl = furl(f"http://{registry_container.get_registry()}") + furl_item.path /= "v2/_catalog" + + response: Response = get(furl_item.url, auth=BASIC_AUTH) + + assert response.status_code == 200 + + +def test_registry_with_images( + registry_container: DockerRegistryContainer, images: list[str] +): + furl_item: furl = furl(f"http://{registry_container.get_registry()}") + furl_item.path /= "v2/_catalog" + + response: Response = get(furl_item.url, auth=BASIC_AUTH) + + assert response.status_code == 200 + assert response.json() == {"repositories": ["pfeiffermax/python-poetry"]} + + furl_item: furl = furl(f"http://{registry_container.get_registry()}") + furl_item.path /= "v2/pfeiffermax/python-poetry/tags/list" + + response: Response = get(furl_item.url, auth=BASIC_AUTH) + + assert response.status_code == 200 + + response_image_tags: list[str] = response.json()["tags"] + image_tags: list[str] = [ + ImageTagComponents.create_from_tag(reference).tag + for reference in images + ] + difference = set(image_tags).difference(set(response_image_tags)) + + assert not difference From cbd93c8398d66b1e0b7f0b6d571ceb3cb72e9038 Mon Sep 17 00:00:00 2001 From: Max Pfeiffer Date: Sun, 9 Jul 2023 19:14:28 +0200 Subject: [PATCH 04/13] Build tests are now using python on whales lib --- build/docker-bake.hcl | 10 +++++-- build/utils.py | 27 ----------------- tests/build_image/conftest.py | 37 +++++------------------- tests/build_image/test_build_version.py | 10 +++---- tests/build_image/test_poetry_version.py | 27 +++++++++-------- tests/build_image/test_python_version.py | 26 +++++++++-------- tests/build_image/test_registry.py | 2 +- tests/conftest.py | 20 ++++--------- tests/constants.py | 7 +++-- tests/publish_image/conftest.py | 7 ++--- tests/utils.py | 30 ++++++++++++++++++- 11 files changed, 93 insertions(+), 110 deletions(-) diff --git a/build/docker-bake.hcl b/build/docker-bake.hcl index 6019400..b32e770 100644 --- a/build/docker-bake.hcl +++ b/build/docker-bake.hcl @@ -15,9 +15,13 @@ target "python-poetry" { context = CONTEXT matrix = { - python_version = ["3.9.16", "3.10.11", "3.11.3"] - os_variant = ["bullseye", "slim-bullseye"] - poetry_version = ["1.3.2", "1.4.2", "1.5.1"] + #python_version = ["3.9.16", "3.10.11", "3.11.3"] + #os_variant = ["bullseye", "slim-bullseye"] + #poetry_version = ["1.3.2", "1.4.2", "1.5.1"] + + python_version = ["3.9.16"] + os_variant = ["slim-bullseye"] + poetry_version = ["1.5.1"] } args = { diff --git a/build/utils.py b/build/utils.py index a275194..d4dddc8 100644 --- a/build/utils.py +++ b/build/utils.py @@ -1,5 +1,4 @@ from pathlib import Path -from python_on_whales import DockerClient def get_context() -> Path: @@ -9,29 +8,3 @@ def get_context() -> Path: def get_docker_bake_file() -> Path: docker_bake_file: Path = Path(__file__).parent.resolve() / "docker-bake.hcl" return docker_bake_file - - -def extract_image_tags_from_build_config(build_config: dict) -> list[str]: - image_tags: list[str] = [] - targets: dict = build_config["target"] - for value in targets.values(): - image_tags.extend(value["tags"]) - return image_tags - - -def generate_image_tags( - bake_file: Path, context: Path, version: str -) -> list[str]: - pow_docker_client: DockerClient = DockerClient() - build_config: dict = pow_docker_client.buildx.bake( - targets=["python-poetry"], - files=[bake_file], - variables=dict( - REGISTRY="localhost:5000", - CONTEXT=str(context), - IMAGE_VERSION=version, - ), - print=True, - ) - images_tags = extract_image_tags_from_build_config(build_config) - return images_tags diff --git a/tests/build_image/conftest.py b/tests/build_image/conftest.py index 40e2de4..dd25fe8 100644 --- a/tests/build_image/conftest.py +++ b/tests/build_image/conftest.py @@ -1,22 +1,15 @@ -from time import sleep - import pytest -from docker.client import DockerClient -from docker.models.containers import Container -from python_on_whales import Builder -from python_on_whales import DockerClient as PowDockerClient -from slugify import slugify +from python_on_whales import Builder, DockerClient -from build.utils import extract_image_tags_from_build_config from tests.constants import ( BAKE_FILE, CONTEXT, REGISTRY_PASSWORD, REGISTRY_USERNAME, - SLEEP_TIME, VERSION, ) from tests.registry_container import DockerRegistryContainer +from tests.utils import extract_image_references_from_build_config @pytest.fixture(scope="package") @@ -31,16 +24,16 @@ def registry_container() -> DockerRegistryContainer: @pytest.fixture(scope="package") def images( - pow_docker_client: PowDockerClient, + docker_client: DockerClient, pow_buildx_builder: Builder, registry_container: DockerRegistryContainer, ): - pow_docker_client.login( + docker_client.login( server=registry_container.get_registry(), username=REGISTRY_USERNAME, password=REGISTRY_PASSWORD, ) - build_config: dict = pow_docker_client.buildx.bake( + build_config: dict = docker_client.buildx.bake( targets=["python-poetry"], builder=pow_buildx_builder, files=[BAKE_FILE], @@ -51,21 +44,7 @@ def images( ), push=True, ) - image_tags: list[str] = extract_image_tags_from_build_config(build_config) - yield image_tags - - -@pytest.fixture(scope="function") -def test_container(docker_client: DockerClient, request): - image_tag: str = request.param - image_name: str = slugify(image_tag) - test_container: Container = docker_client.containers.run( - image_tag, - name=image_name, - detach=True, - tty=True, + image_references: list[str] = extract_image_references_from_build_config( + build_config ) - sleep(SLEEP_TIME) - yield test_container - test_container.stop() - test_container.remove() + yield image_references diff --git a/tests/build_image/test_build_version.py b/tests/build_image/test_build_version.py index 9d44982..6416553 100644 --- a/tests/build_image/test_build_version.py +++ b/tests/build_image/test_build_version.py @@ -1,12 +1,12 @@ import pytest -from tests.constants import IMAGE_TAGS, VERSION +from tests.constants import IMAGE_REFERENCES, VERSION from tests.utils import ImageTagComponents -@pytest.mark.parametrize("image_tag", IMAGE_TAGS) -def test_build_version(image_tag) -> None: - components: ImageTagComponents = ImageTagComponents.create_from_tag( - image_tag +@pytest.mark.parametrize("image_reference", IMAGE_REFERENCES) +def test_build_version(image_reference) -> None: + components: ImageTagComponents = ImageTagComponents.create_from_reference( + image_reference ) assert components.version == VERSION diff --git a/tests/build_image/test_poetry_version.py b/tests/build_image/test_poetry_version.py index 667eb96..beab082 100644 --- a/tests/build_image/test_poetry_version.py +++ b/tests/build_image/test_poetry_version.py @@ -1,18 +1,21 @@ import pytest -from docker.models.containers import Container +from python_on_whales import Container, DockerClient -from tests.constants import IMAGE_TAGS +from tests.constants import IMAGE_REFERENCES from tests.utils import ImageTagComponents -@pytest.mark.parametrize("test_container", IMAGE_TAGS, indirect=True) +@pytest.mark.parametrize("image_reference", IMAGE_REFERENCES) @pytest.mark.usefixtures("images") -def test_poetry_configuration(test_container: Container) -> None: - image_tag_components: ImageTagComponents = ( - ImageTagComponents.create_from_tag(test_container.image.tags[0]) - ) - - (exit_code, output) = test_container.exec_run(["poetry", "--version"]) - assert exit_code == 0 - - assert image_tag_components.poetry_version in output.decode("utf-8") +def test_poetry_configuration( + docker_client: DockerClient, image_reference: str +) -> None: + container: Container + with docker_client.container.run( + image_reference, detach=True, interactive=True, tty=True + ) as container: + output = container.execute(["poetry", "--version"]) + image_tag_components: ImageTagComponents = ( + ImageTagComponents.create_from_reference(image_reference) + ) + assert image_tag_components.poetry_version in output diff --git a/tests/build_image/test_python_version.py b/tests/build_image/test_python_version.py index fb9a631..9f72ee6 100644 --- a/tests/build_image/test_python_version.py +++ b/tests/build_image/test_python_version.py @@ -1,20 +1,22 @@ import pytest -from docker.models.containers import Container +from python_on_whales import Container, DockerClient -from tests.constants import IMAGE_TAGS +from tests.constants import IMAGE_REFERENCES from tests.utils import ImageTagComponents -@pytest.mark.parametrize("test_container", IMAGE_TAGS, indirect=True) +@pytest.mark.parametrize("image_reference", IMAGE_REFERENCES) @pytest.mark.usefixtures("images") def test_python_version( - test_container: Container, + docker_client: DockerClient, + image_reference: str, ) -> None: - image_tag_components: ImageTagComponents = ( - ImageTagComponents.create_from_tag(test_container.image.tags[0]) - ) - - (exit_code, output) = test_container.exec_run(["python", "--version"]) - assert exit_code == 0 - - assert image_tag_components.python_version in output.decode("utf-8") + container: Container + with docker_client.container.run( + image_reference, detach=True, interactive=True, tty=True + ) as container: + output = container.execute(["python", "--version"]) + image_tag_components: ImageTagComponents = ( + ImageTagComponents.create_from_reference(image_reference) + ) + assert image_tag_components.python_version in output diff --git a/tests/build_image/test_registry.py b/tests/build_image/test_registry.py index 1e141a4..98a85e3 100644 --- a/tests/build_image/test_registry.py +++ b/tests/build_image/test_registry.py @@ -43,7 +43,7 @@ def test_registry_with_images( response_image_tags: list[str] = response.json()["tags"] image_tags: list[str] = [ - ImageTagComponents.create_from_tag(reference).tag + ImageTagComponents.create_from_reference(reference).tag for reference in images ] difference = set(image_tags).difference(set(response_image_tags)) diff --git a/tests/conftest.py b/tests/conftest.py index 136b065..a594d10 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,25 +1,17 @@ -import docker import pytest -from docker.client import DockerClient -from python_on_whales import Builder -from python_on_whales import DockerClient as PowDockerClient +from python_on_whales import DockerClient, Builder @pytest.fixture(scope="session") def docker_client() -> DockerClient: - return docker.from_env() + return DockerClient() @pytest.fixture(scope="session") -def pow_docker_client() -> PowDockerClient: - return PowDockerClient() - - -@pytest.fixture(scope="session") -def pow_buildx_builder(pow_docker_client: PowDockerClient) -> Builder: - builder: Builder = pow_docker_client.buildx.create( +def pow_buildx_builder(docker_client: DockerClient) -> Builder: + builder: Builder = docker_client.buildx.create( driver="docker-container", driver_options=dict(network="host") ) yield builder - pow_docker_client.buildx.stop(builder) - pow_docker_client.buildx.remove(builder) + docker_client.buildx.stop(builder) + docker_client.buildx.remove(builder) diff --git a/tests/constants.py b/tests/constants.py index 9dcdf56..25c7ae2 100644 --- a/tests/constants.py +++ b/tests/constants.py @@ -3,7 +3,8 @@ from semver import VersionInfo -from build.utils import generate_image_tags, get_context, get_docker_bake_file +from build.utils import get_context, get_docker_bake_file +from tests.utils import generate_image_references SLEEP_TIME: float = 3.0 REGISTRY_USERNAME: str = "foo" @@ -15,4 +16,6 @@ ) BAKE_FILE: Path = get_docker_bake_file() CONTEXT: Path = get_context() -IMAGE_TAGS: list[str] = generate_image_tags(BAKE_FILE, CONTEXT, VERSION) +IMAGE_REFERENCES: list[str] = generate_image_references( + BAKE_FILE, CONTEXT, VERSION +) diff --git a/tests/publish_image/conftest.py b/tests/publish_image/conftest.py index 3fb45ef..b1e6262 100644 --- a/tests/publish_image/conftest.py +++ b/tests/publish_image/conftest.py @@ -1,6 +1,6 @@ import pytest from click.testing import CliRunner -from docker.client import DockerClient +from python_on_whales import DockerClient, Image @pytest.fixture(scope="package") @@ -12,6 +12,5 @@ def cli_runner() -> CliRunner: @pytest.fixture(scope="package") def cleanup_images(docker_client: DockerClient): yield - for old_image in docker_client.images.list("pfeiffermax/python-poetry"): - for tag in old_image.tags: - docker_client.images.remove(tag, force=True) + images: list[Image] = docker_client.image.list("pfeiffermax/python-poetry") + docker_client.image.remove(images) diff --git a/tests/utils.py b/tests/utils.py index 35242ff..07861e0 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -1,6 +1,8 @@ from dataclasses import dataclass from docker_image import reference +from python_on_whales import DockerClient +from pathlib import Path @dataclass @@ -14,7 +16,7 @@ class ImageTagComponents: python_version: str @classmethod - def create_from_tag(cls, tag: str): + def create_from_reference(cls, tag: str): ref = reference.Reference.parse(tag) registry: str = ref.repository["domain"] image_name: str = ref.repository["path"] @@ -54,3 +56,29 @@ def create_from_tag(cls, tag: str): def create_version_tag_for_example_images(version: str, target: str) -> str: version_tag: str = f"{version}-{target}" return version_tag + + +def extract_image_references_from_build_config(build_config: dict) -> list[str]: + image_tags: list[str] = [] + targets: dict = build_config["target"] + for value in targets.values(): + image_tags.extend(value["tags"]) + return image_tags + + +def generate_image_references( + bake_file: Path, context: Path, version: str +) -> list[str]: + pow_docker_client: DockerClient = DockerClient() + build_config: dict = pow_docker_client.buildx.bake( + targets=["python-poetry"], + files=[bake_file], + variables=dict( + REGISTRY="localhost:5000", + CONTEXT=str(context), + IMAGE_VERSION=version, + ), + print=True, + ) + images_tags = extract_image_references_from_build_config(build_config) + return images_tags From 33cb6b92a97fa38df984951c2ca9da443a4d2e7a Mon Sep 17 00:00:00 2001 From: Max Pfeiffer Date: Sun, 9 Jul 2023 21:59:13 +0200 Subject: [PATCH 05/13] Removed obsolet code --- build/docker-bake.hcl | 10 +- poetry.lock | 296 +++++++++++------------- pyproject.toml | 2 - tests/publish_image/conftest.py | 7 - tests/publish_image/test_cli.py | 3 - tests/publish_image/test_cli_and_env.py | 2 - tests/publish_image/test_env.py | 3 - 7 files changed, 136 insertions(+), 187 deletions(-) diff --git a/build/docker-bake.hcl b/build/docker-bake.hcl index b32e770..6019400 100644 --- a/build/docker-bake.hcl +++ b/build/docker-bake.hcl @@ -15,13 +15,9 @@ target "python-poetry" { context = CONTEXT matrix = { - #python_version = ["3.9.16", "3.10.11", "3.11.3"] - #os_variant = ["bullseye", "slim-bullseye"] - #poetry_version = ["1.3.2", "1.4.2", "1.5.1"] - - python_version = ["3.9.16"] - os_variant = ["slim-bullseye"] - poetry_version = ["1.5.1"] + python_version = ["3.9.16", "3.10.11", "3.11.3"] + os_variant = ["bullseye", "slim-bullseye"] + poetry_version = ["1.3.2", "1.4.2", "1.5.1"] } args = { diff --git a/poetry.lock b/poetry.lock index f0ef2e1..5fcd4d2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2,14 +2,14 @@ [[package]] name = "astroid" -version = "2.15.5" +version = "2.15.6" description = "An abstract syntax tree for Python with inference support." category = "dev" optional = false python-versions = ">=3.7.2" files = [ - {file = "astroid-2.15.5-py3-none-any.whl", hash = "sha256:078e5212f9885fa85fbb0cf0101978a336190aadea6e13305409d099f71b2324"}, - {file = "astroid-2.15.5.tar.gz", hash = "sha256:1039262575027b441137ab4a62a793a9b43defb42c32d5670f38686207cd780f"}, + {file = "astroid-2.15.6-py3-none-any.whl", hash = "sha256:389656ca57b6108f939cf5d2f9a2a825a3be50ba9d589670f393236e0a03b91c"}, + {file = "astroid-2.15.6.tar.gz", hash = "sha256:903f024859b7c7687d7a7f3a3f73b17301f8e42dfd9cc9df9d4418172d3e2dbd"}, ] [package.dependencies] @@ -128,87 +128,87 @@ files = [ [[package]] name = "charset-normalizer" -version = "3.1.0" +version = "3.2.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." category = "main" optional = false python-versions = ">=3.7.0" files = [ - {file = "charset-normalizer-3.1.0.tar.gz", hash = "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-win32.whl", hash = "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-win32.whl", hash = "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-win32.whl", hash = "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-win32.whl", hash = "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-win32.whl", hash = "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b"}, - {file = "charset_normalizer-3.1.0-py3-none-any.whl", hash = "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d"}, + {file = "charset-normalizer-3.2.0.tar.gz", hash = "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-win32.whl", hash = "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-win32.whl", hash = "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-win32.whl", hash = "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-win32.whl", hash = "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-win32.whl", hash = "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80"}, + {file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"}, ] [[package]] @@ -360,7 +360,7 @@ files = [ name = "docker" version = "6.1.3" description = "A Python library for the Docker Engine API." -category = "main" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -395,14 +395,14 @@ regex = ">=2019.4.14" [[package]] name = "exceptiongroup" -version = "1.1.1" +version = "1.1.2" description = "Backport of PEP 654 (exception groups)" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.1.1-py3-none-any.whl", hash = "sha256:232c37c63e4f682982c8b6459f33a8981039e5fb8756b2074364e5055c498c9e"}, - {file = "exceptiongroup-1.1.1.tar.gz", hash = "sha256:d484c3090ba2889ae2928419117447a14daf3c1231d5e30d0aae34f354f01785"}, + {file = "exceptiongroup-1.1.2-py3-none-any.whl", hash = "sha256:e346e69d186172ca7cf029c8c1d16235aa0e04035e5750b4b95039e65204328f"}, + {file = "exceptiongroup-1.1.2.tar.gz", hash = "sha256:12c3e887d6485d16943a309616de20ae5582633e0a2eda17f4e10fd61c1e8af5"}, ] [package.extras] @@ -428,7 +428,7 @@ testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "p name = "furl" version = "2.1.3" description = "URL manipulation made simple." -category = "main" +category = "dev" optional = false python-versions = "*" files = [ @@ -586,7 +586,7 @@ setuptools = "*" name = "orderedmultidict" version = "1.0.1" description = "Ordered Multivalue Dictionary" -category = "main" +category = "dev" optional = false python-versions = "*" files = [ @@ -601,7 +601,7 @@ six = ">=1.8.0" name = "packaging" version = "23.1" description = "Core utilities for Python packages" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -623,14 +623,14 @@ files = [ [[package]] name = "platformdirs" -version = "3.8.0" +version = "3.8.1" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "platformdirs-3.8.0-py3-none-any.whl", hash = "sha256:ca9ed98ce73076ba72e092b23d3c93ea6c4e186b3f1c3dad6edd98ff6ffcca2e"}, - {file = "platformdirs-3.8.0.tar.gz", hash = "sha256:b0cabcb11063d21a0b261d557acb0a9d2126350e63b70cdf7db6347baea456dc"}, + {file = "platformdirs-3.8.1-py3-none-any.whl", hash = "sha256:cec7b889196b9144d088e4c57d9ceef7374f6c39694ad1577a0aab50d27ea28c"}, + {file = "platformdirs-3.8.1.tar.gz", hash = "sha256:f87ca4fcff7d2b0f81c6a748a77973d7af0f4d526f98f308477c3c436c74d528"}, ] [package.extras] @@ -674,48 +674,48 @@ virtualenv = ">=20.10.0" [[package]] name = "pydantic" -version = "1.10.10" +version = "1.10.11" description = "Data validation and settings management using python type hints" category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:adad1ee4ab9888f12dac2529276704e719efcf472e38df7813f5284db699b4ec"}, - {file = "pydantic-1.10.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7a7db03339893feef2092ff7b1afc9497beed15ebd4af84c3042a74abce02d48"}, - {file = "pydantic-1.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67b3714b97ff84b2689654851c2426389bcabfac9080617bcf4306c69db606f6"}, - {file = "pydantic-1.10.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edfdf0a5abc5c9bf2052ebaec20e67abd52e92d257e4f2d30e02c354ed3e6030"}, - {file = "pydantic-1.10.10-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:20a3b30fd255eeeb63caa9483502ba96b7795ce5bf895c6a179b3d909d9f53a6"}, - {file = "pydantic-1.10.10-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:db4c7f7e60ca6f7d6c1785070f3e5771fcb9b2d88546e334d2f2c3934d949028"}, - {file = "pydantic-1.10.10-cp310-cp310-win_amd64.whl", hash = "sha256:a2d5be50ac4a0976817144c7d653e34df2f9436d15555189f5b6f61161d64183"}, - {file = "pydantic-1.10.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:566a04ba755e8f701b074ffb134ddb4d429f75d5dced3fbd829a527aafe74c71"}, - {file = "pydantic-1.10.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f79db3652ed743309f116ba863dae0c974a41b688242482638b892246b7db21d"}, - {file = "pydantic-1.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c62376890b819bebe3c717a9ac841a532988372b7e600e76f75c9f7c128219d5"}, - {file = "pydantic-1.10.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4870f13a4fafd5bc3e93cff3169222534fad867918b188e83ee0496452978437"}, - {file = "pydantic-1.10.10-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:990027e77cda6072a566e433b6962ca3b96b4f3ae8bd54748e9d62a58284d9d7"}, - {file = "pydantic-1.10.10-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8c40964596809eb616d94f9c7944511f620a1103d63d5510440ed2908fc410af"}, - {file = "pydantic-1.10.10-cp311-cp311-win_amd64.whl", hash = "sha256:ea9eebc2ebcba3717e77cdeee3f6203ffc0e78db5f7482c68b1293e8cc156e5e"}, - {file = "pydantic-1.10.10-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:762aa598f79b4cac2f275d13336b2dd8662febee2a9c450a49a2ab3bec4b385f"}, - {file = "pydantic-1.10.10-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6dab5219659f95e357d98d70577b361383057fb4414cfdb587014a5f5c595f7b"}, - {file = "pydantic-1.10.10-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3d4ee957a727ccb5a36f1b0a6dbd9fad5dedd2a41eada99a8df55c12896e18d"}, - {file = "pydantic-1.10.10-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b69f9138dec566962ec65623c9d57bee44412d2fc71065a5f3ebb3820bdeee96"}, - {file = "pydantic-1.10.10-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7aa75d1bd9cc275cf9782f50f60cddaf74cbaae19b6ada2a28e737edac420312"}, - {file = "pydantic-1.10.10-cp37-cp37m-win_amd64.whl", hash = "sha256:9f62a727f5c590c78c2d12fda302d1895141b767c6488fe623098f8792255fe5"}, - {file = "pydantic-1.10.10-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:aac218feb4af73db8417ca7518fb3bade4534fcca6e3fb00f84966811dd94450"}, - {file = "pydantic-1.10.10-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:88546dc10a40b5b52cae87d64666787aeb2878f9a9b37825aedc2f362e7ae1da"}, - {file = "pydantic-1.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c41bbaae89e32fc582448e71974de738c055aef5ab474fb25692981a08df808a"}, - {file = "pydantic-1.10.10-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b71bd504d1573b0b722ae536e8ffb796bedeef978979d076bf206e77dcc55a5"}, - {file = "pydantic-1.10.10-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e088e3865a2270ecbc369924cd7d9fbc565667d9158e7f304e4097ebb9cf98dd"}, - {file = "pydantic-1.10.10-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3403a090db45d4027d2344859d86eb797484dfda0706cf87af79ace6a35274ef"}, - {file = "pydantic-1.10.10-cp38-cp38-win_amd64.whl", hash = "sha256:e0014e29637125f4997c174dd6167407162d7af0da73414a9340461ea8573252"}, - {file = "pydantic-1.10.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9965e49c6905840e526e5429b09e4c154355b6ecc0a2f05492eda2928190311d"}, - {file = "pydantic-1.10.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:748d10ab6089c5d196e1c8be9de48274f71457b01e59736f7a09c9dc34f51887"}, - {file = "pydantic-1.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86936c383f7c38fd26d35107eb669c85d8f46dfceae873264d9bab46fe1c7dde"}, - {file = "pydantic-1.10.10-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7a26841be620309a9697f5b1ffc47dce74909e350c5315ccdac7a853484d468a"}, - {file = "pydantic-1.10.10-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:409b810f387610cc7405ab2fa6f62bdf7ea485311845a242ebc0bd0496e7e5ac"}, - {file = "pydantic-1.10.10-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ce937a2a2c020bcad1c9fde02892392a1123de6dda906ddba62bfe8f3e5989a2"}, - {file = "pydantic-1.10.10-cp39-cp39-win_amd64.whl", hash = "sha256:37ebddef68370e6f26243acc94de56d291e01227a67b2ace26ea3543cf53dd5f"}, - {file = "pydantic-1.10.10-py3-none-any.whl", hash = "sha256:a5939ec826f7faec434e2d406ff5e4eaf1716eb1f247d68cd3d0b3612f7b4c8a"}, - {file = "pydantic-1.10.10.tar.gz", hash = "sha256:3b8d5bd97886f9eb59260594207c9f57dce14a6f869c6ceea90188715d29921a"}, + {file = "pydantic-1.10.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ff44c5e89315b15ff1f7fdaf9853770b810936d6b01a7bcecaa227d2f8fe444f"}, + {file = "pydantic-1.10.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a6c098d4ab5e2d5b3984d3cb2527e2d6099d3de85630c8934efcfdc348a9760e"}, + {file = "pydantic-1.10.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:16928fdc9cb273c6af00d9d5045434c39afba5f42325fb990add2c241402d151"}, + {file = "pydantic-1.10.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0588788a9a85f3e5e9ebca14211a496409cb3deca5b6971ff37c556d581854e7"}, + {file = "pydantic-1.10.11-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e9baf78b31da2dc3d3f346ef18e58ec5f12f5aaa17ac517e2ffd026a92a87588"}, + {file = "pydantic-1.10.11-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:373c0840f5c2b5b1ccadd9286782852b901055998136287828731868027a724f"}, + {file = "pydantic-1.10.11-cp310-cp310-win_amd64.whl", hash = "sha256:c3339a46bbe6013ef7bdd2844679bfe500347ac5742cd4019a88312aa58a9847"}, + {file = "pydantic-1.10.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:08a6c32e1c3809fbc49debb96bf833164f3438b3696abf0fbeceb417d123e6eb"}, + {file = "pydantic-1.10.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a451ccab49971af043ec4e0d207cbc8cbe53dbf148ef9f19599024076fe9c25b"}, + {file = "pydantic-1.10.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b02d24f7b2b365fed586ed73582c20f353a4c50e4be9ba2c57ab96f8091ddae"}, + {file = "pydantic-1.10.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f34739a89260dfa420aa3cbd069fbcc794b25bbe5c0a214f8fb29e363484b66"}, + {file = "pydantic-1.10.11-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e297897eb4bebde985f72a46a7552a7556a3dd11e7f76acda0c1093e3dbcf216"}, + {file = "pydantic-1.10.11-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d185819a7a059550ecb85d5134e7d40f2565f3dd94cfd870132c5f91a89cf58c"}, + {file = "pydantic-1.10.11-cp311-cp311-win_amd64.whl", hash = "sha256:4400015f15c9b464c9db2d5d951b6a780102cfa5870f2c036d37c23b56f7fc1b"}, + {file = "pydantic-1.10.11-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2417de68290434461a266271fc57274a138510dca19982336639484c73a07af6"}, + {file = "pydantic-1.10.11-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:331c031ba1554b974c98679bd0780d89670d6fd6f53f5d70b10bdc9addee1713"}, + {file = "pydantic-1.10.11-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8268a735a14c308923e8958363e3a3404f6834bb98c11f5ab43251a4e410170c"}, + {file = "pydantic-1.10.11-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:44e51ba599c3ef227e168424e220cd3e544288c57829520dc90ea9cb190c3248"}, + {file = "pydantic-1.10.11-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d7781f1d13b19700b7949c5a639c764a077cbbdd4322ed505b449d3ca8edcb36"}, + {file = "pydantic-1.10.11-cp37-cp37m-win_amd64.whl", hash = "sha256:7522a7666157aa22b812ce14c827574ddccc94f361237ca6ea8bb0d5c38f1629"}, + {file = "pydantic-1.10.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bc64eab9b19cd794a380179ac0e6752335e9555d214cfcb755820333c0784cb3"}, + {file = "pydantic-1.10.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8dc77064471780262b6a68fe67e013298d130414d5aaf9b562c33987dbd2cf4f"}, + {file = "pydantic-1.10.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe429898f2c9dd209bd0632a606bddc06f8bce081bbd03d1c775a45886e2c1cb"}, + {file = "pydantic-1.10.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:192c608ad002a748e4a0bed2ddbcd98f9b56df50a7c24d9a931a8c5dd053bd3d"}, + {file = "pydantic-1.10.11-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ef55392ec4bb5721f4ded1096241e4b7151ba6d50a50a80a2526c854f42e6a2f"}, + {file = "pydantic-1.10.11-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:41e0bb6efe86281623abbeeb0be64eab740c865388ee934cd3e6a358784aca6e"}, + {file = "pydantic-1.10.11-cp38-cp38-win_amd64.whl", hash = "sha256:265a60da42f9f27e0b1014eab8acd3e53bd0bad5c5b4884e98a55f8f596b2c19"}, + {file = "pydantic-1.10.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:469adf96c8e2c2bbfa655fc7735a2a82f4c543d9fee97bd113a7fb509bf5e622"}, + {file = "pydantic-1.10.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e6cbfbd010b14c8a905a7b10f9fe090068d1744d46f9e0c021db28daeb8b6de1"}, + {file = "pydantic-1.10.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abade85268cc92dff86d6effcd917893130f0ff516f3d637f50dadc22ae93999"}, + {file = "pydantic-1.10.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e9738b0f2e6c70f44ee0de53f2089d6002b10c33264abee07bdb5c7f03038303"}, + {file = "pydantic-1.10.11-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:787cf23e5a0cde753f2eabac1b2e73ae3844eb873fd1f5bdbff3048d8dbb7604"}, + {file = "pydantic-1.10.11-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:174899023337b9fc685ac8adaa7b047050616136ccd30e9070627c1aaab53a13"}, + {file = "pydantic-1.10.11-cp39-cp39-win_amd64.whl", hash = "sha256:1954f8778489a04b245a1e7b8b22a9d3ea8ef49337285693cf6959e4b757535e"}, + {file = "pydantic-1.10.11-py3-none-any.whl", hash = "sha256:008c5e266c8aada206d0627a011504e14268a62091450210eda7c07fabe6963e"}, + {file = "pydantic-1.10.11.tar.gz", hash = "sha256:f66d479cf7eb331372c470614be6511eae96f1f120344c25f3f9bb59fb1b5528"}, ] [package.dependencies] @@ -813,29 +813,11 @@ tqdm = "*" typer = ">=0.4.1" typing-extensions = "*" -[[package]] -name = "python-slugify" -version = "8.0.1" -description = "A Python slugify application that also handles Unicode" -category = "dev" -optional = false -python-versions = ">=3.7" -files = [ - {file = "python-slugify-8.0.1.tar.gz", hash = "sha256:ce0d46ddb668b3be82f4ed5e503dbc33dd815d83e2eb6824211310d3fb172a27"}, - {file = "python_slugify-8.0.1-py2.py3-none-any.whl", hash = "sha256:70ca6ea68fe63ecc8fa4fcf00ae651fc8a5d02d93dcd12ae6d4fc7ca46c4d395"}, -] - -[package.dependencies] -text-unidecode = ">=1.3" - -[package.extras] -unidecode = ["Unidecode (>=1.1.1)"] - [[package]] name = "pywin32" version = "306" description = "Python for Window Extensions" -category = "main" +category = "dev" optional = false python-versions = "*" files = [ @@ -1058,7 +1040,7 @@ testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs ( name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" -category = "main" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -1100,18 +1082,6 @@ rabbitmq = ["pika"] redis = ["redis"] selenium = ["selenium"] -[[package]] -name = "text-unidecode" -version = "1.3" -description = "The most basic Text::Unidecode port" -category = "dev" -optional = false -python-versions = "*" -files = [ - {file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"}, - {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"}, -] - [[package]] name = "tomli" version = "2.0.1" @@ -1181,14 +1151,14 @@ test = ["black (>=22.3.0,<23.0.0)", "coverage (>=6.2,<7.0)", "isort (>=5.0.6,<6. [[package]] name = "typing-extensions" -version = "4.7.0" +version = "4.7.1" description = "Backported and Experimental Type Hints for Python 3.7+" category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "typing_extensions-4.7.0-py3-none-any.whl", hash = "sha256:5d8c9dac95c27d20df12fb1d97b9793ab8b2af8a3a525e68c80e21060c161771"}, - {file = "typing_extensions-4.7.0.tar.gz", hash = "sha256:935ccf31549830cda708b42289d44b6f74084d616a00be651601a4f968e77c82"}, + {file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"}, + {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, ] [[package]] @@ -1234,7 +1204,7 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess name = "websocket-client" version = "1.6.1" description = "WebSocket client for Python with low level API options" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1335,4 +1305,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "3.9.*" -content-hash = "62a40d4549e06ef6effd68ede59472919fa921eaac5590d12ed215dc596aae0f" +content-hash = "991573e6ec825d568c3547097923659d65451c609c1180e551feb6ced6287a04" diff --git a/pyproject.toml b/pyproject.toml index 607b548..f18e90c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,6 @@ license = "MIT" [tool.poetry.dependencies] python = "3.9.*" click = "8.1.3" -docker = "6.1.3" python-on-whales = "0.62.0" [tool.poetry.dev-dependencies] @@ -22,7 +21,6 @@ semver = "3.0.0" testcontainers = "3.7.1" bcrypt = "4.0.1" docker-image-py = "0.1.12" -python-slugify = "8.0.1" furl = "2.1.3" # https://docs.pytest.org/en/latest/reference/customize.html diff --git a/tests/publish_image/conftest.py b/tests/publish_image/conftest.py index b1e6262..772370d 100644 --- a/tests/publish_image/conftest.py +++ b/tests/publish_image/conftest.py @@ -7,10 +7,3 @@ def cli_runner() -> CliRunner: runner = CliRunner() return runner - - -@pytest.fixture(scope="package") -def cleanup_images(docker_client: DockerClient): - yield - images: list[Image] = docker_client.image.list("pfeiffermax/python-poetry") - docker_client.image.remove(images) diff --git a/tests/publish_image/test_cli.py b/tests/publish_image/test_cli.py index e2d97fe..67aa7d0 100644 --- a/tests/publish_image/test_cli.py +++ b/tests/publish_image/test_cli.py @@ -1,4 +1,3 @@ -import pytest from click.testing import CliRunner, Result from python_on_whales import DockerException @@ -7,7 +6,6 @@ from tests.registry_container import DockerRegistryContainer -@pytest.mark.usefixtures("cleanup_images") def test_registry_with_credentials(cli_runner: CliRunner): with DockerRegistryContainer( username=REGISTRY_USERNAME, password=REGISTRY_PASSWORD @@ -28,7 +26,6 @@ def test_registry_with_credentials(cli_runner: CliRunner): assert result.exit_code == 0 -@pytest.mark.usefixtures("cleanup_images") def test_registry_with_wrong_credentials(cli_runner: CliRunner): with DockerRegistryContainer( username=REGISTRY_USERNAME, password=REGISTRY_PASSWORD diff --git a/tests/publish_image/test_cli_and_env.py b/tests/publish_image/test_cli_and_env.py index f582d8c..4e8c748 100644 --- a/tests/publish_image/test_cli_and_env.py +++ b/tests/publish_image/test_cli_and_env.py @@ -1,10 +1,8 @@ -import pytest from click.testing import CliRunner, Result from build.publish import main -@pytest.mark.usefixtures("cleanup_images") def test_missing_options_and_env(cli_runner: CliRunner): result: Result = cli_runner.invoke(main) assert result.exit_code == 2 diff --git a/tests/publish_image/test_env.py b/tests/publish_image/test_env.py index 5a46355..caa0537 100644 --- a/tests/publish_image/test_env.py +++ b/tests/publish_image/test_env.py @@ -1,4 +1,3 @@ -import pytest from click.testing import CliRunner, Result from python_on_whales import DockerException @@ -7,7 +6,6 @@ from tests.registry_container import DockerRegistryContainer -@pytest.mark.usefixtures("cleanup_images") def test_registry_with_credentials(cli_runner: CliRunner): with DockerRegistryContainer( username=REGISTRY_USERNAME, password=REGISTRY_PASSWORD @@ -24,7 +22,6 @@ def test_registry_with_credentials(cli_runner: CliRunner): assert result.exit_code == 0 -@pytest.mark.usefixtures("cleanup_images") def test_registry_with_wrong_credentials(cli_runner: CliRunner): with DockerRegistryContainer( username=REGISTRY_USERNAME, password=REGISTRY_PASSWORD From ba52e4e19acfd3cbff7b1e2b9c631d04deabd7ba Mon Sep 17 00:00:00 2001 From: Max Pfeiffer Date: Tue, 11 Jul 2023 22:11:02 +0200 Subject: [PATCH 06/13] Try to fix the tests with some wait time for registry container --- build/docker-bake.hcl | 4 ++-- tests/build_image/conftest.py | 5 +++++ tests/build_image/test_registry.py | 5 ----- tests/conftest.py | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/build/docker-bake.hcl b/build/docker-bake.hcl index 6019400..21f7b61 100644 --- a/build/docker-bake.hcl +++ b/build/docker-bake.hcl @@ -15,7 +15,7 @@ target "python-poetry" { context = CONTEXT matrix = { - python_version = ["3.9.16", "3.10.11", "3.11.3"] + python_version = ["3.9.17", "3.10.12", "3.11.4"] os_variant = ["bullseye", "slim-bullseye"] poetry_version = ["1.3.2", "1.4.2", "1.5.1"] } @@ -25,7 +25,7 @@ target "python-poetry" { OFFICIAL_PYTHON_IMAGE = "python:${python_version}-${os_variant}" } - platforms = ["linux/amd64", "linux/arm64"] + platforms = ["linux/amd64", "linux/arm/v5", "linux/arm/v7", "linux/arm64/v8"] tags = ["${REGISTRY}/pfeiffermax/python-poetry:${IMAGE_VERSION}-poetry${poetry_version}-python${python_version}-${os_variant}"] } \ No newline at end of file diff --git a/tests/build_image/conftest.py b/tests/build_image/conftest.py index dd25fe8..fd2d0d8 100644 --- a/tests/build_image/conftest.py +++ b/tests/build_image/conftest.py @@ -1,3 +1,4 @@ +from time import sleep import pytest from python_on_whales import Builder, DockerClient @@ -18,6 +19,10 @@ def registry_container() -> DockerRegistryContainer: username=REGISTRY_USERNAME, password=REGISTRY_PASSWORD ).with_bind_ports(5000, 5000) registry_container.start() + + # Wait for the registry container to come up + sleep(3.0) + yield registry_container registry_container.stop() diff --git a/tests/build_image/test_registry.py b/tests/build_image/test_registry.py index 98a85e3..a80ae88 100644 --- a/tests/build_image/test_registry.py +++ b/tests/build_image/test_registry.py @@ -1,5 +1,3 @@ -from time import sleep - from furl import furl from requests import Response, get from requests.auth import HTTPBasicAuth @@ -12,9 +10,6 @@ def test_registry(registry_container: DockerRegistryContainer): - # Wait for the registry container to come up - sleep(1.0) - furl_item: furl = furl(f"http://{registry_container.get_registry()}") furl_item.path /= "v2/_catalog" diff --git a/tests/conftest.py b/tests/conftest.py index a594d10..d54bca2 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -4,7 +4,7 @@ @pytest.fixture(scope="session") def docker_client() -> DockerClient: - return DockerClient() + return DockerClient(debug=True) @pytest.fixture(scope="session") From 9adcd3452181c6d43825b15ccd56f24a19fd9697 Mon Sep 17 00:00:00 2001 From: Max Pfeiffer Date: Tue, 11 Jul 2023 22:30:53 +0200 Subject: [PATCH 07/13] Fixed the bake file --- build/docker-bake.hcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/docker-bake.hcl b/build/docker-bake.hcl index 21f7b61..bba8bf5 100644 --- a/build/docker-bake.hcl +++ b/build/docker-bake.hcl @@ -25,7 +25,7 @@ target "python-poetry" { OFFICIAL_PYTHON_IMAGE = "python:${python_version}-${os_variant}" } - platforms = ["linux/amd64", "linux/arm/v5", "linux/arm/v7", "linux/arm64/v8"] + platforms = ["linux/amd64", "linux/arm64/v8"] tags = ["${REGISTRY}/pfeiffermax/python-poetry:${IMAGE_VERSION}-poetry${poetry_version}-python${python_version}-${os_variant}"] } \ No newline at end of file From ee9050622910f1422c1bc34e7b4b8470f12c0415 Mon Sep 17 00:00:00 2001 From: Max Pfeiffer Date: Fri, 14 Jul 2023 11:52:02 +0200 Subject: [PATCH 08/13] Try to leverage github cache for docker builds --- .github/workflows/pipeline.yml | 4 ++++ build/publish.py | 1 + tests/build_image/conftest.py | 1 + 3 files changed, 6 insertions(+) diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index 1a89a27..122a08b 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -39,6 +39,8 @@ jobs: steps: - name: Checkout Repository uses: actions/checkout@v3 + - name: Expose GitHub Runtime + uses: crazy-max/ghaction-github-runtime@v2 - name: Setup Python uses: actions/setup-python@v4 with: @@ -75,6 +77,8 @@ jobs: steps: - name: Checkout Repository uses: actions/checkout@v3 + - name: Expose GitHub Runtime + uses: crazy-max/ghaction-github-runtime@v2 - name: Get Git Commit Tag Name uses: olegtarasov/get-tag@v2.1 - name: Setup Python diff --git a/build/publish.py b/build/publish.py index c6a5d65..586ca8f 100644 --- a/build/publish.py +++ b/build/publish.py @@ -49,6 +49,7 @@ def main( targets=["python-poetry"], builder=builder, files=[bake_file], + set={"*.cache-from": "type=gha", "*.cache-to": "type=gha,mode=max"}, variables=variables, push=True, ) diff --git a/tests/build_image/conftest.py b/tests/build_image/conftest.py index fd2d0d8..2d45e33 100644 --- a/tests/build_image/conftest.py +++ b/tests/build_image/conftest.py @@ -42,6 +42,7 @@ def images( targets=["python-poetry"], builder=pow_buildx_builder, files=[BAKE_FILE], + set={"*.cache-to": "type=gha,mode=max", "*.cache-from": "type=gha"}, variables=dict( REGISTRY=registry_container.get_registry(), CONTEXT=CONTEXT, From 28def03b5c4a52b9a165eb791a15faeecf9ccadb Mon Sep 17 00:00:00 2001 From: Max Pfeiffer Date: Wed, 19 Jul 2023 18:41:42 +0200 Subject: [PATCH 09/13] Try fixing GitHub cache usage --- tests/test.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 tests/test.txt diff --git a/tests/test.txt b/tests/test.txt new file mode 100644 index 0000000..e650215 --- /dev/null +++ b/tests/test.txt @@ -0,0 +1,2 @@ +--set *.cache-to=type=gha,mode=max +--set *.cache-to="type=gha,mode=max" --set *.cache-from="type=gha" \ No newline at end of file From 70f4b82f2024a31f886e862080b8e852240f1e93 Mon Sep 17 00:00:00 2001 From: Max Pfeiffer Date: Wed, 19 Jul 2023 18:43:17 +0200 Subject: [PATCH 10/13] Try fixing GitHub cache usage --- build/publish.py | 2 +- tests/build_image/conftest.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/publish.py b/build/publish.py index 586ca8f..619dc69 100644 --- a/build/publish.py +++ b/build/publish.py @@ -49,7 +49,7 @@ def main( targets=["python-poetry"], builder=builder, files=[bake_file], - set={"*.cache-from": "type=gha", "*.cache-to": "type=gha,mode=max"}, + set={"*.cache-to": '"type=gha,mode=max"', "*.cache-from": '"type=gha"'}, variables=variables, push=True, ) diff --git a/tests/build_image/conftest.py b/tests/build_image/conftest.py index 2d45e33..d82a8da 100644 --- a/tests/build_image/conftest.py +++ b/tests/build_image/conftest.py @@ -42,7 +42,7 @@ def images( targets=["python-poetry"], builder=pow_buildx_builder, files=[BAKE_FILE], - set={"*.cache-to": "type=gha,mode=max", "*.cache-from": "type=gha"}, + set={"*.cache-to": '"type=gha,mode=max"', "*.cache-from": '"type=gha"'}, variables=dict( REGISTRY=registry_container.get_registry(), CONTEXT=CONTEXT, From 0458271d550c036443ad3335bb8aec842b9c39e2 Mon Sep 17 00:00:00 2001 From: Max Pfeiffer Date: Thu, 20 Jul 2023 17:41:42 +0200 Subject: [PATCH 11/13] Try to leave cache mode to make it work --- build/publish.py | 3 ++- tests/build_image/conftest.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/build/publish.py b/build/publish.py index 619dc69..edf5d77 100644 --- a/build/publish.py +++ b/build/publish.py @@ -49,7 +49,8 @@ def main( targets=["python-poetry"], builder=builder, files=[bake_file], - set={"*.cache-to": '"type=gha,mode=max"', "*.cache-from": '"type=gha"'}, + # set={"*.cache-to": '"type=gha,mode=max"', "*.cache-from": '"type=gha"'}, + set={"*.cache-to": '"type=gha"', "*.cache-from": '"type=gha"'}, variables=variables, push=True, ) diff --git a/tests/build_image/conftest.py b/tests/build_image/conftest.py index d82a8da..3a64e5e 100644 --- a/tests/build_image/conftest.py +++ b/tests/build_image/conftest.py @@ -42,7 +42,8 @@ def images( targets=["python-poetry"], builder=pow_buildx_builder, files=[BAKE_FILE], - set={"*.cache-to": '"type=gha,mode=max"', "*.cache-from": '"type=gha"'}, + # set={"*.cache-to": '"type=gha,mode=max"', "*.cache-from": '"type=gha"'}, + set={"*.cache-to": '"type=gha"', "*.cache-from": '"type=gha"'}, variables=dict( REGISTRY=registry_container.get_registry(), CONTEXT=CONTEXT, From fce2f950e9b9d16816159d2c5750ae4ee3e3a28b Mon Sep 17 00:00:00 2001 From: Max Pfeiffer Date: Thu, 20 Jul 2023 18:14:29 +0200 Subject: [PATCH 12/13] Try putting Github cache config in bake file --- build/docker-bake.hcl | 8 ++++++++ build/publish.py | 2 -- tests/build_image/conftest.py | 2 -- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/build/docker-bake.hcl b/build/docker-bake.hcl index bba8bf5..9a32ffa 100644 --- a/build/docker-bake.hcl +++ b/build/docker-bake.hcl @@ -28,4 +28,12 @@ target "python-poetry" { platforms = ["linux/amd64", "linux/arm64/v8"] tags = ["${REGISTRY}/pfeiffermax/python-poetry:${IMAGE_VERSION}-poetry${poetry_version}-python${python_version}-${os_variant}"] + + cache-to = [ + "type=gha,mode=max" + ] + + cache-from = [ + "type=gha" + ] } \ No newline at end of file diff --git a/build/publish.py b/build/publish.py index edf5d77..c6a5d65 100644 --- a/build/publish.py +++ b/build/publish.py @@ -49,8 +49,6 @@ def main( targets=["python-poetry"], builder=builder, files=[bake_file], - # set={"*.cache-to": '"type=gha,mode=max"', "*.cache-from": '"type=gha"'}, - set={"*.cache-to": '"type=gha"', "*.cache-from": '"type=gha"'}, variables=variables, push=True, ) diff --git a/tests/build_image/conftest.py b/tests/build_image/conftest.py index 3a64e5e..fd2d0d8 100644 --- a/tests/build_image/conftest.py +++ b/tests/build_image/conftest.py @@ -42,8 +42,6 @@ def images( targets=["python-poetry"], builder=pow_buildx_builder, files=[BAKE_FILE], - # set={"*.cache-to": '"type=gha,mode=max"', "*.cache-from": '"type=gha"'}, - set={"*.cache-to": '"type=gha"', "*.cache-from": '"type=gha"'}, variables=dict( REGISTRY=registry_container.get_registry(), CONTEXT=CONTEXT, From 6eacfe5368bcad7bfa2bf40d914071bd09db799d Mon Sep 17 00:00:00 2001 From: Max Pfeiffer Date: Sat, 22 Jul 2023 07:39:55 +0200 Subject: [PATCH 13/13] Parallelising tests --- .github/workflows/pipeline.yml | 45 +++++++++- build/publish.py | 16 ++++ poetry.lock | 147 ++++++++++++++++++++------------- pyproject.toml | 1 + tests/build_image/conftest.py | 10 +++ 5 files changed, 158 insertions(+), 61 deletions(-) diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index 122a08b..4ad8330 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -33,7 +33,7 @@ jobs: pylint build tests black --check . - run-tests: + run-build-image-tests: needs: code-quality runs-on: ubuntu-20.04 steps: @@ -63,15 +63,54 @@ jobs: - name: Run all tests with pytest run: | source .venv/bin/activate - pytest --cov + pytest tests/build_image --cov - name: Upload coverage to Codecov uses: codecov/codecov-action@v3 with: fail_ci_if_error: true token: ${{ secrets.CODECOV_TOKEN }} + run-publish-image-tests: + needs: code-quality + runs-on: ubuntu-20.04 + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + - name: Expose GitHub Runtime + uses: crazy-max/ghaction-github-runtime@v2 + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: 3.9 + - name: Install Poetry + uses: snok/install-poetry@v1 + with: + version: 1.4.1 + virtualenvs-in-project: true + - name: Load cached venv + id: cached-poetry-dependencies + uses: actions/cache@v3 + with: + path: .venv + key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }} + - name: Install dependencies + if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true' + run: | + poetry install --no-interaction --no-root + - name: Run all tests with pytest + run: | + source .venv/bin/activate + pytest tests/publish_image --cov + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v3 + with: + fail_ci_if_error: true + token: ${{ secrets.CODECOV_TOKEN }} + publish-all-images: - needs: run-tests + needs: + - run-build-image-tests + - run-publish-image-tests if: startsWith(github.ref, 'refs/tags/') runs-on: ubuntu-20.04 steps: diff --git a/build/publish.py b/build/publish.py index c6a5d65..8dec7f1 100644 --- a/build/publish.py +++ b/build/publish.py @@ -20,11 +20,18 @@ "--version-tag", envvar="GIT_TAG_NAME", required=True, help="Version Tag" ) @click.option("--registry", envvar="REGISTRY", help="Docker registry") +@click.option( + "--use-local-cache-storage-backend", + envvar="USE_LOCAL_CACHE_STORAGE_BACKEND", + is_flag=True, + help="Use local cache storage backend for docker builds", +) def main( docker_hub_username: str, docker_hub_password: str, version_tag: str, registry: str, + use_local_cache_storage_backend: bool, ) -> None: context: Path = get_context() bake_file: Path = get_docker_bake_file() @@ -32,6 +39,14 @@ def main( "CONTEXT": str(context), "IMAGE_VERSION": version_tag, } + + bake_file_overrides: dict = {} + if use_local_cache_storage_backend: + bake_file_overrides = { + "*.cache-to": "type=local,mode=max", + "*.cache-from": "type=local", + } + if registry: variables["REGISTRY"] = registry @@ -50,6 +65,7 @@ def main( builder=builder, files=[bake_file], variables=variables, + set=bake_file_overrides, push=True, ) print(build_config) diff --git a/poetry.lock b/poetry.lock index 5fcd4d2..3a52947 100644 --- a/poetry.lock +++ b/poetry.lock @@ -346,14 +346,14 @@ graph = ["objgraph (>=1.7.2)"] [[package]] name = "distlib" -version = "0.3.6" +version = "0.3.7" description = "Distribution utilities" category = "dev" optional = false python-versions = "*" files = [ - {file = "distlib-0.3.6-py2.py3-none-any.whl", hash = "sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e"}, - {file = "distlib-0.3.6.tar.gz", hash = "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46"}, + {file = "distlib-0.3.7-py2.py3-none-any.whl", hash = "sha256:2e24928bc811348f0feb63014e97aaae3037f2cf48712d51ae61df7fd6075057"}, + {file = "distlib-0.3.7.tar.gz", hash = "sha256:9dafe54b34a028eafd95039d5e5d4851a13734540f1331060d31c9916e7147a8"}, ] [[package]] @@ -442,14 +442,14 @@ six = ">=1.8.0" [[package]] name = "identify" -version = "2.5.24" +version = "2.5.25" description = "File identification library for Python" category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "identify-2.5.24-py2.py3-none-any.whl", hash = "sha256:986dbfb38b1140e763e413e6feb44cd731faf72d1909543178aa79b0e258265d"}, - {file = "identify-2.5.24.tar.gz", hash = "sha256:0aac67d5b4812498056d28a9a512a483f5085cc28640b02b258a59dac34301d4"}, + {file = "identify-2.5.25-py2.py3-none-any.whl", hash = "sha256:9df2489842707d431b38ce3410ef8df40da5b10a3e28a3fcac1a42523e956409"}, + {file = "identify-2.5.25.tar.gz", hash = "sha256:db4de0e758c0db8f81996816cd2f3f2f8c5c8d49a7fd02f3b4109aac6fd80e29"}, ] [package.extras] @@ -623,14 +623,14 @@ files = [ [[package]] name = "platformdirs" -version = "3.8.1" +version = "3.9.1" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "platformdirs-3.8.1-py3-none-any.whl", hash = "sha256:cec7b889196b9144d088e4c57d9ceef7374f6c39694ad1577a0aab50d27ea28c"}, - {file = "platformdirs-3.8.1.tar.gz", hash = "sha256:f87ca4fcff7d2b0f81c6a748a77973d7af0f4d526f98f308477c3c436c74d528"}, + {file = "platformdirs-3.9.1-py3-none-any.whl", hash = "sha256:ad8291ae0ae5072f66c16945166cb11c63394c7a3ad1b1bc9828ca3162da8c2f"}, + {file = "platformdirs-3.9.1.tar.gz", hash = "sha256:1b42b450ad933e981d56e59f1b97495428c9bd60698baab9f3eb3d00d5822421"}, ] [package.extras] @@ -794,6 +794,37 @@ pytest = ">=4.6" [package.extras] testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] +[[package]] +name = "pytest-dotenv" +version = "0.5.2" +description = "A py.test plugin that parses environment files before running tests" +category = "dev" +optional = false +python-versions = "*" +files = [ + {file = "pytest-dotenv-0.5.2.tar.gz", hash = "sha256:2dc6c3ac6d8764c71c6d2804e902d0ff810fa19692e95fe138aefc9b1aa73732"}, + {file = "pytest_dotenv-0.5.2-py3-none-any.whl", hash = "sha256:40a2cece120a213898afaa5407673f6bd924b1fa7eafce6bda0e8abffe2f710f"}, +] + +[package.dependencies] +pytest = ">=5.0.0" +python-dotenv = ">=0.9.1" + +[[package]] +name = "python-dotenv" +version = "1.0.0" +description = "Read key-value pairs from a .env file and set them as environment variables" +category = "dev" +optional = false +python-versions = ">=3.8" +files = [ + {file = "python-dotenv-1.0.0.tar.gz", hash = "sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba"}, + {file = "python_dotenv-1.0.0-py3-none-any.whl", hash = "sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a"}, +] + +[package.extras] +cli = ["click (>=5.0)"] + [[package]] name = "python-on-whales" version = "0.62.0" @@ -839,52 +870,52 @@ files = [ [[package]] name = "pyyaml" -version = "6.0" +version = "6.0.1" description = "YAML parser and emitter for Python" category = "dev" optional = false python-versions = ">=3.6" files = [ - {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, - {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, - {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, - {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, - {file = "PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"}, - {file = "PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"}, - {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"}, - {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"}, - {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"}, - {file = "PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"}, - {file = "PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"}, - {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"}, - {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"}, - {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"}, - {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"}, - {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"}, - {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"}, - {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"}, - {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"}, - {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"}, - {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"}, - {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"}, - {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"}, - {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, - {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, + {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, + {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, + {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, + {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, + {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, + {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, ] [[package]] @@ -1163,14 +1194,14 @@ files = [ [[package]] name = "urllib3" -version = "2.0.3" +version = "2.0.4" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "urllib3-2.0.3-py3-none-any.whl", hash = "sha256:48e7fafa40319d358848e1bc6809b208340fafe2096f1725d05d67443d0483d1"}, - {file = "urllib3-2.0.3.tar.gz", hash = "sha256:bee28b5e56addb8226c96f7f13ac28cb4c301dd5ea8a6ca179c0b9835e032825"}, + {file = "urllib3-2.0.4-py3-none-any.whl", hash = "sha256:de7df1803967d2c2a98e4b11bb7d6bd9210474c46e8a0401514e3a42a75ebde4"}, + {file = "urllib3-2.0.4.tar.gz", hash = "sha256:8d22f86aae8ef5e410d4f539fde9ce6b2113a001bb4d189e0aed70642d602b11"}, ] [package.extras] @@ -1181,14 +1212,14 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "virtualenv" -version = "20.23.1" +version = "20.24.1" description = "Virtual Python Environment builder" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "virtualenv-20.23.1-py3-none-any.whl", hash = "sha256:34da10f14fea9be20e0fd7f04aba9732f84e593dac291b757ce42e3368a39419"}, - {file = "virtualenv-20.23.1.tar.gz", hash = "sha256:8ff19a38c1021c742148edc4f81cb43d7f8c6816d2ede2ab72af5b84c749ade1"}, + {file = "virtualenv-20.24.1-py3-none-any.whl", hash = "sha256:01aacf8decd346cf9a865ae85c0cdc7f64c8caa07ff0d8b1dfc1733d10677442"}, + {file = "virtualenv-20.24.1.tar.gz", hash = "sha256:2ef6a237c31629da6442b0bcaa3999748108c7166318d1f55cc9f8d7294e97bd"}, ] [package.dependencies] @@ -1305,4 +1336,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "3.9.*" -content-hash = "991573e6ec825d568c3547097923659d65451c609c1180e551feb6ced6287a04" +content-hash = "364c1aa34a5a092c9b72769c718b34da1a3175092bf69bc53f4bc4b0b7ad24c1" diff --git a/pyproject.toml b/pyproject.toml index f18e90c..d42624d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,6 +14,7 @@ python-on-whales = "0.62.0" pylint = "2.17.4" pytest = "7.3.1" pytest-cov = "4.1.0" +pytest-dotenv = "0.5.2" coverage = "7.2.7" black = "23.3.0" pre-commit = "3.3.2" diff --git a/tests/build_image/conftest.py b/tests/build_image/conftest.py index fd2d0d8..a1265d3 100644 --- a/tests/build_image/conftest.py +++ b/tests/build_image/conftest.py @@ -11,6 +11,7 @@ ) from tests.registry_container import DockerRegistryContainer from tests.utils import extract_image_references_from_build_config +from os import getenv @pytest.fixture(scope="package") @@ -38,6 +39,14 @@ def images( username=REGISTRY_USERNAME, password=REGISTRY_PASSWORD, ) + + bake_file_overrides: dict = {} + if getenv("USE_LOCAL_CACHE_STORAGE_BACKEND"): + bake_file_overrides = { + "*.cache-to": "type=local,mode=max", + "*.cache-from": "type=local", + } + build_config: dict = docker_client.buildx.bake( targets=["python-poetry"], builder=pow_buildx_builder, @@ -47,6 +56,7 @@ def images( CONTEXT=CONTEXT, IMAGE_VERSION=VERSION, ), + set=bake_file_overrides, push=True, ) image_references: list[str] = extract_image_references_from_build_config(