feat: proxy-aware marketplace indexes#617
feat: proxy-aware marketplace indexes#617sergio-sisternes-epam merged 4 commits intomicrosoft:mainfrom
Conversation
Route marketplace browse/search/add through the registry proxy when PROXY_REGISTRY_URL is set. When PROXY_REGISTRY_ONLY=1 the GitHub Contents API fallback is blocked entirely, enabling air-gapped marketplace discovery. Closes microsoft#506 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR makes marketplace index fetching proxy-aware so apm marketplace add/browse/search/update can work in proxied or air-gapped environments by preferring the registry proxy (Artifactory Archive Entry Download) and optionally blocking direct GitHub API fallback when PROXY_REGISTRY_ONLY=1. It also adds support for registering marketplaces on non-github.com hosts and prevents cache collisions across hosts.
Changes:
- Add proxy-first fetch path for
marketplace.jsonviafetch_entry_from_archive(), with optional registry-only enforcement blocking GitHub fallback. - Add
--host(andHOST/OWNER/REPO) support toapm marketplace add, and include host in marketplace cache keys. - Add unit tests for proxy behavior and cache-key host isolation; update changelog.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
src/apm_cli/marketplace/client.py |
Implements proxy-first marketplace JSON fetch and host-aware cache keys / cache clearing. |
src/apm_cli/commands/marketplace.py |
Adds --host support and argument parsing for non-github.com marketplace repos; updates cache clearing to include host. |
tests/unit/marketplace/test_marketplace_client.py |
Adds unit tests covering proxy success/fallback/enforce-only and cache key behavior. |
CHANGELOG.md |
Adds an Unreleased entry describing the proxy-aware marketplace behavior. |
- Validate --host flag with is_valid_fqdn() and normalize to lowercase - Normalize host in _cache_key() for case-insensitive comparison - Update CHANGELOG to use backticks and include update command - Add docs for --host flag and proxy support in marketplace guide, CLI reference, and APM guide skill Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace `"ghes.corp.com" in key` with `startswith()`/`endswith()` assertions to satisfy CodeQL's URL substring sanitization check. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
sergio-sisternes-epam
left a comment
There was a problem hiding this comment.
Clean, well-scoped PR. Proxy support layers naturally into the existing _fetch_file() flow, tests are comprehensive (10 new covering all proxy paths), and docs/CHANGELOG/skill files are all updated consistently. One minor performance suggestion below.
Summary
apm marketplace add/browse/search/updatethrough the registry proxy (Artifactory Archive Entry Download) whenPROXY_REGISTRY_URLis setPROXY_REGISTRY_ONLY=1, enabling fully air-gapped marketplace discovery--hostflag tomarketplace addfor GHES / non-github.com marketplace reposBuilds on the shared
fetch_entry_from_archive()utility from #525.Closes #506
Design
_fetch_file()inmarketplace/client.pynow checksRegistryConfig.from_env()first. When a proxy is configured, it callsfetch_entry_from_archive()to fetchmarketplace.jsonvia the Artifactory Archive Entry Download API. If the proxy returns valid JSON, it is used directly. If it fails andPROXY_REGISTRY_ONLY=1, the GitHub API fallback is blocked._auto_detect_path()gains proxy support transparently since it calls_fetch_file()in a loop.Test plan
marketplace add/browse/search/updatewithPROXY_REGISTRY_ONLY=1againsthttps://artifactory-remote.checkpoint.com/artifactory/github/usinganthropics/skillsandarevlo/claude-code-workflowsRelated
fetch_entry_from_archive()infrastructure (merged)_parse_artifactory_base_url()ignoresPROXY_REGISTRY_URL(separate bug)apm install plugin@marketplacevalidation bypasses registry proxy #615 --apm install plugin@marketplacevalidation bypasses registry proxy (separate bug)🤖 Generated with Claude Code