diff --git a/.cirrus.yml b/.cirrus.yml index a51b805b..c6053af7 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -15,7 +15,7 @@ env: #### Cache-image names to test with (double-quotes around names are critical) #### # Google-cloud VM Images - IMAGE_SUFFIX: "c20250107t132430z-f41f40d13" + IMAGE_SUFFIX: "c20250131t121915z-f41f40d13" FEDORA_CACHE_IMAGE_NAME: "fedora-podman-py-${IMAGE_SUFFIX}" diff --git a/.github/workflows/publish-to-test-pypi.yml b/.github/workflows/publish-to-test-pypi.yml new file mode 100644 index 00000000..72f9643f --- /dev/null +++ b/.github/workflows/publish-to-test-pypi.yml @@ -0,0 +1,118 @@ +name: Publish Python 🐍 distribution 📦 to PyPI and TestPyPI + +on: push + +jobs: + build: + name: Build distribution 📦 + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.x" + + - name: Install pypa/build + run: >- + python3 -m + pip install + build + --user + - name: Build a binary wheel and a source tarball + run: python3 -m build + - name: Store the distribution packages + uses: actions/upload-artifact@v4 + with: + name: python-package-distributions + path: dist/ + + publish-to-pypi: + name: >- + Publish Python 🐍 distribution 📦 to PyPI + if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes + needs: + - build + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/podman + permissions: + id-token: write # IMPORTANT: mandatory for trusted publishing + + steps: + - name: Download all the dists + uses: actions/download-artifact@v4 + with: + name: python-package-distributions + path: dist/ + - name: Publish distribution 📦 to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + + github-release: + name: >- + Sign the Python 🐍 distribution 📦 with Sigstore + and upload them to GitHub Release + needs: + - publish-to-pypi + runs-on: ubuntu-latest + + permissions: + contents: write # IMPORTANT: mandatory for making GitHub Releases + id-token: write # IMPORTANT: mandatory for sigstore + + steps: + - name: Download all the dists + uses: actions/download-artifact@v4 + with: + name: python-package-distributions + path: dist/ + - name: Sign the dists with Sigstore + uses: sigstore/gh-action-sigstore-python@v3.0.0 + with: + inputs: >- + ./dist/*.tar.gz + ./dist/*.whl + - name: Create GitHub Release + env: + GITHUB_TOKEN: ${{ github.token }} + run: >- + gh release create + '${{ github.ref_name }}' + --repo '${{ github.repository }}' + --notes "" + - name: Upload artifact signatures to GitHub Release + env: + GITHUB_TOKEN: ${{ github.token }} + # Upload to GitHub Release using the `gh` CLI. + # `dist/` contains the built packages, and the + # sigstore-produced signatures and certificates. + run: >- + gh release upload + '${{ github.ref_name }}' dist/** + --repo '${{ github.repository }}' + + publish-to-testpypi: + name: Publish Python 🐍 distribution 📦 to TestPyPI + needs: + - build + runs-on: ubuntu-latest + + environment: + name: testpypi + url: https://test.pypi.org/p/podman + + permissions: + id-token: write # IMPORTANT: mandatory for trusted publishing + + steps: + - name: Download all the dists + uses: actions/download-artifact@v4 + with: + name: python-package-distributions + path: dist/ + - name: Publish distribution 📦 to TestPyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + repository-url: https://test.pypi.org/legacy/ diff --git a/.packit.yaml b/.packit.yaml index 40b2fe50..ffeab598 100644 --- a/.packit.yaml +++ b/.packit.yaml @@ -87,3 +87,25 @@ jobs: targets: - fedora-latest-stable skip_build: true + + - job: tests + trigger: pull_request + tmt_plan: /upstream/all + packages: [python-podman-fedora] + targets: + - fedora-all + + - job: tests + trigger: pull_request + tmt_plan: /upstream/base + packages: [python-podman-centos] + targets: + - centos-stream-9 + - centos-stream-10 + + - job: tests + trigger: pull_request + tmt_plan: /upstream/base + packages: [python-podman-rhel] + targets: + - epel-9 diff --git a/Makefile b/Makefile index cbf87e67..ce1f961b 100644 --- a/Makefile +++ b/Makefile @@ -13,9 +13,9 @@ export PODMAN_VERSION ?= "5.3.0" .PHONY: podman podman: rm dist/* || : - $(PYTHON) -m pip install --user -r requirements.txt + $(PYTHON) -m pip install -q build PODMAN_VERSION=$(PODMAN_VERSION) \ - $(PYTHON) setup.py sdist bdist bdist_wheel + $(PYTHON) -m build .PHONY: lint lint: tox @@ -26,6 +26,14 @@ tests: tox # see tox.ini for environment variable settings $(PYTHON) -m tox -e coverage,py39,py310,py311,py312,py313 +.PHONY: tests-ci-base-python +tests-ci-base-python: + $(PYTHON) -m tox -e coverage,py + +.PHONY: tests-ci-all-python +tests-ci-all-python: + $(PYTHON) -m tox -e coverage,py39,py310,py311,py312,py313 + .PHONY: unittest unittest: coverage run -m unittest discover -s podman/tests/unit diff --git a/README.md b/README.md index f2ffee71..b7b641d4 100644 --- a/README.md +++ b/README.md @@ -24,8 +24,9 @@ pip install podman ## Dependencies -* For runtime dependencies, see [requirements.txt](https://github.com/containers/podman-py/blob/main/requirements.txt). -* For testing and development dependencies, see [test-requirements.txt](https://github.com/containers/podman-py/blob/main/test-requirements.txt). +* For runtime dependencies, see \[dependencies\] in [pyproject.toml](https://github.com/containers/podman-py/blob/main/pyproject.toml) +* For testing and development dependencies, see \[project.optional.dependencies\] in [pyproject.toml](https://github.com/containers/podman-py/blob/main/pyproject.toml) + * The package is split in \[progress\_bar\], \[docs\], and \[test\] ## Example usage diff --git a/plans/main.fmf b/plans/main.fmf index 06e46b52..cb70fc96 100644 --- a/plans/main.fmf +++ b/plans/main.fmf @@ -11,16 +11,11 @@ prepare: - make - podman - python3-pip - - python3.9 - - python3.10 - - python3.11 - - python3.12 - - python3.13 - name: pip dependencies how: shell script: - - pip3 install -r test-requirements.txt + - pip3 install .[test] - name: ssh configuration how: shell @@ -36,20 +31,34 @@ prepare: # we want to change this to tag:stable once all the coverage tests are fixed filter: tag:lint - /tests: - summary: Run Python Podman Tests on upstream PRs + /base: + summary: Run Python Podman Tests on Upstream PRs for base Python discover+: - filter: tag:upstream + filter: tag:base + + /all: + summary: Run Python Podman Tests on Upstream PRs for all Python versions + prepare+: + - name: install all python versions + how: install + package: + - python3.9 + - python3.10 + - python3.11 + - python3.12 + - python3.13 + discover+: + filter: tag:matrix adjust+: enabled: false when: initiator is not defined or initiator != packit /downstream: - /tests: + /all: summary: Run Python Podman Tests on bodhi / errata and dist-git PRs discover+: - filter: tag:downstream + filter: tag:matrix adjust+: enabled: false diff --git a/podman/domain/containers_create.py b/podman/domain/containers_create.py index 523a9023..80d7f7c8 100644 --- a/podman/domain/containers_create.py +++ b/podman/domain/containers_create.py @@ -245,8 +245,8 @@ def create( read_only (bool): Mount the container's root filesystem as read only. read_write_tmpfs (bool): Mount temporary file systems as read write, in case of read_only options set to True. Default: False - restart_policy (dict[str, Union[str, int]]): Restart the container when it exits. remove (bool): Remove the container when it has finished running. Default: False. + restart_policy (dict[str, Union[str, int]]): Restart the container when it exits. Configured as a dictionary with keys: - Name: One of on-failure, or always. diff --git a/podman/domain/networks.py b/podman/domain/networks.py index bbc89539..98bd094b 100644 --- a/podman/domain/networks.py +++ b/podman/domain/networks.py @@ -111,6 +111,7 @@ def connect(self, container: Union[str, Container], *_, **kwargs) -> None: f"/networks/{self.name}/connect", data=json.dumps(data), headers={"Content-type": "application/json"}, + **kwargs, ) response.raise_for_status() diff --git a/pyproject.toml b/pyproject.toml index 5361b2fd..cc88c2bb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,32 +1,129 @@ -[tool.black] -line-length = 100 -skip-string-normalization = true -preview = true -target-version = ["py39"] -include = '\.pyi?$' -exclude = ''' -/( - \.git - | \.tox - | \.venv - | \.history - | build - | dist - | docs - | hack -)/ -''' -[tool.isort] -profile = "black" -line_length = 100 [build-system] -# Any changes should be copied into requirements.txt, setup.cfg, and/or test-requirements.txt -requires = [ - "setuptools>=46.4", -] +requires = ["setuptools>=46.4"] build-backend = "setuptools.build_meta" + +[project] +name = "podman" +dynamic = ["version"] +description = "Bindings for Podman RESTful API" +readme = "README.md" +license = {file = "LICENSE"} +requires-python = ">=3.9" +authors = [ + { name = "Brent Baude" }, + { name = "Jhon Honce", email = "jhonce@redhat.com" }, + { name = "Urvashi Mohnani" }, + { name = "Nicola Sella", email = "nsella@redhat.com" }, +] +keywords = [ + "libpod", + "podman", +] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Topic :: Software Development :: Libraries :: Python Modules", +] +# compatible releases +# ~= with version numbers +dependencies = [ + "requests >=2.24", + "tomli>=1.2.3; python_version<'3.11'", + "urllib3", +] + +[project.optional-dependencies] +progress_bar = [ + "rich >= 12.5.1", +] +docs = [ + "sphinx" +] +test = [ + "coverage", + "fixtures", + "pytest", + "requests-mock", + "tox", +] + +[project.urls] +"Bug Tracker" = "https://github.com/containers/podman-py/issues" +Homepage = "https://github.com/containers/podman-py" +"Libpod API" = "https://docs.podman.io/en/latest/_static/api.html" + [tool.pytest.ini_options] log_cli = true log_cli_level = "DEBUG" log_cli_format = "%(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s)" log_cli_date_format = "%Y-%m-%d %H:%M:%S" + +[tool.setuptools] +packages = ["podman"] + +[tool.setuptools.dynamic] +version = {attr = "podman.version.__version__"} + +[tool.ruff] +line-length = 100 +src = ["podman"] + +# This is the section where Black is mostly replaced with Ruff +[tool.ruff.format] +exclude = [ + ".git", + ".history", + ".tox", + ".venv", + "build", + "dist", + "docs", + "hack", +] +quote-style = "preserve" + +[tool.ruff.lint] +select = [ + # More stuff here https://docs.astral.sh/ruff/rules/ + "F", # Pyflakes + "E", # Pycodestyle Error + "W", # Pycodestyle Warning + "N", # PEP8 Naming + # TODO "UP", # Pyupgrade + # TODO "ANN", + # TODO "S", # Bandit + # "B", # Bugbear + "A", # flake-8-builtins + "YTT", # flake-8-2020 + "PLC", # Pylint Convention + "PLE", # Pylint Error + "PLW", # Pylint Warning +] +# Some checks should be enabled for code sanity disabled now +# to avoid changing too many lines +ignore = [ + "F821", # TODO Undefined name + "F541", # TODO f-string is missing placeholders + "F401", # TODO Module imported but unused + "F841", # TODO Local variable is assigned to but never used + "E402", # TODO Module level import not at top of file + "E741", # TODO ambiguous variable name + "E722", # TODO do not use bare 'except' + "E501", # TODO line too long + "N818", # TODO Error Suffix in exception name + "N80", # TODO Invalid Name + "ANN10", # Missing type annotation + "PLW2901", # TODO Redefined Loop Name +] +[tool.ruff.lint.flake8-builtins] +builtins-ignorelist = ["copyright", "all"] +[tool.ruff.lint.per-file-ignores] +"podman/tests/*.py" = ["S"] diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index f16a9878..00000000 --- a/requirements.txt +++ /dev/null @@ -1,7 +0,0 @@ -# Any changes should be copied into pyproject.toml -requests>=2.24 -setuptools -sphinx -tomli>=1.2.3; python_version<'3.11' -urllib3 -wheel diff --git a/ruff.toml b/ruff.toml deleted file mode 100644 index 84bceb20..00000000 --- a/ruff.toml +++ /dev/null @@ -1,49 +0,0 @@ - -line-length = 100 -[format] -exclude = [ - ".git", - ".venv", - ".history", - "build", - "dist", - "docs", - "hack", -] -quote-style = "preserve" -[lint] -select = [ - # More stuff here https://docs.astral.sh/ruff/rules/ - "F", # Pyflakes - "E", # Pycodestyle Error - "W", # Pycodestyle Warning - "N", # PEP8 Naming - "UP", # Pyupgrade - # TODO "ANN", - "S", # Bandit - "B", # Bugbear - "A", # flake-8-builtins - "YTT", # flake-8-2020 - "PLC", # Pylint Convention - "PLE", # Pylint Error - "PLW", # Pylint Warning -] -# Some checks should be enabled for code sanity disabled now -# to avoid changing too many lines -ignore = [ - "F821", # TODO Undefined name - # Some Exceptions such as NotFound and NotFoundError can be ambiguous - # This change need to be performed with carefulness - "N818", # TODO Error Suffix in exception name - # This can lead to API breaking changes so it's disabled for now - "N80", # TODO Invalid Name - # TODO this error fails on one file and it's necessary to address - # the issue properly on a specific PR - "S108", - # TODO This is probably a false positive - "S603", -] -[lint.per-file-ignores] -"podman/tests/*.py" = ["S"] -[lint.flake8-builtins] -builtins-ignorelist = ["copyright", "all"] diff --git a/test-requirements.txt b/test-requirements.txt deleted file mode 100644 index 1a70e359..00000000 --- a/test-requirements.txt +++ /dev/null @@ -1,8 +0,0 @@ -# Any changes should be copied into pyproject.toml --r requirements.txt -ruff -coverage -fixtures -pytest -requests-mock >= 1.11.0 -tox diff --git a/tests/main.fmf b/tests/main.fmf index 8aa9767e..7800081f 100644 --- a/tests/main.fmf +++ b/tests/main.fmf @@ -18,6 +18,14 @@ require: test: cd .. && make unittest /tests: - tag: [ upstream, downstream ] - summary: Run all tests - test: cd .. && make tests + /base_python: + tag: [ base ] + summary: Run all tests on the base python version + test: cd .. && make tests-ci-base-python + duration: 10m + + /all_python: + tag: [ matrix] + summary: Run all tests for all ptyhon versions available + test: cd .. && make tests-ci-all-python + duration: 10m diff --git a/tox.ini b/tox.ini index 25169f8c..e69da23b 100644 --- a/tox.ini +++ b/tox.ini @@ -6,8 +6,7 @@ ignore_basepython_conflict = true [testenv] basepython = python3 usedevelop = True -install_command = pip install {opts} {packages} -deps = -r{toxinidir}/test-requirements.txt +deps = .[test] commands = pytest {posargs} setenv = PODMAN_LOG_LEVEL = {env:PODMAN_LOG_LEVEL:INFO}