Repository navigation
{CI} Upgrade azdev to decouple from wheel 0.30.0 - #9922
Conversation
Drop the wheel==0.30.0 and setuptools==70.0.0 pins and read extension metadata through azdev's pkginfo path instead of the old metadata.json. IndexVerify now installs azdev so test_index.py can import util. Added e2e packaging tests for the az/azdev lifecycle and metadata parity.
️✔️Azure CLI Extensions Breaking Change Test
|
|
Hi aryasadeghi1, |
|
CI |
There was a problem hiding this comment.
Pull request overview
This PR updates CI and validation tooling to decouple extension metadata handling from wheel==0.30.0 by switching to azdev’s pkginfo-based metadata, and adds an e2e packaging test harness to exercise extension build/install flows under the active packaging toolchain.
Changes:
- Update
scripts/ci/util.py+scripts/ci/test_index.pyto compare metadata semantically (ignoring legacy wheel-only noise fields) and remove dependency onwheel.install.WHEEL_INFO_RE. - Update Azure Pipelines templates/jobs to install azdev (temporarily from
azure-cli-dev-toolssource) and drop legacy wheel/setuptools pins. - Add
tests/e2e/packagingharness + tests for CLI/azdev lifecycle, build isolation behavior, and metadata parity checks.
Reviewed changes
Copilot reviewed 14 out of 18 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
azure-pipelines.yml |
Removes wheel pin and installs azdev so index verification can run with pkginfo-based metadata. |
.azure-pipelines/templates/azdev_setup.yml |
Switches azdev install to source (temporarily) and removes setuptools pin. |
scripts/ci/util.py |
Reads wheel metadata via azdev’s pkginfo helper instead of legacy metadata.json. |
scripts/ci/test_index.py |
Compares metadata by meaning (canonicalized deps / ignored noise keys) and removes wheel regex dependency. |
.github/pull_request_template.md |
Updates local checklist for running test_index.py. |
.gitignore |
Ignores additional .venv* directories at repo root. |
pytest.ini |
Defines markers for the new e2e packaging test suite. |
tests/e2e/packaging/test_packaging_smoke.py |
Adds smoke tests to fail fast when the harness is unusable. |
tests/e2e/packaging/test_packaging_lifecycle.py |
Adds end-to-end build/install/remove tests for az and azdev, including build-isolation scenarios. |
tests/e2e/packaging/test_extension_metadata_parity.py |
Adds parity tests comparing pkginfo-derived metadata against src/index.json with allowlisted noise. |
tests/e2e/packaging/runner.py |
Adds a cross-platform command runner (notably PATHEXT-aware on Windows). |
tests/e2e/packaging/run_local.ps1 |
Convenience script to run packaging tests locally with a portable Python resolution strategy. |
tests/e2e/packaging/fixtures/manifest.json |
Declares packaging fixtures and which are enabled in tests. |
tests/e2e/packaging/fixtures.py |
Loads the fixture manifest into typed objects. |
tests/e2e/packaging/conftest.py |
Adds pytest fixtures for repo root, fixture manifest, and temp extension dir. |
tests/e2e/packaging/__init__.py |
Marks packaging tests as a package. |
tests/e2e/__init__.py |
Marks e2e tests as a package. |
tests/__init__.py |
Marks tests as a package. |
| from packaging import version | ||
| from util import SRC_PATH | ||
| from wheel.install import WHEEL_INFO_RE | ||
| from util import SRC_PATH |
| azext_metadata = _get_azext_metadata(ext_dir) | ||
|
|
||
| if not azext_metadata: | ||
| raise ValueError('azext_metadata.json for Extension "{}" Metadata is missing'.format(ext_name)) | ||
|
|
||
| metadata.update(azext_metadata) | ||
|
|
||
| for dist_info_dirname in dist_info_dirs: | ||
| parsed_dist_info_dir = WHEEL_INFO_RE(dist_info_dirname) | ||
| if parsed_dist_info_dir and parsed_dist_info_dir.groupdict().get('name') == ext_name.replace('-', '_'): | ||
| whl_metadata_filepath = os.path.join(ext_dir, dist_info_dirname, WHL_METADATA_FILENAME) | ||
| if os.path.isfile(whl_metadata_filepath): | ||
| with open(whl_metadata_filepath) as f: | ||
| metadata.update(json.load(f)) | ||
| if azext_metadata: | ||
| metadata.update(azext_metadata) | ||
| metadata.update(generated_metadata) |
| sub_golden = golden | ||
| sub_candidate = candidate | ||
| present_in_both = True | ||
| for p in parts: | ||
| if isinstance(sub_golden, dict) and p in sub_golden: | ||
| sub_golden = sub_golden[p] | ||
| else: | ||
| present_in_both = False | ||
| break | ||
| if isinstance(sub_candidate, dict) and p in sub_candidate: | ||
| sub_candidate = sub_candidate[p] | ||
| else: | ||
| present_in_both = False | ||
| break | ||
| path_text = "/".join(parts) if parts else "(root)" | ||
| if not present_in_both: | ||
| report.schema_gaps.append(path_text) | ||
| else: | ||
| report.real_bugs.append(path_text) |
| try: | ||
| with tempfile.TemporaryDirectory(prefix="e2e-metadata-") as tmp: | ||
| tmp_path = Path(tmp) | ||
| wheel_path = _build_wheel(fixture.path, tmp_path / "wheel") | ||
| extract_dir = tmp_path / "extract" | ||
| extract_dir.mkdir(parents=True, exist_ok=True) | ||
| candidate = get_ext_metadata(str(extract_dir), str(wheel_path), fixture.name) | ||
| golden = _load_latest_index_entry(candidate["name"]) | ||
| report = _classify_diff(candidate, golden) | ||
| return candidate, report | ||
| except Exception as exc: | ||
| pytest.skip("Could not build wheel for '{}': {}".format(fixture_name, exc)) |
| # pkginfo-based metadata module (decoupled from wheel==0.30.0), so azdev must be | ||
| # installed here. Install from the merged azure-cli-dev-tools source until azdev | ||
| # 0.2.11b1 is published to PyPI, then switch this to: pip install --upgrade "azdev==0.2.11b1" | ||
| pip install --upgrade "git+https://github.com/Azure/azure-cli-dev-tools.git@dev#egg=azdev" |
| # azdev 0.2.11b1 (decouples extension metadata from wheel==0.30.0) is not on PyPI yet. | ||
| # Install from the merged azure-cli-dev-tools source until the pre-release is published, | ||
| # then switch this back to: pip install --upgrade "azdev==0.2.11b1" | ||
| pip install --upgrade "git+https://github.com/Azure/azure-cli-dev-tools.git@dev#egg=azdev" |
Restore the ValueError when azext_metadata.json is missing so test_index still flags wheels with no azext metadata. Pin azdev to a specific dev-tools commit instead of @dev in azdev_setup for reproducible builds. In the metadata parity test, separate missing-from-candidate (schema gap) from extra candidate fields, and stop turning non-build errors into skips. Note that test_index now needs azdev in the PR template, drop a stray trailing space, and ignore the cosmetic license_file field in the diff.
The pkginfo path serializes optional extras differently than the old wheel 0.30.0 index entries, so extensions that declare an extra (connectedk8s 1.11.0, stack-hci-vm) tripped test_metadata even though their real runtime deps match. Drop extra-gated requirements and the extras field from the comparison, ignore the cosmetic wheel-only fields (description_content_type, project_url, license_file, python.details), and skip the two old entries whose published index predates run_requires / maxCliCoreVersion capture.
| # pkginfo-based metadata module (decoupled from wheel==0.30.0), so azdev must be | ||
| # installed here. Install from the merged azure-cli-dev-tools source until azdev | ||
| # 0.2.11b1 is published to PyPI, then switch this to: pip install --upgrade "azdev==0.2.11b1" | ||
| pip install --upgrade "git+https://github.com/Azure/azure-cli-dev-tools.git@dev#egg=azdev" |
There was a problem hiding this comment.
Out of curiosity, is the Kenny Hietbrink (@dev) (vs the pinned SHA in azdev_setup.yml) intentional?
There was a problem hiding this comment.
It's not intentional, I will push a fix for this!
There was a problem hiding this comment.
Whilst its inconsistency across the .yml files it should not influence the behaviour as Kenny Hietbrink (@dev) without SHA includes the changes applied.
There was a problem hiding this comment.
This is now addressed!
Matches azdev_setup.yml so both pipeline jobs install the same azdev build and CI stays reproducible.
Part of #7740. Needs azdev 0.2.11b1 (azure-cli-dev-tools#549).
We've been pinned to wheel==0.30.0 because the old metadata.json it wrote is what azdev read to build index.json entries. Newer wheel stopped writing that file, so this switches the CI over to azdev's pkginfo-based metadata and drops
the wheel==0.30.0 / setuptools==70.0.0 pins.
Changes:
pytest tests/e2e/packagingpasses locally (13 tests).Still TODO after this: publish azdev 0.2.11b1 and flip the source installs back
to azdev==0.2.11b1, and eventually the pyproject.toml migration.