From bf92dcf57f7a118242b93a79ad9901efc702a6cb Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Sat, 29 Jun 2024 16:55:44 +0200 Subject: [PATCH 1/9] Add new CI job which build the release artifact (tarball, wheel) and verifies it works (unpacks the tarball, runs tests). Also remove MANIFEST.in in favor or include rules declared in pyproject.toml. --- .github/workflows/main.yml | 77 ++++++++++++++++++++++++++++++++++++++ .gitignore | 1 + MANIFEST.in | 25 ------------- pyproject.toml | 32 ++++++++++++++-- 4 files changed, 107 insertions(+), 28 deletions(-) delete mode 100644 MANIFEST.in diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0a46cf3157..b6ea76c9a6 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -201,6 +201,83 @@ jobs: run: | tox -e black-check,isort-check,pyupgrade,checks,import-timings,lint,pylint,mypy + build_test_release_artifact: + name: Build and Test Release Artifact + runs-on: ubuntu-latest + + strategy: + matrix: + python_version: [3.8] + + steps: + - uses: actions/checkout@master + with: + fetch-depth: 1 + + - name: Use Python ${{ matrix.python_version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python_version }} + + - name: Cache Python Dependencies + uses: actions/cache@v4 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('requirements-lint.txt') }} + restore-keys: | + ${{ runner.os }}-pip- + + - name: Install Python Dependencies + run: | + pip install -r requirements-ci.txt + pip install -e ".[build]" + + - name: Build Release Artifact + run: | + pip list installed + python -m build -vv + + - name: Set Environment + run: | + export PYTHONPATH=. + export VERSION=$(python -c "import libcloud ; print(libcloud.__version__)") + echo "VERSION=${VERSION}" >> "$GITHUB_ENV" + + - name: Verify Tarball Release Artifact + run: | + # Verify tarball file exists + export TARBALL_FILENAME="apache_libcloud-${VERSION}.tar.gz" + + ls -la "dist/${TARBALL_FILENAME}" + + cd dist/ + + # Unpack tarball and verify + run the tests + tar -xzvf "${TARBALL_FILENAME}" + + cd "apache_libcloud-${VERSION}/" + tox -epy3.8 + + - name: Verify Wheel Release Artifact + run: | + # Verify wheel file exists + export WHEEL_FILENAME="apache_libcloud-${VERSION}-py2.py3-none-any.whl" + + ls -la "dist/${WHEEL_FILENAME}" + + cd dist/ + + # Unpack wheel and verify + run tests + unzip "${WHEEL_FILENAME}" -d "wheel" + cd wheel + + # Since wheel doesn't include those files, we need to manually copy them over from + # repo root so we can run the tests + cp ../../tox.ini . + cp ../../requirements-tests.txt . + cp ../../libcloud/test/secrets.py-dist libcloud/test/secrets.py + tox -epy3.8 + build_test_docker_image: name: Build and Verify Docker Image runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index 9f79c16590..62e23cfe49 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ coverage.xml .idea dist/*apache-libcloud* dist/*apache_libcloud* +dist/wheel docs/apidocs/* _build/ apache_libcloud.egg-info/ diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 67421d7f94..0000000000 --- a/MANIFEST.in +++ /dev/null @@ -1,25 +0,0 @@ -global-exclude *.py[cod] -global-exclude .pytest_cache -include LICENSE -include NOTICE -include example_*.py -include CHANGES.rst -include README.rst -include tox.ini -include pyproject.toml -include requirements-tests.txt -include requirements-lint.txt -include libcloud/data/pricing.json -include libcloud/test/secrets.py-dist -include demos/* -include scripts/check_file_names.sh -recursive-exclude libcloud/test secrets.py -prune libcloud/test/secrets.py -prune requirements-rtd.txt -prune dist -prune build -prune contrib/ -prune docs/ -prune demos/ -prune integration/ -prune pylint_plugins/ diff --git a/pyproject.toml b/pyproject.toml index d89e53b564..8a4b0b6631 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -85,11 +85,37 @@ test = [ ] [tool.setuptools.packages.find] -where = ["./"] -include = ["libcloud", "libcloud.test*" ] +include = ["libcloud"] +namespaces = false [tool.setuptools.package-data] -"*" = ["*.json", "*.xml", "*.pub", "*.key", "*.pem", "*.crt", "*.csv", "*.txt", "*.html"] +"*" = [ + "LICENSE", + "NOTICE", + "example*.py", + "CHANGES.rst", + "README.rst", + "tox.ini", + "pyproject.toml", + "requirements-tests.txt", + "requirements-lint.txt", + "libcloud/test/secrets.py-dist", + "demos/*" +] +"libcloud.data" = [ + "pricing.json" +] +"libcloud.test" = [ + "*.json", + "*.xml", + "*.pub", + "*.key", + "*.pem", + "*.crt", + "*.csv", + "*.txt", + "*.html" +] "libcloud.test.compute.fixtures.misc" = ["*"] "libcloud.test.dns.fixtures.worldwidedns" = ["*"] From c817325f5a33a906efdd9836066860b62c983e2e Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Sun, 2 Mar 2025 19:43:41 +0100 Subject: [PATCH 2/9] Fix typo, remove obsolete config option for wheels. --- pyproject.toml | 3 +-- setup.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 9ad93e3608..a75dd44b78 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,7 +74,7 @@ Changelog = "https://github.com/apache/libcloud/blob/trunk/CHANGES.rst" [project.optional-dependencies] build = [ - "build==1.2.1" + "build==1.2.2" ] publish = [ "twine==5.1.1" @@ -128,7 +128,6 @@ version = {attr = "libcloud.__version__"} readme = {file = ["README.rst"], content-type = "text/x-rst"} [tool.distutils.bdist_wheel] -universal = true [tool.black] diff --git a/setup.py b/setup.py index 0659d811e0..0567aba8ad 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Project utilized pyproject.toml for setup and packaging metadata, this file is only left in place +# Project utilizes pyproject.toml for setup and packaging metadata, this file is only left in place # so we can still utilize setup.py --version from setuptools import setup From f971caad71300ed716919bb8b16497e36a6db9ba Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Sun, 2 Mar 2025 19:53:32 +0100 Subject: [PATCH 3/9] Remove setup.py. --- dist/deploy.sh | 2 +- docs/testing.rst | 2 +- setup.py | 21 --------------------- 3 files changed, 2 insertions(+), 23 deletions(-) delete mode 100644 setup.py diff --git a/dist/deploy.sh b/dist/deploy.sh index c75540f1a2..107ef01908 100755 --- a/dist/deploy.sh +++ b/dist/deploy.sh @@ -21,7 +21,7 @@ pushd "${SCRIPT_DIR}/../" # We redirect stderr to /dev/null since sometimes setuptools may print pyproject # related warning -VERSION=$(python setup.py --version 2> /dev/null) +VERSION=$(grep -Po '(?<=^__version__ = ")[^"]+' libcloud/__init__.py) popd pushd "${SCRIPT_DIR}" diff --git a/docs/testing.rst b/docs/testing.rst index 86b9c908c6..56499ed0cd 100644 --- a/docs/testing.rst +++ b/docs/testing.rst @@ -77,7 +77,7 @@ To generate the test coverage run the following command: .. sourcecode:: bash - PYTHONPATH=. python setup.py coverage + tox -e coverage_html_report When it completes you should see a new ``coverage_html_report`` directory which contains the test coverage. diff --git a/setup.py b/setup.py deleted file mode 100644 index 0567aba8ad..0000000000 --- a/setup.py +++ /dev/null @@ -1,21 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Project utilizes pyproject.toml for setup and packaging metadata, this file is only left in place -# so we can still utilize setup.py --version - -from setuptools import setup - -setup() From 4f8e7b2fdb9838db6905dd3c6aa2fb0ad56ce397 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Sun, 2 Mar 2025 19:56:07 +0100 Subject: [PATCH 4/9] Update changelog. --- CHANGES.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index e71175c0d7..80e2546558 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -7,6 +7,14 @@ Changes in Apache Libcloud 3.9.0 Common ~~~~~~ +- Unused ``setup.py`` file has been removed. The project has switched + to ``pyproject.toml`` a while ago and unused file has been removed to + reduce potential confusion. Corresponding ``MANIFEST.in`` has also been + removed in favor of explicit include and exclude directives in + ``pyproject.toml``. + (#2024) + [Tomaz Muraus - @Kami] + - Indicate we also support Python 3.12 (non beta) and Python 3.13. (#2050) [Tomaz Muraus - @Kami] From e2d85f1833c09d247377ffe6ef250042e42473af Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Sun, 2 Mar 2025 20:02:25 +0100 Subject: [PATCH 5/9] Don't install project in editable mode to avoid issues. --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4748e27176..29965301d6 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -199,7 +199,7 @@ jobs: - name: Install Python Dependencies run: | pip install -r requirements-ci.txt - pip install -e ".[build]" + pip install "build==1.2.2" - name: Build Release Artifact run: | From 4ede98f012298ece9e20b7d0104ea667b98c2af3 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Sun, 2 Mar 2025 20:08:23 +0100 Subject: [PATCH 6/9] Correctly include package data files. --- pyproject.toml | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a75dd44b78..321acdaf34 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -89,19 +89,6 @@ where = ["./"] include = ["libcloud", "libcloud.test*", "libcloud.*" ] [tool.setuptools.package-data] -"*" = [ - "LICENSE", - "NOTICE", - "example*.py", - "CHANGES.rst", - "README.rst", - "tox.ini", - "pyproject.toml", - "requirements-tests.txt", - "requirements-lint.txt", - "libcloud/test/secrets.py-dist", - "demos/*" -] "libcloud.data" = [ "pricing.json" ] @@ -114,11 +101,27 @@ include = ["libcloud", "libcloud.test*", "libcloud.*" ] "*.crt", "*.csv", "*.txt", - "*.html" + "*.html", + "secrets.py-dist", ] "libcloud.test.compute.fixtures.misc" = ["*"] "libcloud.test.dns.fixtures.worldwidedns" = ["*"] +# Files outside of packages (in the repository root, demos directory, etc.) +[tool.setuptools.data-files] +"" = [ + "LICENSE", + "NOTICE", + "CHANGES.rst", + "README.rst", + "tox.ini", + "pyproject.toml", + "requirements-tests.txt", + "requirements-lint.txt", +] +"demos" = ["demos/*"] + + [tool.setuptools] include-package-data = true exclude-package-data = { "*" = ["secrets.py"], "libcloud.test" = ["secrets.py"] } From bc7154131bca3ed849c7eca5192af88c093089fa Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Sun, 2 Mar 2025 20:31:01 +0100 Subject: [PATCH 7/9] Add MANIFEST.in back since pyproject.toml + setuptools is still lacking exclude functionality. --- CHANGES.rst | 4 +--- MANIFEST.in | 43 +++++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 36 +++++++++--------------------------- 3 files changed, 53 insertions(+), 30 deletions(-) create mode 100644 MANIFEST.in diff --git a/CHANGES.rst b/CHANGES.rst index 80e2546558..82224f8ddb 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -9,9 +9,7 @@ Common - Unused ``setup.py`` file has been removed. The project has switched to ``pyproject.toml`` a while ago and unused file has been removed to - reduce potential confusion. Corresponding ``MANIFEST.in`` has also been - removed in favor of explicit include and exclude directives in - ``pyproject.toml``. + reduce potential confusion. (#2024) [Tomaz Muraus - @Kami] diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000000..650cdda7d2 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,43 @@ +# NOTE: We still need to use MANIFEST.in for backward compatibility with past +# distributions since pyproject.toml + setuptools backend doesn't support +# as flexible includes and excludes as we need. +global-exclude *.py[cod] +global-exclude .pytest_cache + +# Include common files at the repository root +include LICENSE +include NOTICE +include example_*.py +include CHANGES.rst +include README.rst +include tox.ini +include pyproject.toml +include requirements-tests.txt +include requirements-lint.txt +include libcloud/data/pricing.json +include libcloud/test/secrets.py-dist +include demos/* +include scripts/check_file_names.sh +recursive-exclude libcloud/test secrets.py +prune libcloud/test/secrets.py +prune requirements-rtd.txt +prune dist +prune build +prune contrib/ +prune docs/ +prune demos/ +prune integration/ +prune pylint_plugins/ +prune __pycache__ + +# Recursively include all files under the fixture directories +recursive-include libcloud/test/backup/fixtures * +recursive-include libcloud/test/common/fixtures * +recursive-include libcloud/test/compute/fixtures * +recursive-include libcloud/test/container/fixtures * +recursive-include libcloud/test/dns/fixtures * +recursive-include libcloud/test/loadbalancer/fixtures * +recursive-include libcloud/test/storage/fixtures * + +# Exclude __pycache__ directories +prune **/__pycache__ diff --git a/pyproject.toml b/pyproject.toml index 321acdaf34..4fc164081d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -93,34 +93,16 @@ include = ["libcloud", "libcloud.test*", "libcloud.*" ] "pricing.json" ] "libcloud.test" = [ - "*.json", - "*.xml", - "*.pub", - "*.key", - "*.pem", - "*.crt", - "*.csv", - "*.txt", - "*.html", - "secrets.py-dist", + "**/*.json", + "**/*.xml", + "**/*.pub", + "**/*.key", + "**/*.pem", + "**/*.crt", + "**/*.csv", + "**/*.txt", + "**/*.html", ] -"libcloud.test.compute.fixtures.misc" = ["*"] -"libcloud.test.dns.fixtures.worldwidedns" = ["*"] - -# Files outside of packages (in the repository root, demos directory, etc.) -[tool.setuptools.data-files] -"" = [ - "LICENSE", - "NOTICE", - "CHANGES.rst", - "README.rst", - "tox.ini", - "pyproject.toml", - "requirements-tests.txt", - "requirements-lint.txt", -] -"demos" = ["demos/*"] - [tool.setuptools] include-package-data = true From 7cf97c81305fcb0b995234102e1ebdd77c180f81 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Sun, 2 Mar 2025 20:37:50 +0100 Subject: [PATCH 8/9] Update filename now that we have removed obsolete universal wheel property. --- .github/workflows/main.yml | 2 +- dist/verify_checksums.sh | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 29965301d6..48a51f35d9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -230,7 +230,7 @@ jobs: - name: Verify Wheel Release Artifact run: | # Verify wheel file exists - export WHEEL_FILENAME="apache_libcloud-${VERSION}-py2.py3-none-any.whl" + export WHEEL_FILENAME="apache_libcloud-${VERSION}-py3-none-any.whl" ls -la "dist/${WHEEL_FILENAME}" diff --git a/dist/verify_checksums.sh b/dist/verify_checksums.sh index 6e50ba9d2e..af1e6b4261 100755 --- a/dist/verify_checksums.sh +++ b/dist/verify_checksums.sh @@ -30,11 +30,11 @@ TMP_DIR=$(mktemp -d) # TODO: Use json endpoint + jq to parse out the url # https://pypi.org/pypi/apache-libcloud/3.4.0/json EXTENSIONS[0]=".tar.gz" -EXTENSIONS[1]="-py2.py3-none-any.whl" +EXTENSIONS[1]="-py3-none-any.whl" APACHE_MIRROR_URL="http://www.apache.org/dist/libcloud" PYPI_MIRROR_URL_SOURCE="https://pypi.python.org/packages/source/a/apache-libcloud" -PYPI_MIRROR_URL_WHEEL="https://files.pythonhosted.org/packages/py2.py3/a/apache-libcloud" +PYPI_MIRROR_URL_WHEEL="https://files.pythonhosted.org/packages/py3/a/apache-libcloud" # From http://tldp.org/LDP/abs/html/debugging.html#ASSERT function assert () # If condition false, @@ -69,7 +69,7 @@ do extension=${EXTENSIONS[$i]} file_name="${VERSION}${extension}" - if [ "${extension}" = "-py2.py3-none-any.whl" ]; then + if [ "${extension}" = "-py3-none-any.whl" ]; then # shellcheck disable=SC2001 file_name=$(echo "${file_name}" | sed "s/apache-libcloud/apache_libcloud/g") fi @@ -77,7 +77,7 @@ do apache_url="${APACHE_MIRROR_URL}/${file_name}" pypi_url="${PYPI_MIRROR_URL}/${file_name}" - if [ "${extension}" = "-py2.py3-none-any.whl" ]; then + if [ "${extension}" = "-py3-none-any.whl" ]; then pypi_url="${PYPI_MIRROR_URL_WHEEL}/${file_name}" else pypi_url="${PYPI_MIRROR_URL_SOURCE}/${file_name}" From 8546be92faff2b5886a51f45f65ef8cf368f3f01 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Sun, 2 Mar 2025 20:45:15 +0100 Subject: [PATCH 9/9] Add changelog entry. --- CHANGES.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index 82224f8ddb..1c3390de65 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -42,6 +42,16 @@ Common (#1940) [@munahaf on behalf of OpenRefactory and Open Source Security Foundation] +- Update versions of build and packaging tools required to build the package. + + Per report from Rui Chen (@chenrui333) ansible homebrew package which + depends on libcloud was failing to build with Libcloud 3.8.0. + + Special thanks to Rui Chen for their assistance with troubleshooting the issue + and testing v3.9.0 release candidate. + (#2047) + [Tomaz Muraus - @Kami, Rui Chen - @chenrui333] + Compute ~~~~~~~