You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: share AuthResolver across install to prevent duplicate auth popups (#424)
* fix: share AuthResolver across install to prevent duplicate auth popups
Create a single AuthResolver at the top of the install command and
thread it through _validate_and_add_packages_to_apm_yml,
_validate_package_exists, and _install_apm_dependencies so that all
validation and download steps within one CLI invocation share the same
credential cache.
Also fixes a lock inversion in AuthResolver.resolve() that allowed
two concurrent callers for the same (host, org) key to each trigger
their own credential-helper lookup before either result was cached.
* Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* fix: move AuthResolver import to improve clarity and prevent potential issues
* fix: remove accidentally tracked dist.old build artifact
The dist.old/apm-windows-x86_64.sha256 checksum file was an accidental
build artifact committed to the repo. Nothing in the codebase references
dist.old/, and dist/ is already in .gitignore.
* fix: reuse shared auth_resolver for verbose auth logging in install
The verbose auth logging block inside _install_apm_dependencies was
creating a fresh AuthResolver() instance instead of reusing the shared
resolver passed to the function. This meant the resolved credentials
were not cached, potentially triggering duplicate credential-helper
popups when the resolver was used for logging after downloads.
Replace the per-verbose-block AuthResolver() construction with direct
use of the auth_resolver parameter already available in scope.
* fix: resolve per-dep auth before building GHES/ADO validation URL
In _validate_package_exists, the URL for git ls-remote was built via
_build_repo_url() without a token for GHES and ADO hosts. Since the
downloader constructor no longer resolves credentials eagerly (to
prevent duplicate auth popups), self.github_token / self.ado_token are
now env-only. Credential-helper-only users on GHES/ADO would therefore
receive a tokenless ls-remote URL and see an OS credential prompt --
reintroducing exactly the problem this PR targets.
Fix: call auth_resolver.resolve_for_dep(dep_ref) for non-generic
(GHES/ADO) hosts before building the URL, and pass the resolved token
to _build_repo_url(token=...). Generic hosts are excluded because they
rely on git credential helpers through the relaxed validate_env, not
on APM-managed auth.
* fix: use resolved dep_token in clone error handler for credential-helper users
The error handler in _clone_with_fallback used self.has_github_token to
determine whether to show an 'authentication not configured' message.
Since the constructor no longer calls auth_resolver.resolve() eagerly,
self.has_github_token reflects env-var tokens only. Credential-helper-
only users (gh auth login, macOS Keychain, etc.) have has_github_token=False
even when credentials are available via helper, causing a misleading
'set up authentication' error when the actual cause is a permissions
or repo-not-found issue.
Switch to has_token, which is derived from dep_ctx.token (the result of
per-dependency resolve_for_dep(), including credential-helper tokens).
When has_token is True but clone still fails, the error correctly falls
through to the generic 'check permissions' message. When has_token is
False (truly no auth configured), the auth setup guidance is shown.
* docs: clarify why AuthResolver is imported outside APM_DEPS_AVAILABLE guard
AuthResolver has no optional dependencies (stdlib + internal utils only).
Add comments explaining it must be imported unconditionally, not inside
the APM_DEPS_AVAILABLE try/except block: if an optional dep like GitPython
is missing, a gated import would produce a NameError inside install()
before the graceful APM_DEPS_AVAILABLE guard can produce a useful error.
* docs: document lock hold trade-off in AuthResolver.resolve()
Add a comment explaining why the lock is held for the full duration of
credential resolution, not just for the cache check/write. Key points:
- Prevents duplicate OS credential-helper popups under parallel downloads
- First caller fills cache; subsequent same-key calls are O(1) hits
- Bounded by APM_GIT_CREDENTIAL_TIMEOUT (default 60s)
- No deadlock risk: single lock, never nested
* refactor: remove unused _default_github_ctx field from GitHubPackageDownloader
The field was assigned in _setup_git_environment() but never read anywhere
in the codebase. Remove it to eliminate dead code and reduce confusion
about its purpose.
---------
Co-authored-by: Daniel Meppiel <51440732+danielmeppiel@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
0 commit comments