From 801b67c339fa58d3f587023603ac2d54807f1bac Mon Sep 17 00:00:00 2001 From: aryasadeghi1 Date: Thu, 20 Aug 2026 19:41:53 +1000 Subject: [PATCH 1/2] {Packaging} Build wheels with `python -m build` instead of `python setup.py` `scripts/ci/build.sh` invoked `python setup.py bdist_wheel` / `sdist` directly. Setuptools 80+ deprecates running setup.py as a CLI and warns that these calls must be removed "to avoid build errors in the future", so drive the builds through the standard PEP 517 frontend instead. `--no-isolation` preserves current behaviour: the build uses the setuptools already installed by the caller rather than provisioning a fresh one. This keeps each caller's setuptools pin in force and avoids requiring outbound network access inside the packaging test containers. `--wheel` and `--sdist` are separate invocations on purpose. A bare `python -m build` builds an sdist first and then builds the wheel from it, which would newly make MANIFEST.in correctness load-bearing. `build` is added to the four scripts that run scripts/ci/build.sh, since none of them installed the PEP 517 frontend. Verified locally: wheels produced via `python -m build --wheel --no-isolation` are identical to the previous `setup.py bdist_wheel` output for all four distributions -- same archive member list and same METADATA. --- scripts/ci/build.sh | 11 +++++++---- scripts/release/debian/test_deb_in_docker.sh | 3 ++- scripts/release/homebrew/test_homebrew_package.sh | 3 ++- scripts/release/rpm/test_azurelinux_in_docker.sh | 6 ++++-- scripts/release/rpm/test_rpm_in_docker.sh | 6 ++++-- 5 files changed, 19 insertions(+), 10 deletions(-) diff --git a/scripts/ci/build.sh b/scripts/ci/build.sh index de66b39d950..016341b15d2 100755 --- a/scripts/ci/build.sh +++ b/scripts/ci/build.sh @@ -52,8 +52,11 @@ title 'Build Azure CLI and its command modules' for setup_file in $(find src -name 'setup.py'); do pushd $(dirname ${setup_file}) >/dev/null echo "Building module at $(pwd) ..." - python setup.py -q bdist_wheel -d $output_dir - python setup.py -q sdist -d $sdist_dir + # --no-isolation builds against the environment prepared by the caller rather than + # provisioning a fresh one, which keeps the caller's setuptools pin in force and + # avoids requiring outbound network access inside the packaging test containers. + python -m build --wheel --no-isolation --outdir $output_dir + python -m build --sdist --no-isolation --outdir $sdist_dir popd >/dev/null done @@ -187,8 +190,8 @@ Azure CLI Test Cases EOL pushd $testsrc_dir >/dev/null -python setup.py -q bdist_wheel -d $output_dir -python setup.py -q sdist -d $sdist_dir +python -m build --wheel --no-isolation --outdir $output_dir +python -m build --sdist --no-isolation --outdir $sdist_dir popd >/dev/null ############################################## diff --git a/scripts/release/debian/test_deb_in_docker.sh b/scripts/release/debian/test_deb_in_docker.sh index 003bdafd7ce..1c81be4c78b 100644 --- a/scripts/release/debian/test_deb_in_docker.sh +++ b/scripts/release/debian/test_deb_in_docker.sh @@ -14,7 +14,8 @@ time az self-test time az --version cd /azure-cli/ -/opt/az/bin/python3 -m pip install wheel +# `build` is the PEP 517 frontend used by scripts/ci/build.sh. +/opt/az/bin/python3 -m pip install wheel build ln -sf /opt/az/bin/python3 /usr/bin/python ./scripts/ci/build.sh diff --git a/scripts/release/homebrew/test_homebrew_package.sh b/scripts/release/homebrew/test_homebrew_package.sh index c0471691cef..380918ef449 100755 --- a/scripts/release/homebrew/test_homebrew_package.sh +++ b/scripts/release/homebrew/test_homebrew_package.sh @@ -20,7 +20,8 @@ AZ_BASE=/usr/local/Cellar/azure-cli/$CLI_VERSION/libexec export PATH=$AZ_BASE/bin:$PATH export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES echo $PATH -pip install wheel +# `build` is the PEP 517 frontend used by scripts/ci/build.sh. +pip install wheel build ./scripts/ci/build.sh pip install pytest --prefix $AZ_BASE pip install pytest-xdist --prefix $AZ_BASE diff --git a/scripts/release/rpm/test_azurelinux_in_docker.sh b/scripts/release/rpm/test_azurelinux_in_docker.sh index 46ae88086fc..35f74c72d60 100644 --- a/scripts/release/rpm/test_azurelinux_in_docker.sh +++ b/scripts/release/rpm/test_azurelinux_in_docker.sh @@ -14,8 +14,10 @@ time az self-test time az --version cd /azure-cli/ -# Cap setuptools<81: 81 removes setup.py --dry-run and changes distutils command signatures (82 removes pkg_resources); build.sh relies on setup.py. -python -m pip install --upgrade "setuptools<81" +# Cap setuptools<81: 81 removes setup.py --dry-run and changes distutils command signatures (82 removes pkg_resources). +# scripts/ci/build.sh builds with `python -m build --no-isolation`, so this pin is the setuptools the build uses. +# `build` is the PEP 517 frontend that script invokes. +python -m pip install --upgrade "setuptools<81" build ./scripts/ci/build.sh # From Fedora36, when using `pip install --prefix` with root privileges, the package is installed into `{prefix}/local/lib`. diff --git a/scripts/release/rpm/test_rpm_in_docker.sh b/scripts/release/rpm/test_rpm_in_docker.sh index 37250ddcb67..27d77912837 100644 --- a/scripts/release/rpm/test_rpm_in_docker.sh +++ b/scripts/release/rpm/test_rpm_in_docker.sh @@ -15,8 +15,10 @@ time az self-test time az --version cd /azure-cli/ -# Cap setuptools<81: 81 removes setup.py --dry-run and changes distutils command signatures (82 removes pkg_resources); build.sh relies on setup.py. -python -m pip install --upgrade pip "setuptools<81" +# Cap setuptools<81: 81 removes setup.py --dry-run and changes distutils command signatures (82 removes pkg_resources). +# scripts/ci/build.sh builds with `python -m build --no-isolation`, so this pin is the setuptools the build uses. +# `build` is the PEP 517 frontend that script invokes. +python -m pip install --upgrade pip "setuptools<81" build ./scripts/ci/build.sh # From Fedora36, when using `pip install --prefix` with root privileges, the package is installed into `{prefix}/local/lib`. From 07dee97b451503daf9fd3d6d46a41bbc6585d17e Mon Sep 17 00:00:00 2001 From: aryasadeghi1 Date: Fri, 21 Aug 2026 17:46:30 +1000 Subject: [PATCH 2/2] {Packaging} Install the build frontend in jobs that source scripts/ci/build.sh scripts/ci/artifacts.sh sources scripts/ci/build.sh, so IntegrationTestAgainstProfiles and TestExtensionsLoading run the build too. Neither installed the PEP 517 frontend, so the build failed with 'No module named build'. Add it to both jobs, and provision it from build.sh when absent so the callers that no pipeline references (test_integration.sh, test_ref_doc.sh, the Windows MSI test flow) cannot hit the same failure. --- azure-pipelines.yml | 4 ++-- scripts/ci/build.sh | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 75ce83fc57f..ec92e49f382 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -577,7 +577,7 @@ jobs: displayName: 'Use Python $(python.version)' inputs: versionSpec: '$(python.version)' - - bash: pip install --upgrade pip wheel "setuptools<81" + - bash: pip install --upgrade pip wheel build "setuptools<81" displayName: 'Install pip and wheel' - bash: ./scripts/ci/test_profile_integration.sh displayName: 'Run Integration Test against Profiles' @@ -598,7 +598,7 @@ jobs: displayName: 'Use Python $(python.version)' inputs: versionSpec: '$(python.version)' - - bash: pip install --upgrade pip wheel "setuptools<81" + - bash: pip install --upgrade pip wheel build "setuptools<81" displayName: 'Install pip and wheel setuptools' - bash: ./scripts/ci/test_extensions.sh displayName: 'Load extensions' diff --git a/scripts/ci/build.sh b/scripts/ci/build.sh index 016341b15d2..c5a49c759f5 100755 --- a/scripts/ci/build.sh +++ b/scripts/ci/build.sh @@ -49,6 +49,13 @@ title 'Determine version' ############################################## # build product packages title 'Build Azure CLI and its command modules' + +# This script builds through the PEP 517 frontend. It is invoked both directly and by +# being sourced via scripts/ci/artifacts.sh, so the set of callers responsible for +# provisioning the frontend is easy to miss. Install it here if it is absent rather +# than failing partway through the build. +python -c 'import build' 2>/dev/null || python -m pip install --disable-pip-version-check -q build + for setup_file in $(find src -name 'setup.py'); do pushd $(dirname ${setup_file}) >/dev/null echo "Building module at $(pwd) ..."