Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
afb5228
Pin microsoft-teams-api in version 2.0.16
ceciliaavila Sep 10, 2026
b2661ef
Implement Teams API Drift Detector workflows
ceciliaavila Sep 9, 2026
a23e990
Pin version 2.0.16 of microsoft-teams-api
ceciliaavila Sep 9, 2026
e5919f9
Fix error en tests
ceciliaavila Sep 10, 2026
d21307b
Apply batched suggestions from code review
ceciliaavila Sep 10, 2026
11335a7
Apply Copilot's feedback
ceciliaavila Sep 15, 2026
7a5f9ac
Avoid pull_request_target and cross-job artifact consumption that cau…
ceciliaavila Sep 15, 2026
3c3cfae
Pin microsoft-teams-api in version 2.0.16
ceciliaavila Sep 10, 2026
ab81ad5
Implement Teams API Drift Detector workflows
ceciliaavila Sep 9, 2026
1f06b76
Pin version 2.0.16 of microsoft-teams-api
ceciliaavila Sep 9, 2026
34c6f6c
Fix error en tests
ceciliaavila Sep 10, 2026
ea75d5a
Apply batched suggestions from code review
ceciliaavila Sep 10, 2026
9e6487d
Apply Copilot's feedback
ceciliaavila Sep 15, 2026
b56555b
Avoid pull_request_target and cross-job artifact consumption that cau…
ceciliaavila Sep 15, 2026
4f09c0f
Add teams metadata validation
ceciliaavila Sep 10, 2026
af72c81
Use underscore for variable name
ceciliaavila Sep 10, 2026
a0332f5
Merge branch 'southworks/add/teams-api-drift-detector' of https://git…
ceciliaavila Sep 16, 2026
f094592
Tighten advisory validator
ceciliaavila Sep 16, 2026
6c05835
Merge branch 'main' into southworks/add/teams-api-drift-detector
ceciliaavila Sep 24, 2026
c802366
Merge branch 'southworks/add/teams-api-drift-detector' into southwork…
ceciliaavila Sep 24, 2026
102cb8a
Refactor validation for capability owners and areas
ceciliaavila Sep 24, 2026
a0b4064
Merge branch 'main' into southworks/add/metadata-check
ceciliaavila Sep 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 65 additions & 1 deletion .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,70 @@ on:
branches: [ "main", "release/*" ]

jobs:
teams-api-metadata-changes:
name: Detect MSTeams metadata-relevant changes
if: ${{ github.event_name == 'pull_request' }}
Comment thread
ceciliaavila marked this conversation as resolved.
runs-on: ubuntu-latest
outputs:
changed: ${{ steps.changed.outputs.changed }}
base_ref: ${{ steps.changed.outputs.base_ref }}
steps:
- name: Checkout repository with full history
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- id: changed
name: Check changed paths
env:
PR_BASE_SHA: ${{ github.event.pull_request.base.sha }}
PUSH_BASE_SHA: ${{ github.event.before }}
shell: bash
run: |
base_ref="$PR_BASE_SHA"
if [[ -z "$base_ref" ]]; then
base_ref="$PUSH_BASE_SHA"
fi
if [[ -z "$base_ref" || "$base_ref" == "0000000000000000000000000000000000000000" ]]; then
echo "changed=false" >> "$GITHUB_OUTPUT"
exit 0
fi

if git diff --quiet "$base_ref" "$GITHUB_SHA" -- \
libraries/microsoft-agents-hosting-msteams/microsoft_agents/hosting/msteams \
libraries/microsoft-agents-hosting-msteams/setup.py \
libraries/microsoft-agents-hosting-msteams/teams-api-usage-manifest.json \
libraries/microsoft-agents-hosting-msteams/config/teams-capabilities.yaml; then
echo "changed=false" >> "$GITHUB_OUTPUT"
else
echo "changed=true" >> "$GITHUB_OUTPUT"
fi
echo "base_ref=$base_ref" >> "$GITHUB_OUTPUT"

