feat: add workspace dep versioning via hatch-teams-build plugin#378
Merged
heyitsaamir merged 6 commits intomainfrom Apr 10, 2026
Merged
feat: add workspace dep versioning via hatch-teams-build plugin#378heyitsaamir merged 6 commits intomainfrom
heyitsaamir merged 6 commits intomainfrom
Conversation
…rsioning Built wheels previously emitted bare `Requires-Dist: microsoft-teams-common` with no version constraint, allowing pip to mix incompatible versions. The renamed hatch-teams-build plugin now includes a metadata hook that rewrites workspace deps to `>=<current_nbgv_version>` at build time, and gracefully skips rewriting when nbgv is unavailable (fallback 0.0.0). Also updates the cookiecutter package template to use dynamic versioning. Co-Authored-By: Claude <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Renames the Hatchling build plugin to hatch-teams-build and extends it with a metadata hook that, at build time, constrains bare microsoft-teams-* dependencies to >=<current version> to avoid mixing incompatible SDK package versions.
Changes:
- Replace
hatch-nbgvwithhatch-teams-buildacross the workspace and package build configurations. - Add a Hatchling metadata hook to rewrite bare workspace dependencies to
>=<current nbgv-derived version>(with a fallback when nbgv is unavailable). - Update the cookiecutter package template to use dynamic versioning and the new plugin.
Reviewed changes
Copilot reviewed 22 out of 23 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| uv.lock | Updates lock entries to use hatch-teams-build instead of hatch-nbgv. |
| tools/hatch-teams-build/pyproject.toml | Defines the renamed plugin distribution, dependencies, and Hatch entry point. |
| tools/hatch-teams-build/src/hatch_teams_build/version_source.py | Renames the version source plugin to TeamsBuildVersionSource / teams-build. |
| tools/hatch-teams-build/src/hatch_teams_build/metadata_hook.py | Implements metadata hook to rewrite bare microsoft-teams-* deps to >=<version>. |
| tools/hatch-teams-build/src/hatch_teams_build/hooks.py | Registers the version source + metadata hook with Hatchling. |
| tools/hatch-teams-build/src/hatch_teams_build/init.py | Exposes the new plugin components. |
| tools/hatch-teams-build/tests/test_metadata_hook.py | Adds unit tests for version stripping and dependency rewriting behavior. |
| tools/hatch-teams-build/tests/init.py | Removes old hatch-nbgv test exports. |
| tools/hatch-nbgv/src/hatch_nbgv/hooks.py | Removes the old plugin hook registration file. |
| pyproject.toml | Switches the workspace tool source + release deps to hatch-teams-build. |
| packages/apps/pyproject.toml | Uses hatch-teams-build for dynamic versioning and enables the metadata hook. |
| packages/api/pyproject.toml | Uses hatch-teams-build for dynamic versioning and enables the metadata hook. |
| packages/ai/pyproject.toml | Uses hatch-teams-build for dynamic versioning and enables the metadata hook. |
| packages/botbuilder/pyproject.toml | Uses hatch-teams-build for dynamic versioning and enables the metadata hook. |
| packages/devtools/pyproject.toml | Uses hatch-teams-build for dynamic versioning and enables the metadata hook. |
| packages/graph/pyproject.toml | Uses hatch-teams-build for dynamic versioning and enables the metadata hook. |
| packages/mcpplugin/pyproject.toml | Uses hatch-teams-build for dynamic versioning and enables the metadata hook. |
| packages/openai/pyproject.toml | Uses hatch-teams-build for dynamic versioning and enables the metadata hook. |
| packages/a2aprotocol/pyproject.toml | Uses hatch-teams-build for dynamic versioning and enables the metadata hook. |
| packages/common/pyproject.toml | Switches version source to teams-build. |
| packages/cards/pyproject.toml | Switches version source to teams-build. |
| templates/package/cookiecutter.json | Removes explicit version prompt (template now uses dynamic versioning). |
| templates/package/{{cookiecutter.pypi_package_name}}/pyproject.toml | Updates template to dynamic versioning + new plugin + metadata hook section. |
The CI was failing because pytest collected hatch-teams-build tests which can't import the plugin (it's a build dep, not in the workspace venv). Fix by setting testpaths=["packages"] and removing the tests __init__.py. Also adds a README explaining how the plugin works. Co-Authored-By: Claude <noreply@anthropic.com>
Build output inspection (uv build + PKG-INFO) is the real verification. These tests were awkward to run and couldn't be part of the normal test suite. Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
The version source already raises when nbgv is missing and NBGV_REQUIRED is set, but add an explicit check in the metadata hook too so CI never silently publishes wheels with bare deps. Co-Authored-By: Claude <noreply@anthropic.com>
Addresses Copilot review — the metadata hook now imports FALLBACK_VERSION from the version source instead of hardcoding "0.0.0". Co-Authored-By: Claude <noreply@anthropic.com>
lilyydu
approved these changes
Apr 10, 2026
This was referenced Apr 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
In a UV workspace, sibling packages reference each other as bare dependencies (e.g.
microsoft-teams-common) withworkspace = truesource mappings. UV resolves these correctly during local development, but the source mappings are stripped at build time — published wheels end up with unconstrainedRequires-Dist: microsoft-teams-common, meaning pip will happily install any version, even an incompatible one from a different release.This is the same problem that hatch-cada solves for generic workspaces. Rather than adding an external dependency, we extend our existing build plugin to handle it in-house with full control over the behavior.
Solution
Rename
hatch-nbgv→hatch-teams-buildand add a metadata hook that rewrites baremicrosoft-teams-*dependencies to>=<current_nbgv_version>at build time.2.0.0a49microsoft-teams-common>=2.0.0a490.0.0microsoft-teams-common(bare, unchanged)NBGV_REQUIRED=1(nbgv missing)Changes
tools/hatch-teams-build/— renamed fromhatch-nbgv, now provides both a version source and metadata hookpackages/*/pyproject.toml— updated to useteams-buildplugin name and opt into the metadata hooktemplates/package/— cookiecutter template uses dynamic versioning and the new pluginpyproject.toml— scopedtestpaths = ["packages"]so the main test suite doesn't collect plugin testsTest plan
uv syncsucceedsuv build packages/apps --sdist→Requires-Dist: microsoft-teams-api>=2.0.0a490.0.0, deps stay bare, no errorsNBGV_REQUIRED=1without nbgv → hard error from both version source and metadata hookpoe test→ 579 passed🤖 Generated with Claude Code