Description
azpysdk breaking . --changelog --use-apistub --latest-pypi-version can produce an empty changelog in SDK generation when the newly generated local package has the same distribution version as the latest package on PyPI. Running the same command after automation bumps the local version produces the expected changelog.
Observed while generating azure-mgmt-relationships in pipeline build 6696107:
Reproduction
- Start with a published package such as
azure-mgmt-relationships==1.0.0b1.
- Generate a changed local package that still declares version
1.0.0b1.
- Run:
azpysdk breaking . --changelog --use-apistub --latest-pypi-version
The pipeline output includes:
Downloading azure-mgmt-relationships==1.0.0b1 from PyPI.
azure-mgmt-relationships is already installed with the same version as the provided wheel. Use --force-reinstall to force an installation of the wheel.
===== changelog start =====
===== changelog end =====
After the package version is updated locally to 1.0.0b2, the same command correctly reports the added APIs and breaking changes relative to PyPI 1.0.0b1.
Root cause
The APIStub changelog path generates the current report first and the stable PyPI report second. Both APIStub invocations use the same Python environment. The current invocation installs the local package. When the PyPI baseline has the same distribution name and version, pip skips installing the downloaded wheel, so the stable report is also generated from the local package. Comparing the two reports therefore yields an empty changelog.
The SDK generation workflow cannot simply bump the version first because the next version is calculated from the changelog result.
Suggested fix
Before APIStub processes a --generate-from-pypi wheel, uninstall the currently installed distribution using the same Python executable:
if generate_from_pypi:
pkg_path = self.download_pypi_wheel(
executable, package_name, generate_from_pypi, staging_directory
)
self.run_venv_command(
executable,
["-m", "pip", "uninstall", "-y", package_name],
cwd=staging_directory,
check=False,
immediately_dump=True,
)
This keeps the existing generation/version workflow, avoids the overhead of separate virtual environments, and ensures the downloaded baseline wheel is installed even when its version matches the local package. Alternatively, the APIStub installer could use pip install --force-reinstall.
Expected behavior
The current API report must always come from local source and the stable API report must always come from the requested PyPI wheel, regardless of whether their declared versions are equal.
Test coverage
Add a regression test where local source and the baseline wheel use the same package name and version but expose different APIs. Verify that the generated changelog is non-empty and that uninstall/reinstallation occurs only for the PyPI path.
Description
azpysdk breaking . --changelog --use-apistub --latest-pypi-versioncan produce an empty changelog in SDK generation when the newly generated local package has the same distribution version as the latest package on PyPI. Running the same command after automation bumps the local version produces the expected changelog.Observed while generating
azure-mgmt-relationshipsin pipeline build 6696107:Reproduction
azure-mgmt-relationships==1.0.0b1.1.0.0b1.azpysdk breaking . --changelog --use-apistub --latest-pypi-versionThe pipeline output includes:
After the package version is updated locally to
1.0.0b2, the same command correctly reports the added APIs and breaking changes relative to PyPI1.0.0b1.Root cause
The APIStub changelog path generates the current report first and the stable PyPI report second. Both APIStub invocations use the same Python environment. The current invocation installs the local package. When the PyPI baseline has the same distribution name and version, pip skips installing the downloaded wheel, so the stable report is also generated from the local package. Comparing the two reports therefore yields an empty changelog.
The SDK generation workflow cannot simply bump the version first because the next version is calculated from the changelog result.
Suggested fix
Before APIStub processes a
--generate-from-pypiwheel, uninstall the currently installed distribution using the same Python executable:This keeps the existing generation/version workflow, avoids the overhead of separate virtual environments, and ensures the downloaded baseline wheel is installed even when its version matches the local package. Alternatively, the APIStub installer could use
pip install --force-reinstall.Expected behavior
The current API report must always come from local source and the stable API report must always come from the requested PyPI wheel, regardless of whether their declared versions are equal.
Test coverage
Add a regression test where local source and the baseline wheel use the same package name and version but expose different APIs. Verify that the generated changelog is non-empty and that uninstall/reinstallation occurs only for the PyPI path.