feat: TEA (Transparency Exchange API) integration#186
Conversation
There was a problem hiding this comment.
Pull request overview
This PR integrates the Transparency Exchange API (TEA) into sbomify-action by adding libtea>=0.4.0 as a dependency, exposing libtea's CLI commands under sbomify-action tea, and adding a TeaSource enrichment plugin that auto-discovers TEA servers from PURL type mappings to fetch CLE lifecycle data (release date, end-of-support, end-of-life) and license information.
Changes:
- New
libtea>=0.4.0dependency (with transitive deps:pydantic,pydantic-core,semver,annotated-types,typing-inspection), plus bumps ofconan,identify, andsentry-sdk - New
sbomify_action/cli/tea.pyCLI group re-exporting libtea's commands plus a customfetchconvenience command - New
sbomify_action/_enrichment/sources/tea.pyenrichment source with PURL-to-domain auto-discovery and SSRF validation; registry early-exit logic updated to continue through CLE-capable sources even when NTIA fields are satisfied
Reviewed changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
pyproject.toml |
Adds libtea>=0.4.0,<1 as a direct dependency |
uv.lock |
Resolves libtea==0.4.0 and its transitive dependencies; bumps conan, identify, sentry-sdk |
sbomify_action/cli/tea.py |
New CLI subcommand group registering libtea's commands plus a custom fetch command |
sbomify_action/cli/main.py |
Registers tea_group into the CLI; refactors PRODUCT_RELEASE validation to strip whitespace and collect cleaned entries |
sbomify_action/_enrichment/sources/tea.py |
New enrichment source with SSRF-safe TEA_BASE_URL override, client caching, CLE event extraction |
sbomify_action/_enrichment/sources/__init__.py |
Exports TeaSource |
sbomify_action/_enrichment/registry.py |
Adds _CLE_PROVIDERS set and updates early-exit logic to continue querying CLE-capable sources even when NTIA fields are complete |
sbomify_action/_enrichment/metadata.py |
Adds cle_release_date to has_data() check |
sbomify_action/_enrichment/enricher.py |
Registers TeaSource at priority 43 and adds clear_tea() to clear_all_caches() |
tests/test_tea_enrichment.py |
22 new enrichment tests covering discovery, caching, CLE extraction, SSRF, token pass-through |
tests/test_tea_cli.py |
17 new CLI tests covering fetch flow, error handling, and _select_best_format |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
b3f9fd1 to
b199e9c
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 10 out of 11 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 10 out of 11 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 13 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 13 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 13 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 13 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 15 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 15 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 14 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
- Replace manual is_private/is_loopback/etc checks with ip.is_global which also rejects multicast (224.0.0.0/4, ff00::/8) and other non-globally-routable ranges - Add comment explaining str() wrap on to_string() for mypy strict
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 14 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…cstring - Add clear=True to test_fetch_base_url_override and test_fetch_base_url_with_token to prevent TEA_TOKEN env pollution - Update fetch_metadata docstring to describe two-phase early exit: NTIA+CLE complete stops entirely, NTIA-only skips non-CLE sources
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 14 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…erride first - Move _is_safe_url call inside cache-miss branch to avoid redundant DNS resolution on every _get_client invocation - Import libtea private helpers (_build_client, _error) via getattr with fallback functions that provide clear error messages if API changes - Check TEA_BASE_URL safety first in supports() — unsafe override now returns False for all PURL types instead of only unmapped ones
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 14 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Split _is_safe_url into a cached wrapper and _check_url_safety for the actual check. Results are memoized per URL in _url_safety_cache, making supports() O(1) after the first call. Cache is cleared by clear_cache().
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 14 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 14 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 14 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 14 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Summary
libtea>=0.4.0,<1dependency for TEA client supportsbomify-action teaCLI subcommand group (re-exports libtea's 15+ commands)sbomify-action tea fetchconvenience command (discovery → collection → download in one step)pypi→pypi.sbomify.com)TEA_BASE_URLenv var overrides auto-discovery for any PURL typeTEA_BASE_URL(rejects private, loopback, link-local, unspecified, and reserved IPs)Test plan