Skip to content

fix(auth): expand port hint with git credential fill command and docs URL#1608

Merged
danielmeppiel merged 3 commits into
mainfrom
danielmeppiel/799-port-hint-verify
Jun 2, 2026
Merged

fix(auth): expand port hint with git credential fill command and docs URL#1608
danielmeppiel merged 3 commits into
mainfrom
danielmeppiel/799-port-hint-verify

Conversation

@danielmeppiel

Copy link
Copy Markdown
Collaborator

TL;DR

The [i] hint emitted by AuthResolver.build_error_context when a custom port is detected now includes a concrete verification command and a docs link, raising actionability from ~70% to ~100%.

Problem (WHY)

Follow-up from PR #788 review panel (devx-ux-expert finding #4). The previous hint:

[i] Host 'bitbucket.example.com:7999' -- verify your credential helper stores per-port entries (some helpers key by host only).

Named the right problem but not the next action. Users had to translate "stores per-port entries" into a concrete debugging step for their specific helper (GCM, osxkeychain, libsecret, gh-auth) themselves.

Approach (WHAT)

Rewrite the hint to three lines:

[i] Host 'bitbucket.example.com:7999' -- this helper may key by host only.
    Verify with: printf 'protocol=https\nhost=bitbucket.example.com:7999\n\n' | git credential fill
    See: https://microsoft.github.io/apm/getting-started/authentication/#custom-port-hosts-and-per-port-credentials

Implementation (HOW)

flowchart LR
    A[build_error_context] --> B{host_info.port != None?}
    B -->|Yes| C[Emit 3-line hint:\n1. host-only key warning\n2. git credential fill cmd\n3. docs URL]
    B -->|No| D[Skip hint]
Loading

Files changed:

  • src/apm_cli/core/auth.py -- rewrites the port hint string (lines 710-714)
  • tests/unit/test_auth.py -- adds two new assertions: git credential fill substring + docs URL anchor; existing per-port assertion continues to pass via the URL
  • docs/src/content/docs/getting-started/authentication.md -- adds the verification command to the "Custom-port hosts" section
  • packages/apm-guide/.apm/skills/apm-usage/authentication.md -- mirrors the same update

Trade-offs:

  • No helper-specific advice inline: the helper is opaque to APM at emission time; the docs table is the right place for helper-specific detail.
  • Three-line hint is slightly more verbose but all three lines are actionable.

Validation evidence

  • uv run --extra dev pytest tests/unit/test_auth.py -q: 105 passed
  • uv run --extra dev ruff check src/ tests/: All checks passed
  • uv run --extra dev ruff format --check src/ tests/: 1165 files already formatted
  • uv run --extra dev python -m pylint --disable=all --enable=R0801 --min-similarity-lines=10 --fail-on=R0801 src/apm_cli/: 10.00/10
  • bash scripts/lint-auth-signals.sh: auth-signal lint clean

How to test

# Trigger the hint by attempting to install from a host with a custom port
# with no credential configured:
apm install bitbucket.corp.com:7999/org/pkg --verbose
# Look for the three-line [i] hint in the auth error output.

# Or run the unit tests directly:
uv run --extra dev pytest tests/unit/test_auth.py::TestBuildErrorContextWithPort -v

README.md drift note: README.md is not modified per project policy. No content in README.md references the port hint wording, so no drift exists.

Closes #799

… URL

The [i] hint emitted by AuthResolver.build_error_context when dep_ref.port
is set named the right problem but not the remedy. Users had to translate
'stores per-port entries' into a concrete debugging step themselves.

New three-line hint:
  [i] Host 'host:port' -- this helper may key by host only.
      Verify with: printf 'protocol=https\nhost=host:port\n\n' | git credential fill
      See: https://microsoft.github.io/apm/getting-started/authentication/#custom-port-hosts-and-per-port-credentials

Rationale:
- git credential fill is the helper-agnostic entry point every credential
  helper implements; it reproduces exactly what APM sends internally.
- The docs URL points to the per-helper compatibility table already in tree.
- Matches the wire-format precedent set by the cross-protocol warning
  (also emits a 'See: <docs URL>' line).

Docs: authentication.md section updated with the same verification
command; apm-guide skill mirror updated in parallel.

Closes #799

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 2, 2026 16:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves the actionability of the custom-port credential-helper hint emitted by AuthResolver.build_error_context by adding (1) a concrete git credential fill verification command and (2) a direct link to the relevant authentication docs section, and mirrors that guidance in the documentation corpus.

Changes:

  • Updated AuthResolver.build_error_context to emit a 3-line [i] hint when host_info.port is set (warning + verification command + docs URL).
  • Added unit tests to assert presence of the git credential fill command and the docs anchor in the emitted hint.
  • Updated both the public docs and the in-repo APM usage skill docs to include the same verification command.
