Skip to content

[BUG] Marketplace install fails for *.ghe.com hosts — auth resolves against github.com instead of registered host #1285

@kkadete

Description

@kkadete

Describe the bug

Installing a plugin from a marketplace registered on a GHE Cloud host (*.ghe.com) fails with an authentication error. The verbose output shows APM resolves auth against github.com instead of the registered marketplace host (e.g. corp.ghe.com), even though the marketplace was added with --host corp.ghe.com and the marketplace fetch itself succeeds.

The resolved canonical string lacks the host prefix — it emits myorg/my-marketplace/plugins/my-plugin instead of corp.ghe.com/myorg/my-marketplace/plugins/my-plugin — so the install pipeline defaults to github.com for authentication.

To Reproduce

  1. Register a marketplace on a GHE Cloud host:
    apm marketplace add --host corp.ghe.com myorg/my-marketplace
  2. Confirm the marketplace is registered correctly:
    cat ~/.apm/marketplaces.json
    # Shows: "host": "corp.ghe.com"
  3. The marketplace marketplace.json has a plugin with a relative source:
    { "name": "my-plugin", "source": "./plugins/my-plugin", "version": "1.0.0" }
  4. Install a plugin from that marketplace:
    apm install my-plugin@my-marketplace --verbose
  5. Observe verbose output:
    Resolving my-plugin@my-marketplace via marketplace...
    Resolved to: myorg/my-marketplace/plugins/my-plugin        <-- missing corp.ghe.com/ prefix
    Auth resolved: host=github.com, org=myorg, ...             <-- wrong host
    [i] plugins/my-plugin/apm.yml@main (Authentication failed for myorg/my-marketplace ...)
    

Expected behavior

Authentication should resolve against the host registered in the marketplace (corp.ghe.com). The resolved canonical string should be:

corp.ghe.com/myorg/my-marketplace/plugins/my-plugin

The install should succeed, the same way a direct install with the host-qualified path works:

# This works correctly:
apm install corp.ghe.com/myorg/my-marketplace/plugins/my-plugin

Environment (please complete the following information):

  • OS: Windows 11 (Git Bash)
  • Python Version: 3.12
  • APM Version: 0.13.0
  • Marketplace host: *.ghe.com (GHE Cloud)

Additional context

  • The marketplace fetch phase works correctly — it authenticates against corp.ghe.com and retrieves marketplace.json without issues.
  • Only the plugin install/validation phase fails — the host from the marketplace registration is lost when resolving the plugin's relative source path.
  • gh auth status confirms valid auth for corp.ghe.com.
  • Setting GITHUB_HOST=corp.ghe.com is not a viable workaround for users with dependencies on both github.com and corp.ghe.com in the same manifest.
  • Workaround: use the fully-qualified path directly:
    apm install corp.ghe.com/myorg/my-marketplace/plugins/my-plugin

Suggested fix

In resolve_marketplace_plugin() (src/apm_cli/marketplace/resolver.py), after the _marketplace_host_needs_explicit_git_path block, dep_ref is still None for *.ghe.com hosts because is_github_hostname() returns True and the block is skipped. The canonical string from resolve_plugin_source() is a bare owner/repo/path without the host, so downstream DependencyReference.parse() defaults to github.com.

Add a host-prefix step scoped to in-marketplace sources on non-github.com hosts:

# After: canonical = resolve_plugin_source(...)
# After the _marketplace_host_needs_explicit_git_path block:

if (
    dep_ref is None
    and source.host
    and source.host.lower() != "github.com"
    and _is_in_marketplace_source(plugin, source)
):
    base = canonical.split("#", 1)[0]
    ref_suffix = ""
    if "#" in canonical:
        ref_suffix = f"#{canonical.split('#', 1)[1]}"
    canonical = f"{source.host}/{base}{ref_suffix}"

The _is_in_marketplace_source guard ensures the host prefix is only added for sources that resolve back to the marketplace's own repo (relative string sources always qualify). Dict sources pointing to external repos on a different host are left unchanged.

Metadata

Metadata

Assignees

No one assigned

    Labels

    type/bugSomething does not work as documented.

    Type

    No type

    Projects

    Status

    In Progress

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions