Skip to content

feat: add workspace dep versioning via hatch-teams-build plugin#378

Merged
heyitsaamir merged 6 commits intomainfrom
feat/nbgv-workspace-dep-versions
Apr 10, 2026
Merged

feat: add workspace dep versioning via hatch-teams-build plugin#378
heyitsaamir merged 6 commits intomainfrom
feat/nbgv-workspace-dep-versions

Conversation

@heyitsaamir
Copy link
Copy Markdown
Collaborator

@heyitsaamir heyitsaamir commented Apr 10, 2026

Problem

In a UV workspace, sibling packages reference each other as bare dependencies (e.g. microsoft-teams-common) with workspace = true source mappings. UV resolves these correctly during local development, but the source mappings are stripped at build time — published wheels end up with unconstrained Requires-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-nbgvhatch-teams-build and add a metadata hook that rewrites bare microsoft-teams-* dependencies to >=<current_nbgv_version> at build time.

Scenario Version Workspace deps in wheel
CI / release (nbgv available) 2.0.0a49 microsoft-teams-common>=2.0.0a49
Local dev (nbgv unavailable) 0.0.0 microsoft-teams-common (bare, unchanged)
CI with NBGV_REQUIRED=1 (nbgv missing) Hard error Build fails loudly

Changes

  • tools/hatch-teams-build/ — renamed from hatch-nbgv, now provides both a version source and metadata hook
  • All 11 packages/*/pyproject.toml — updated to use teams-build plugin name and opt into the metadata hook
  • templates/package/ — cookiecutter template uses dynamic versioning and the new plugin
  • pyproject.toml — scoped testpaths = ["packages"] so the main test suite doesn't collect plugin tests

Test plan

  • uv sync succeeds
  • uv build packages/apps --sdistRequires-Dist: microsoft-teams-api>=2.0.0a49
  • Build without nbgv → version 0.0.0, deps stay bare, no errors
  • NBGV_REQUIRED=1 without nbgv → hard error from both version source and metadata hook
  • poe test → 579 passed

🤖 Generated with Claude Code

…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>
Copilot AI review requested due to automatic review settings April 10, 2026 00:38
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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-nbgv with hatch-teams-build across 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.

Comment thread tools/hatch-teams-build/tests/test_metadata_hook.py Outdated
Comment thread tools/hatch-teams-build/src/hatch_teams_build/metadata_hook.py Outdated
Comment thread pyproject.toml
heyitsaamir and others added 5 commits April 9, 2026 17:51
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>
@heyitsaamir heyitsaamir merged commit 8366aeb into main Apr 10, 2026
7 checks passed
@heyitsaamir heyitsaamir deleted the feat/nbgv-workspace-dep-versions branch April 10, 2026 02:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants