fix: install versioned marketplace package directories - #3156
Open
sama Pyb (Pybsama) wants to merge 4 commits into
Open
sama Pyb (Pybsama) wants to merge 4 commits into
sama Pyb (Pybsama) wants to merge 4 commits into
Conversation
sama Pyb (Pybsama)
requested review from
Daniel Meppiel (danielmeppiel) and
Sergio Sisternes (sergio-sisternes-epam)
as code owners
October 3, 2026 05:45
Contributor
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The Contents API path can still accept non-directory entries before the stricter Git tree check runs.
Review effort: Balanced
Findings: 1
Open (2)
What changed in this PR
Fixes installation of versioned marketplace package directories while preserving structured Git/path references.
Changes:
- Resolves dotted marketplace directories as explicit Git/path dependencies.
- Preserves structured identities during selective installs and dry runs.
- Adds Git tree validation and regression coverage.
| File | Description |
|---|---|
.apm/architecture/owners/install-deployment.json |
Registers package-selection ownership. |
scripts/architecture_linter/checks/install_dry_run_plan.py |
Guards structured selector usage. |
src/apm_cli/deps/github_downloader_validation.py |
Tightens Git tree probing. |
src/apm_cli/install/dry_run_plan.py |
Preserves interpreted dependency identities. |
src/apm_cli/install/package_selection.py |
Centralizes selector identity resolution. |
src/apm_cli/install/phases/resolve.py |
Uses structured references during filtering. |
src/apm_cli/marketplace/resolver.py |
Handles dotted marketplace directory paths. |
tests/integration/test_architecture_owner_rule_mutations.py |
Tests architecture guard enforcement. |
tests/integration/test_marketplace_versioned_directory_lifecycle.py |
Covers the complete install lifecycle. |
tests/unit/deps/test_github_downloader_validation.py |
Updates expected Git tree output. |
tests/unit/deps/test_versioned_directory_probe.py |
Tests tree, blob, symlink, and gitlink probes. |
tests/unit/install/phases/test_resolve_selective_update_plan.py |
Tests selective filtering and descendants. |
tests/unit/install/test_dry_run_render.py |
Tests dry-run identity preservation. |
tests/unit/marketplace/test_versioned_directory_resolution.py |
Tests classification and traversal rejection. |
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+819
to
+821
| # ``-d`` also includes gitlinks (160000 commit), which cannot be | ||
| # materialized as plugin content without following another repository. | ||
| if output and output.split(maxsplit=2)[:2] == ["040000", "tree"]: |
| assert ctx.intended_dep_keys == {selected.get_unique_key()} | ||
|
|
||
|
|
||
| def test_only_filter_preserves_structured_versioned_path_and_descendants(): |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Description
Installing
my-plugin@marketplacefails when the catalog points at a versioned directory produced byapm pack, such asplugins/my-plugin-1.2.3. Shorthand parsing mistakes the dotted suffix for an unsupported file extension.Use the existing explicit Git/path reference when the marketplace already identifies the repository and path. Keep that interpreted identity through selective installation and dry-run planning using the existing package-selection module instead of reparsing an ambiguous display string. GitHub/GHE Contents API success requires a directory listing, not merely HTTP 200. The Git fallback requires an actual tree entry, so file, symbolic-link, and submodule responses cannot bypass directory validation.
Supported individual files, package-content validation, containment checks, bundle naming, and local marketplace behavior retain their existing contracts.
Issue and approved scope
Fixes #3078.
Human scope approval: #3078 (comment)
This completes the bounded versioned-directory installation repair; it does not change the bundle layout from #2432.
Type of change
Testing
The hermetic lifecycle test runs
apm pack, commits the generated bundle to a local Git repository, previews installation without changing the consumer, verifies the first install deploys the expected skill, and replays the lockfile. Semver, calendar versions, and the local-marketplace control are covered. Negative cases reject unknown files, version-named blobs, malformed package content, and traversal without writing the consumer manifest or lockfile; real Git tree probes also reject symbolic links.The GitHub catalog fetch is substituted at the transport boundary with the existing Git fetcher against the committed local fixture. Source classification, resolution, download, validation, deployment, and lock replay run normally with external network access denied. This is not a live GitHub API integration test.
Focused validation:
These focused runs overlap; their counts are not a whole-suite total.
The six CI test-quality/architecture-ratchet modules also pass locally: 91 passed. Full-source Ruff lint/format, pylint duplication checks, architecture/auth boundaries, YAML I/O/file-length/portable-path guards, and
git diff --checkpass.A broader earlier run had 4,791 passes and 25 failures: one introduced module-length violation was fixed by the shared selection helper and passes in the final checks; 24 Unix installer fixture failures came from writing the Chinese checkout's Python path as ASCII. The same encoding failure was reproduced using an unchanged HEAD fixture. The full suite is therefore not claimed green, and Windows was not tested locally.
Spec conformance (OpenAPM v0.1)
No normative requirement changes. This repairs consumption of existing explicit Git/path coordinates and preserves path validation, package-content checks, and lockfile identity; it introduces no new manifest syntax or bundle format.