Show a summary per file
File Description
src/apm_cli/core/auth.py Expands the port-specific hint to include a git credential fill reproduction command and a docs link.
tests/unit/test_auth.py Adds assertions covering the new command and docs link in the hint output.
docs/src/content/docs/getting-started/authentication.md Documents the helper-agnostic verification command in the custom-port credentials section.
packages/apm-guide/.apm/skills/apm-usage/authentication.md Mirrors the same verification command in the APM usage skill docs.

Copilot's findings

  • Files reviewed: 4/4 changed files
  • Comments generated: 1

Comment thread tests/unit/test_auth.py
Comment on lines +1239 to +1246
def test_port_hint_includes_docs_url(self):
with patch.dict(os.environ, {}, clear=True):
with patch.object(GitHubTokenManager, "resolve_credential_from_git", return_value=None):
resolver = AuthResolver()
msg = resolver.build_error_context("bitbucket.corp.com", "clone", port=7999)
assert "custom-port-hosts-and-per-port-credentials" in msg, (
f"Expected docs URL anchor in hint, got:\n{msg}"
)
…nstant

- Replace substring URL assertion in test_port_hint_includes_docs_url with
  urllib.parse.urlparse checks per tests.instructions.md (CodeQL
  py/incomplete-url-substring-sanitization)
- Promote _docs_url local variable to module-level _PORT_CREDENTIAL_DOCS_URL
  constant, matching _PROTOCOL_FALLBACK_DOCS_URL pattern in clone_engine.py
- Normalize 'Docs:' prefix in port hint (was 'See:') for consistency with
  the five other build_error_context URL lines in auth.py
- Add CHANGELOG entry for the user-visible credential error improvement

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@danielmeppiel

Copy link
Copy Markdown
Collaborator Author

apm-review-panel recommendation

Headline: Ship after fixing the substring URL assertion that will fail CodeQL CI; all other findings are low-friction folds.

CEO arbitration: The panel is in strong agreement: this is a well-scoped, user-facing improvement to credential error ergonomics. The single blocking issue -- a substring URL assertion in test_port_hint_includes_docs_url -- was independently flagged by both python-architect and test-coverage-expert (CodeQL py/incomplete-url-substring-sanitization). The fix is mechanical. All other recommended folds are bounded, in-scope refinements: promoting _docs_url to a module constant matches the _PROTOCOL_FALLBACK_DOCS_URL convention; normalizing Docs: prefix keeps build_error_context output consistent; and harmonizing the skill mirror prevents drift introduced by this PR. The oss-growth-hacker mprintf finding was verified NOT-LEGIT (the file correctly reads printf).

Deferred (not blocking): [i] prefix normalization across all of build_error_context -- touches established format pattern beyond this PR's scope; deserves a standalone PR.


Findings applied in commit 5ea8027a

# Persona Finding Disposition
1 test-coverage-expert + python-architect test_port_hint_includes_docs_url uses substring URL assertion (CodeQL py/incomplete-url-substring-sanitization); violates tests.instructions.md FOLD (BLOCKING) -- fixed: urlparse with .hostname + .fragment assertions
2 python-architect _docs_url local variable should be module-level constant FOLD -- promoted to _PORT_CREDENTIAL_DOCS_URL
3 devx-ux-expert " See:" prefix inconsistent with all other build_error_context URL lines (lines 594, 603, 622, 636, 651 all use " Docs:") FOLD -- normalized to " Docs:"
4 oss-growth-hacker CHANGELOG entry for user-visible auth improvement FOLD -- added to [Unreleased] > Fixed
5 doc-writer Skill mirror prose diverges from canonical getting-started wording DEFER -- prose is acceptably close; a precision pass would be a separate docs-only PR
6 cli-logging-expert [i] prefix unique among build_error_context entries (others are bare text) DEFER -- touches established format pattern beyond this PR's scope
7 supply-chain-security-expert display interpolated in suggested shell command without quoting DEFER -- display is already inside single-quotes in the resulting shell string; low real-world risk
8 auth-expert Hint omits path= line for useHttpPath setups DEFER -- additional hint enhancement; separate scope

Ship recommendation: ship_with_followups -- folds applied, lint green (ruff + pylint 10.00/10 + auth-signals clean), all 5 port-hint tests pass. Ready for maintainer merge once CI clears.

@danielmeppiel danielmeppiel merged commit bee4c54 into main Jun 2, 2026
1 check passed
@danielmeppiel danielmeppiel deleted the danielmeppiel/799-port-hint-verify branch June 2, 2026 18:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] build_error_context [i] port hint should name a concrete verification command + doc link

2 participants