From a6afd831bbf123e4d46bc498423d1cd33f64d91e Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Thu, 21 Aug 2025 00:43:54 +0200 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=93=A6=F0=9F=A7=AA=20Simplify=20the?= =?UTF-8?q?=20RPM=20spec?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch removes the SRPM-vendored PyPI-sourced dependencies and migrates packaging to rely on `pyproject-rpm-macros` under RHEL. Previously, this set of helpers was only in use on Fedora. This move allows us to get rid of a lot of conditionals that were making people's lives difficult. --- .github/workflows/ci-cd.yml | 135 +++++++-------------- packaging/rpm/ansible-pylibssh.spec | 180 +++------------------------- 2 files changed, 59 insertions(+), 256 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index c608b1093..75a1b4009 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -996,9 +996,6 @@ jobs: - tag: fedora:40 - tag: fedora:41 - tag: fedora:42 - # No matching package to install: 'python3dist(wheel)' - # - tag: centos/centos:stream9 - # registry: quay.io - tag: ubi9/ubi:9.0.0 registry: registry.access.redhat.com - tag: ubi9/ubi:9.1 @@ -1030,13 +1027,6 @@ jobs: matrix.target-container.tag }} - continue-on-error: >- # Stub for in-matrix "allowed-failures" - ${{ - contains(matrix.target-container.tag, '--DISABLED--') - && true - || false - }} - steps: - name: Produce artifact name id: distribution-meta @@ -1044,29 +1034,17 @@ jobs: dist_tag=$(rpm --eval '%{?dist}') echo "dist-tag=${dist_tag}" >> "${GITHUB_OUTPUT}" - - name: Enable EPEL repository - if: contains(matrix.target-container.tag, 'centos') - run: dnf install --assumeyes epel-release - - name: Install build tooling run: >- dnf install --assumeyes dnf-plugins-core rpm-build - ${{ - !contains(matrix.target-container.tag, 'ubi') - && 'rpmdevtools rpmlint' - || '' - }} + rpmdevtools + rpmlint - - name: Create rpmbuild directory structure on a community distro - if: >- - !contains(matrix.target-container.tag, 'ubi') + - name: Create rpmbuild directory structure run: rpmdev-setuptree - - name: Create rpmbuild directory structure on RHEL - if: contains(matrix.target-container.tag, 'ubi') - run: mkdir -pv ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS} - name: Retrieve the project source from an sdist inside the GHA artifact uses: re-actors/checkout-python-sdist@release/v2 @@ -1089,8 +1067,6 @@ jobs: merge-multiple: true - name: Lint the RPM spec file - if: >- - !contains(matrix.target-container.tag, 'ubi') run: rpmlint packaging/rpm/ansible-pylibssh.spec - name: Copy sdist to the sources dir @@ -1099,85 +1075,73 @@ jobs: 'dist/${{ needs.pre-setup.outputs.sdist-artifact-name }}' ~/rpmbuild/SOURCES/ - - name: Install static test dependencies missing from UBI9 - if: contains(matrix.target-container.tag, 'ubi9') + - name: Install transitive deps for build deps in external repos + if: contains(matrix.target-container.tag, 'ubi') + run: >- + dnf install + --assumeyes + python3-packaging + python3-pluggy + python3-py + python3-tomli + + - name: Install static test dependencies missing from all UBIs + if: contains(matrix.target-container.tag, 'ubi') run: >- rpm -ivh --nodeps - https://rpmfind.net/linux/centos-stream/"$( + https://rpmfind.net/linux/epel/"$( rpm --eval '%{rhel}' - )"-stream/AppStream/x86_64/os/Packages/python3-pytest-6.2.2-6${{ + )"/Everything/x86_64/Packages/p/python3-pytest-cov-4.0.0-2${{ steps.distribution-meta.outputs.dist-tag }}.noarch.rpm - https://rpmfind.net/linux/centos-stream/"$( + https://rpmfind.net/linux/epel/"$( rpm --eval '%{rhel}' - )"-stream/CRB/x86_64/os/Packages/python3-wheel-0.36.2-7${{ + )"/Everything/x86_64/Packages/p/python3-pytest-xdist-2.5.0-2${{ steps.distribution-meta.outputs.dist-tag }}.noarch.rpm - - - name: Install static test dependencies missing from all UBIs - if: contains(matrix.target-container.tag, 'ubi') - run: >- - rpm - -ivh - --nodeps https://rpmfind.net/linux/epel/"$( rpm --eval '%{rhel}' - )"/Everything/x86_64/Packages/p/python3-pytest-cov-${{ - contains(matrix.target-container.tag, 'ubi9') - && '4.0.0-2' - || '2.6.0-1' - }}${{ steps.distribution-meta.outputs.dist-tag }}.noarch.rpm + )"/Everything/x86_64/Packages/t/tox-3.28.0-1${{ + steps.distribution-meta.outputs.dist-tag + }}.noarch.rpm https://rpmfind.net/linux/epel/"$( rpm --eval '%{rhel}' - )"/Everything/x86_64/Packages/p/python3-pytest-xdist-${{ - contains(matrix.target-container.tag, 'ubi9') - && '2.5.0-2' - || '1.24.1-1' - }}${{ steps.distribution-meta.outputs.dist-tag }}.noarch.rpm + )"/Everything/x86_64/Packages/p/python3-filelock-3.7.1-1${{ + steps.distribution-meta.outputs.dist-tag + }}.noarch.rpm https://rpmfind.net/linux/epel/"$( rpm --eval '%{rhel}' - )"/Everything/x86_64/Packages/t/tox-${{ - contains(matrix.target-container.tag, 'ubi9') - && '3.28.0-1' - || '3.4.0-2' - }}${{ steps.distribution-meta.outputs.dist-tag }}.noarch.rpm + )"/Everything/x86_64/Packages/p/python3-tox-current-env-0.0.16-1${{ + steps.distribution-meta.outputs.dist-tag + }}.noarch.rpm https://rpmfind.net/linux/epel/"$( rpm --eval '%{rhel}' - )"/Everything/x86_64/Packages/p/python3-execnet-${{ - contains(matrix.target-container.tag, 'ubi9') - && '1.9.0-3' - || '1.7.1-1' - }}${{ steps.distribution-meta.outputs.dist-tag }}.noarch.rpm + )"/Everything/x86_64/Packages/p/python3-execnet-1.9.0-3${{ + steps.distribution-meta.outputs.dist-tag + }}.noarch.rpm https://rpmfind.net/linux/epel/"$( rpm --eval '%{rhel}' - )"/Everything/x86_64/Packages/p/python3-coverage-${{ - contains(matrix.target-container.tag, 'ubi9') - && '6.2-1' - || '4.5.1-9' - }}${{ steps.distribution-meta.outputs.dist-tag }}.x86_64.rpm + )"/Everything/x86_64/Packages/p/python3-coverage-6.2-1${{ + steps.distribution-meta.outputs.dist-tag + }}.x86_64.rpm https://rpmfind.net/linux/epel/"$( rpm --eval '%{rhel}' - )"/Everything/x86_64/Packages/p/python3-apipkg-${{ - contains(matrix.target-container.tag, 'ubi9') - && '2.1.1-1' - || '1.5-6' - }}${{ steps.distribution-meta.outputs.dist-tag }}.noarch.rpm + )"/Everything/x86_64/Packages/p/python3-expandvars-0.12.0-1${{ + steps.distribution-meta.outputs.dist-tag + }}.noarch.rpm - name: Install static build requirements run: dnf builddep --assumeyes --spec packaging/rpm/ansible-pylibssh.spec - - name: Fetch sources and patches on a community distro - if: >- - !contains(matrix.target-container.tag, 'ubi') + - name: Fetch sources and patches run: >- spectool --all --get-files --sourcedir packaging/rpm/ansible-pylibssh.spec - - name: Resolve and install dynamic build deps and build an SRPM on Fedora + - name: Resolve and install dynamic build deps and build an SRPM # Ref: https://github.com/rpm-software-management/rpm/commit/58dcfdd - if: contains(matrix.target-container.tag, 'fedora') run: | while : do @@ -1195,38 +1159,25 @@ jobs: }}.buildreqs.nosrc.rpm done - - name: Build an SRPM on RHELish - if: >- - !contains(matrix.target-container.tag, 'fedora') - run: >- - rpmbuild - ${{ - contains(matrix.target-container.tag, 'ubi') - && '--undefine=_disable_source_fetch' - || '' - }} - -bs - packaging/rpm/ansible-pylibssh.spec - - name: Build binary RPMs run: >- rpmbuild --rebuild - $HOME/rpmbuild/SRPMS/python-ansible-pylibssh-${{ + "$HOME/rpmbuild/SRPMS/python-ansible-pylibssh-${{ needs.pre-setup.outputs.dist-version }}-1${{ steps.distribution-meta.outputs.dist-tag - }}.src.rpm + }}.src.rpm" - name: Install the packaged binary RPM on the system run: >- dnf install --assumeyes - $HOME/rpmbuild/RPMS/x86_64/python3-ansible-pylibssh-${{ + "$HOME/rpmbuild/RPMS/x86_64/python3-ansible-pylibssh-${{ needs.pre-setup.outputs.dist-version }}-1${{ steps.distribution-meta.outputs.dist-tag - }}.x86_64.rpm + }}.x86_64.rpm" - name: Smoke-test the installed library run: >- diff --git a/packaging/rpm/ansible-pylibssh.spec b/packaging/rpm/ansible-pylibssh.spec index eaa9b209e..8e67b5214 100644 --- a/packaging/rpm/ansible-pylibssh.spec +++ b/packaging/rpm/ansible-pylibssh.spec @@ -9,23 +9,20 @@ %endif %global python_importable_name pylibsshext -# RHEL or CentOS: -%if 0%{?rhel} -%global normalized_dist_name ansible_pylibssh -%global whl_glob %{normalized_dist_name}-%{version}-cp3*-cp3*-linux_%{_arch}.whl -%endif %global buildroot_site_packages "%{buildroot}%{python3_sitearch}" %if 0%{?with_debug} %global _dwz_low_mem_die_limit 0 %else -# RHEL or CentOS: -%if 0%{?rhel} # Prevent requiring a Build ID in the compiled shared objects %global debug_package %{nil} %endif -%endif + +# NOTE: Newer distro versions enable the source_date_epoch_from_changelog macro +# NOTE: and it breaks because we don't currently include the change log. +# Ref: https://fedoraproject.org/wiki/Changes/ReproducibleBuildsClampMtimes +%global source_date_epoch_from_changelog 0 Name: python-%{pypi_name} Version: %{upstream_version} @@ -36,34 +33,9 @@ Summary: Python bindings for libssh client specific to Ansible use case License: LGPL-2+ URL: https://github.com/ansible/pylibssh Source0: %{pypi_source} -Source1: %{pypi_source expandvars 0.7.0} -# RHEL or CentOS: -%if 0%{?rhel} -Source2: %{pypi_source build 0.3.1.post1} -Source3: %{pypi_source Cython 0.29.32} -Source4: %{pypi_source packaging 20.9} -Source5: %{pypi_source setuptools 56.0.0} -Source6: %{pypi_source setuptools_scm 8.1.0} -Source8: %{pypi_source tomli 2.0.1} -Source9: %{pypi_source pep517 0.10.0} -Source10: %{pypi_source pip 21.1.1} -Source11: %{pypi_source pyparsing 2.4.7} -# RHEL specifically, not CentOS: -%if 0%{?centos} == 0 -Source12: %{pypi_source importlib_metadata 4.0.1} -Source13: %{pypi_source zipp 3.4.1} -Source14: %{pypi_source typing_extensions 4.12.2} -%endif -Source15: %{pypi_source pytest 6.2.4} -Source16: %{pypi_source pytest-cov 2.12.1} -Source18: %{pypi_source pytest-xdist 2.3.0} -Source19: %{pypi_source iniconfig 1.1.1} -Source20: %{pypi_source attrs 20.3.0} -Source21: %{pypi_source pluggy 0.13.1} -Source22: %{pypi_source py 1.10.0} -Source23: %{pypi_source coverage 5.5} -Source24: %{pypi_source tomli 1.2.3} -%endif + +# `pyproject-rpm-macros` provides %%pyproject_buildrequires +BuildRequires: pyproject-rpm-macros # Test dependencies: # keygen? @@ -72,13 +44,6 @@ BuildRequires: openssh BuildRequires: openssh-server # ssh? BuildRequires: openssh-clients -# RHEL or CentOS: -%if 0%{?rhel} -BuildRequires: python3dist(pytest) -BuildRequires: python3dist(pytest-cov) -BuildRequires: python3dist(pytest-xdist) -BuildRequires: python3dist(tox) -%endif # Build dependencies: BuildRequires: gcc @@ -86,27 +51,8 @@ BuildRequires: gcc BuildRequires: libssh-devel BuildRequires: python3-devel -# RHEL or CentOS: -%if 0%{?rhel} -BuildRequires: python3dist(pip) -BuildRequires: python3dist(wheel) -# CentOS, not RHEL: -%if 0%{?centos} -BuildRequires: python3dist(importlib-metadata) -%endif -%endif -# Fedora: -%if 0%{?fedora} -# `pyproject-rpm-macros` provides %%pyproject_buildrequires -BuildRequires: pyproject-rpm-macros - -# `python3-pip` is used to install vendored build deps -BuildRequires: python3-pip - -# `python3-toml` is not retrieved by %%pyproject_buildrequires for some reason -BuildRequires: python3-toml -%endif +# Runtime dependencies: Requires: libssh >= 0.9.0 %description @@ -122,133 +68,39 @@ Summary: %{summary} $summary %prep -%autosetup -n %{pypi_name}-%{version} - -PYTHONPATH="$(pwd)/bin" \ -%{__python3} -m pip install --no-deps -t bin %{SOURCE1} - -# RHEL or CentOS: -%if 0%{?rhel} -PYTHONPATH="$(pwd)/bin" \ -%{__python3} -m pip install --no-deps -t bin %{SOURCE9} -PYTHONPATH="$(pwd)/bin" \ -%{__python3} -m pip install --no-deps -t bin %{SOURCE2} -PYTHONPATH="$(pwd)/bin" \ -%{__python3} -m pip install --no-deps -t bin %{SOURCE10} -PYTHONPATH="$(pwd)/bin" \ -%{__python3} -m pip install --no-deps -t bin %{SOURCE3} --install-option="--no-cython-compile" -PYTHONPATH="$(pwd)/bin" \ -%{__python3} -m pip install --no-deps -t bin %{SOURCE4} -PYTHONPATH="$(pwd)/bin" \ -%{__python3} -m pip install --no-deps -t bin %{SOURCE5} -PYTHONPATH="$(pwd)/bin" \ -%{__python3} -m pip install --no-deps -t bin %{SOURCE6} -PYTHONPATH="$(pwd)/bin" \ -%{__python3} -m pip install --no-deps -t bin %{SOURCE8} -# RHEL specifically, not CentOS: -%if 0%{?centos} == 0 -PYTHONPATH="$(pwd)/bin" \ -%{__python3} -m pip install --no-deps -t bin %{SOURCE14} -%endif -PYTHONPATH="$(pwd)/bin" \ -%{__python3} -m pip install --no-deps -t bin %{SOURCE11} -# RHEL specifically, not CentOS: -%if 0%{?centos} == 0 -PYTHONPATH="$(pwd)/bin" \ -%{__python3} -m pip install --no-deps -t bin %{SOURCE12} -PYTHONPATH="$(pwd)/bin" \ -%{__python3} -m pip install --no-deps -t bin %{SOURCE13} -%endif -PYTHONPATH="$(pwd)/bin" \ -%{__python3} -m pip install --no-deps -t bin %{SOURCE15} -PYTHONPATH="$(pwd)/bin" \ -%{__python3} -m pip install --no-deps -t bin %{SOURCE16} -PYTHONPATH="$(pwd)/bin" \ -%{__python3} -m pip install --no-deps -t bin %{SOURCE18} -PYTHONPATH="$(pwd)/bin" \ -%{__python3} -m pip install --no-deps -t bin %{SOURCE19} -PYTHONPATH="$(pwd)/bin" \ -%{__python3} -m pip install --no-deps -t bin %{SOURCE20} -PYTHONPATH="$(pwd)/bin" \ -%{__python3} -m pip install --no-deps -t bin %{SOURCE21} -PYTHONPATH="$(pwd)/bin" \ -%{__python3} -m pip install --no-deps -t bin %{SOURCE22} -PYTHONPATH="$(pwd)/bin" \ -%{__python3} -m pip install --no-deps -t bin %{SOURCE23} -PYTHONPATH="$(pwd)/bin" \ -%{__python3} -m pip install --no-deps -t bin %{SOURCE24} +%autosetup -p1 -n %{pypi_name}-%{version} + +%if 0%{?rhel} == 9 +# NOTE: Since RHEL 9 does not have setuptools-scm 7+ in the repos, we change the +# NOTE: metadata to require a lower version and hope for the best +sed -i 's/\(.*"setuptools-scm\)[^"]\+\(",.*\)/\1 >= 6\2/g' pyproject.toml %endif -# Fedora: -%if 0%{?fedora} -PYTHONPATH="$(pwd)/bin" \ %generate_buildrequires %pyproject_buildrequires -t -%endif %build -# Fedora: -%if 0%{?fedora} %pyproject_wheel -%endif - -# RHEL or CentOS: -%if 0%{?rhel} -PYTHONPATH="$(pwd)/bin" \ -%{__python3} \ - -m build \ - --wheel \ - --skip-dependencies \ - --no-isolation \ - . -%endif %install -# Fedora: -%if 0%{?fedora} %pyproject_install %pyproject_save_files "%{python_importable_name}" -%endif - -# RHEL or CentOS: -%if 0%{?rhel} -%{py3_install_wheel %{whl_glob}} -# Set the installer to rpm so that pip knows not to manage this dist: -sed \ - -i 's/pip/rpm/' \ - %{buildroot_site_packages}/%{normalized_dist_name}-%{version}.dist-info/INSTALLER -%endif %check export PYTHONPATH="%{buildroot_site_packages}:${PYTHONPATH}" -# Fedora: -%if "%{?fedora:SET}" == "SET" %pyproject_check_import %tox -e just-pytest -# CentOS or RHEL: -%else -export PYTHONPATH="$(pwd)/bin:${PYTHONPATH}" -%{__python3} -m pytest \ - --no-cov -%endif -%files -n python3-%{pypi_name} %{?fedora:-f} %{?fedora:%{pyproject_files}} +%files -n python3-%{pypi_name} -f %{pyproject_files} %license LICENSE.rst %doc README.rst -# RHEL or CentOS -%if 0%{?rhel} -# NOTE: %%{python3_sitelib} points to /lib/ while %%{python3_sitearch} -# NOTE: points to /lib64/ when necessary. -%{python3_sitearch}/%{python_importable_name} -%{python3_sitearch}/%{normalized_dist_name}-%{version}.dist-info -%endif %changelog From b48276a4fd2c28163701ada9a9750b8d91ce0804 Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Thu, 21 Aug 2025 11:48:33 +0200 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=93=9D=20Add=20change=20notes=20for?= =?UTF-8?q?=20PR=20#759?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/changelog-fragments/759.contrib.rst | 7 +++++++ docs/changelog-fragments/759.packaging.rst | 6 ++++++ 2 files changed, 13 insertions(+) create mode 100644 docs/changelog-fragments/759.contrib.rst create mode 100644 docs/changelog-fragments/759.packaging.rst diff --git a/docs/changelog-fragments/759.contrib.rst b/docs/changelog-fragments/759.contrib.rst new file mode 100644 index 000000000..37e35d640 --- /dev/null +++ b/docs/changelog-fragments/759.contrib.rst @@ -0,0 +1,7 @@ +The CI/CD jobs for smoke-testing RPMs have been simplified +and now, they execute the same steps for all distro types. +They make use of ``pyproject-rpm-macros`` even under RHEL. +Installing external RPMs is the only conditional step that +is skipped on Fedora. + +-- by :user:`webknjaz` diff --git a/docs/changelog-fragments/759.packaging.rst b/docs/changelog-fragments/759.packaging.rst new file mode 100644 index 000000000..846d4f289 --- /dev/null +++ b/docs/changelog-fragments/759.packaging.rst @@ -0,0 +1,6 @@ +The RPM spec file no longer makes use of unpackaged dists +from PyPI on RHEL. The configuration is almost identical to +the one for Fedora. Only the ``setuptools-scm`` spec is +temporarily patched to allow older versions under RHEL. + +-- by :user:`webknjaz`