Repository navigation
feat(marketplace): load live local catalogs directly from apm.yml - #3367
Nadeesha D Shalom (Nadeesha-D-Shalom) wants to merge 1 commit into
Conversation
|
Nadeesha D Shalom (@Nadeesha-D-Shalom) please read the following Contributor License Agreement(CLA). If you agree with the CLA, please reply with the following information.
Contributor License AgreementContribution License AgreementThis Contribution License Agreement (“Agreement”) is agreed to by the party signing below (“You”),
|
There was a problem hiding this comment.
🟢 Approval recommended
No blocking issues were identified, and focused regression coverage supports the canonical routing, containment, snapshot and compatibility behavior.
No open issues 🎉
What changed in this PR
Implements #2729 by allowing explicitly selected local apm.yml files to serve as live marketplace catalogs, reusing existing authoring and installation machinery without generating JSON.
Changes:
- Adds invocation-local catalog snapshots, canonical validation and path containment, with fresh reads on later operations.
- Adds bounded
--offlinesupport for registration and browsing while preserving existing catalog and dependency workflows. - Adds regression tests, architecture guards and documentation for local previews.
| File | Description |
|---|---|
| tests/unit/marketplace/test_authoring_source.py | Tests snapshots, containment, offline behavior and native-output preservation. |
| tests/integration/test_marketplace_authoring_lifecycle.py | Covers discovery, selected installation, replay and existing-source compatibility. |
| tests/integration/test_architecture_authoring_source.py | Tests rejection of packing calls in the read-only adapter. |
| src/apm_cli/marketplace/client.py | Routes explicitly selected local YAML catalogs to the adapter. |
| src/apm_cli/marketplace/builder.py | Composes discovery catalogs and avoids local-only credential initialization. |
| src/apm_cli/marketplace/authoring_source.py | Coordinates validation, resolution, containment and invocation snapshots. |
| src/apm_cli/commands/marketplace/__init__.py | Adds local YAML examples and bounded offline options. |
| scripts/architecture_linter/checks/marketplace_catalog_and_contract.py | Enforces canonical routing and the adapter's no-writing boundary. |
| packages/apm-guide/.apm/skills/apm-usage/commands.md | Documents live previews and offline limits. |
| docs/src/content/docs/reference/cli/marketplace.md | Explains command behavior, snapshots and dependency portability. |
| docs/src/content/docs/producer/publish-to-a-marketplace.md | Adds the producer's direct local-preview workflow. |
| docs/src/content/docs/consumer/installing-from-marketplaces.md | Explains discovery and installation from local authoring catalogs. |
| .apm/architecture/owners/marketplace-plugins.json | Registers ownership and the guard for live authoring catalogs. |
Review effort: Balanced
add(marketplace): load live local catalogs directly from apm.yml
TL;DR
Allow
apm marketplace add ./apm.yml --name alice-devto register an explicitly selected local authoring catalog without generating JSON first.Later explicit operations reread that file, while each invocation uses one configuration snapshot.
Selected installs retain the actual package dependency and existing lockfile semantics.
Issue and approved scope
Fixes #2729.
Human approval: #2729 (comment)
Review contact: Daniel Meppiel (@danielmeppiel).
This implements the bounded local-authoring change.
Registry-backed authoring, durable catalog-following intent, and the separate enterprise API conformance scenario remain with their respective issues.
Important
Registration creates a local discovery source. It does not publish packages, install inventory, activate plugins, or run package hooks.
Local paths and hashes remain local dependencies; they do not distribute files to other machines.
Problem (WHY)
Approach (WHAT)
apm.yml; retain existing source classification for JSON, Git and hosted JSON.--offlinebehavior onmarketplace addandmarketplace browse.Implementation (HOW)
src/apm_cli/marketplace/authoring_source.pysrc/apm_cli/marketplace/client.pysrc/apm_cli/marketplace/builder.pysrc/apm_cli/commands/marketplace/__init__.py.apm/architecture/owners/marketplace-plugins.jsonandscripts/architecture_linter/checks/marketplace_catalog_and_contract.pytests/unit/marketplace/test_authoring_source.pytests/integration/test_marketplace_authoring_lifecycle.pylifecycle_smokeselection.tests/integration/test_architecture_authoring_source.pypackages/apm-guide/.apm/skills/apm-usage/commands.mdThe dashed nodes identify the new local input and its in-memory discovery view; existing consumer and lockfile owners remain downstream.
flowchart LR A[Explicit local apm.yml] --> B[Canonical authoring parser] B --> C[Canonical ref resolver] C --> D[In-memory discovery composer] D --> E[Existing marketplace consumer] E --> F[Browse or view] E --> G[Install selected actual dependency] G --> H[Existing manifest and lockfile] I[JSON or Git or HTTPS catalog] --> E classDef added stroke-dasharray:5 5 class A,D addedThe diagram was rendered successfully with
mmdc.Trade-offs
--offlineis limited to this local YAML path. Full commit SHAs and local entries work without network; tags and ranges are not persisted for later offline invocations.pluginRootlayout hints are omitted from the temporary discovery view so authored paths remain relative to the selected file. Native generated catalogs retain their original representation, verified before and after discovery composition.Benefits
apm pack.Validation
Python 3.12.15 and dependencies installed from the unchanged
uv.lockwithuv sync --frozen --extra dev --extra build.Marketplace regression suite and new architecture guard:
The five deselections are symlink-related cases requiring privileges unavailable to this Windows account. They are not disabled in the committed suite.
PyInstaller 6.17.0 packaged executable, selected through
APM_BINARY_PATH:Full Ruff lint and formatting:
Full duplication check (
pylint R0801):Architecture linter exited 0. Auth and assertion/duplicate ratchets:
Documentation build and generated-page link checks:
git diff --checkpassed. These are local Windows results; required GitHub checks and maintainer review still apply.Scenario Evidence
tests/integration/test_marketplace_authoring_lifecycle.py::test_live_local_catalog_register_browse_view_install_and_edittests/integration/test_marketplace_authoring_lifecycle.py::test_failed_reregistration_preserves_registered_sourcetests/integration/test_marketplace_authoring_lifecycle.py::test_remote_entry_records_real_source_and_replays_without_previewtests/integration/test_marketplace_authoring_lifecycle.py::test_existing_catalog_sources_still_register_without_authoring_resolutiontests/unit/marketplace/test_authoring_source.py::test_plugin_root_never_rebases_authored_package_pathstests/unit/marketplace/test_authoring_source.py::test_discovery_composition_does_not_change_native_outputtests/unit/marketplace/test_authoring_source.py::test_local_catalog_does_not_resolve_remote_credentials;::test_pinned_remote_commit_needs_no_ref_or_metadata_networktests/unit/marketplace/test_authoring_source.py::test_invocation_snapshot_is_shared_but_next_invocation_rereadsHow to test
uv sync --frozen --extra dev --extra build.uv run --frozen pytest tests/unit/marketplace tests/integration/test_architecture_authoring_source.py; expect the marketplace suite to pass on the CI platform.uv run --frozen pytest tests/integration/test_marketplace_authoring_lifecycle.py; expect all eight scenarios to pass using the installed CLI. For packaged validation, build withbuild/apm.spec, setAPM_BINARY_PATHto the resulting executable, and repeat.apm marketplace add ./apm.yml --name alice-dev, edit it, and browse again. Expect current entries with no generated catalog writes; a malformed edit must fail without replacing registration.cd docs && npm ci && npm run build; expect clean checks and valid relative links.Type of change and testing
Spec conformance