teams-api-metadata:
name: Validate Teams API metadata accuracy
needs: teams-api-metadata-changes
if: ${{ needs.teams-api-metadata-changes.outputs.changed == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Checkout repository with full history
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- name: Set up Python 3.12
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.12"
cache: pip
cache-dependency-path: scripts/teams-api-drift/requirements.txt
- name: Install Teams API drift tooling
run: python -m pip install -r scripts/teams-api-drift/requirements.txt
- name: Validate usage and capability metadata
env:
BASE_REF: ${{ needs.teams-api-metadata-changes.outputs.base_ref }}
run: >-
python scripts/teams-api-drift/teams-api-drift.py verify-usage
--base-ref "$BASE_REF"

build:

runs-on: ubuntu-latest
Expand Down Expand Up @@ -80,4 +144,4 @@ jobs:
python -m pip install ./dist/microsoft_agents_testing*.whl
- name: Test with pytest
run: |
pytest -W "ignore:SelectableGroups dict interface is deprecated. Use select.:DeprecationWarning"
pytest -W "ignore:SelectableGroups dict interface is deprecated. Use select.:DeprecationWarning"
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
# Curated ownership map. Direct compatibility always takes precedence over adoption.
# For capability maintenance and sourceReview acknowledgments, see
# scripts/teams-api-drift/README.md#source-review-acknowledgments.
schemaVersion: 1
dependency:
package: microsoft-teams-api
capabilities:
teams-api-client:
description: Creates, caches and exposes the Teams API client for a turn.
owners: [microsoft_agents/hosting/msteams/_teams_api_client.py, microsoft_agents/hosting/msteams/teams_turn_context.py]
owners: [microsoft_agents/hosting/msteams/_teams_api_client.py, microsoft_agents/hosting/msteams/teams_agent_extension.py, microsoft_agents/hosting/msteams/teams_turn_context.py]
upstreamAreas: [microsoft_teams.api.clients]
adoptionPolicy: strict-compatibility
activity-data:
Expand All @@ -25,7 +27,7 @@ capabilities:
adoptionPolicy: review-new-members
meetings:
description: Routes meeting lifecycle and participant events.
owners: [microsoft_agents/hosting/msteams/meeting]
owners: [microsoft_agents/hosting/msteams/meeting, microsoft_agents/hosting/msteams/teams_activity.py]
upstreamAreas: [microsoft_teams.api.models.meetings, microsoft_teams.api.clients.meeting]
adoptionPolicy: review-new-members
message-extensions:
Expand Down
51 changes: 45 additions & 6 deletions scripts/teams-api-drift/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,53 @@ The adjacent `config/teams-capabilities.yaml` maps upstream module areas to
feature owners and adoption policies. It supports strict compatibility,
review-new-members and advisory-only policies. It does not authorize adoption.

### Source review acknowledgments

The main Python CI workflow checks extension source changes against both metadata
documents.
Update `teams-api-usage-manifest.json` when a changed file adds, removes, or
changes Teams API imports, calls, model fields, construction, validation, or
public exposure. Update `config/teams-capabilities.yaml` when files are added,
removed, moved between features, or change the upstream areas owned by a feature.

Some source edits do not affect either document. For a usage-related edit that
has been reviewed and needs no usage metadata change, add or change this property
in `teams-api-usage-manifest.json`:

```json
"sourceReview": {
"outcome": "no-usage-metadata-change",
"reason": "Explain specifically why the changed source preserves recorded usage."
}
```

For a structural or capability-related edit that needs no capability metadata
change, add or change this property in `config/teams-capabilities.yaml`:

```yaml
sourceReview:
outcome: no-capability-metadata-change
reason: Explain specifically why capability ownership and upstream areas remain accurate.
```

The acknowledgment must differ from the base branch, include a non-empty reason,
and be committed with or after the source change. A previous acknowledgment cannot
silently approve later edits. Run the same review locally with:

```bash
python scripts/teams-api-drift/teams-api-drift.py verify-usage --base-ref main
```

## Workflows

PRs to `main` or `release/*` run dependency analysis only when the exact Teams
version pin in `setup.py` changes. The base branch pin is the baseline and the PR
pin is the candidate. Manual PR-workflow dispatch takes explicit `from` and `to`
versions. The weekly workflow runs Monday at 08:00 UTC and compares the current
pin (currently 2.0.16) with the latest stable release, including future major
versions. Once maintainers approve an upgrade, changing the pin establishes the
The Python package workflow validates usage and capability metadata whenever the
MSTeams source or either metadata document changes. The Teams API drift PR
workflow still runs only when the exact Teams version pin in `setup.py` changes.
The base branch pin is the baseline and the PR pin is the candidate. Manual
PR-workflow dispatch takes explicit `from` and `to` versions. The weekly workflow
runs Monday at 08:00 UTC and compares the current pin (currently 2.0.16) with the
latest stable release, including future major versions.
Once maintainers approve an upgrade, changing the pin establishes the
new baseline. When the resolved versions are identical, manual and scheduled runs
finish successfully after version resolution; comparison, tests, reports, AI and
publication are skipped.
Expand Down
10 changes: 8 additions & 2 deletions scripts/teams-api-drift/teams_api_drift/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
write_text,
)
from .compare import compare_versions
from .metadata import validate_teams_api_metadata
from .report import prepare_context, render_report, validate_agent_report
from .resolve import resolve_versions

Expand Down Expand Up @@ -74,6 +75,10 @@ def main(command=None, argv=None):
elif command == "verify-usage":
parser.add_argument("--manifest", "-m", type=Path, default=MANIFEST)
parser.add_argument("--capabilities", type=Path, default=CAPABILITIES)
parser.add_argument(
"--base-ref",
help="Git ref used to verify metadata review for changed source files",
)
elif command == "prepare-candidate":
parser.add_argument("--version", required=True)
parser.add_argument("--environment", type=Path, required=True)
Expand Down Expand Up @@ -144,8 +149,9 @@ def main(command=None, argv=None):
write_json(destination(args.output, "resolved-versions.json"), result)
print(json.dumps(result))
elif command == "verify-usage":
manifest = validate_manifest(read_json(args.manifest))
read_capabilities(args.capabilities)
manifest = validate_teams_api_metadata(
args.manifest, args.capabilities, base_ref=args.base_ref
)
print(f"Verified {len(manifest['usages'])} Teams API usages")
elif command == "prepare-candidate":
result = prepare_candidate_environment(
Expand Down
Loading
Loading