test(auth): preserve streaming Git shim commands - #2673
test(auth): preserve streaming Git shim commands#2673Daniel Meppiel (danielmeppiel) wants to merge 1 commit into
Conversation
Keep bidirectional git batch commands attached to their inherited pipes while capturing only finite remote commands for localized stderr synthesis. This addresses the test-coverage panel follow-up and prevents the installed-CLI auth lifecycle from deadlocking. Co-authored-by: Naofel El Alouani <95690519+Naofel-eal@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
0d00492 to
b094243
Compare
There was a problem hiding this comment.
Pull request overview
This PR makes Git authentication-failure detection locale-independent by pinning Git subprocess locale variables to C, ensuring AuthResolver.is_public_github_auth_failure continues to classify failures correctly and the credential retry path triggers reliably across non-English environments. It also updates the installed-test Git shim to avoid buffering long-lived bidirectional Git commands and adds regression coverage across unit and installed-CLI lifecycle tiers.
Changes:
- Pin
LC_ALL=CandLANGUAGE=CinAuthResolver._build_git_envvia an immutable mapping to prevent caller mutation. - Extend unit + integration coverage for the translated-stderr failure/retry path and for shim streaming behavior.
- Update the Git credential shim to capture output only for finite remote operations and log locale observations; add a changelog entry for the user-visible fix.
Show a summary per file
| File | Description |
|---|---|
src/apm_cli/core/auth.py |
Adds an immutable locale policy and applies it in the canonical auth-path Git environment builder. |
tests/unit/core/test_public_github_anonymous_first.py |
Adds unit tests asserting locale pinning/immutability and that translated auth failures still trigger a token retry. |
tests/integration/test_public_github_anonymous_lifecycle_e2e.py |
Seeds a non-English locale and verifies the installed CLI completes the private repo lifecycle with pinned locale variables. |
tests/utils/git_credential_shim.py |
Adjusts shim to stream non-remote commands and only capture output for finite remote operations; logs locale variables for assertions. |
tests/unit/test_git_credential_shim.py |
Adds a cross-platform regression test ensuring the shim doesn’t buffer bidirectional Git commands (cat-file --batch-check). |
CHANGELOG.md |
Records the fix under Unreleased Fixed with contributor attribution and issue closure reference. |
Review details
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Suppressed comments (1)
tests/utils/git_credential_shim.py:126
- _uses_non_c_git_message_locale() treats an empty locale as non-C ("" does not startwith("C")), which can cause the shim to inject the translated auth stderr even when the effective locale is actually the default "C". It also ignores LC_MESSAGES/LANG, which are part of gettext locale resolution, so the shim's locale check can diverge from real git behavior.
def _uses_non_c_git_message_locale():
locale = os.environ.get("LANGUAGE") or os.environ.get("LC_ALL") or ""
return not locale.startswith("C")
- Files reviewed: 2/2 changed files
- Comments generated: 1
- Review effort level: Lite
| real_git = shutil.which("git") | ||
| assert real_git is not None |
APM Review Panel:
|
| Persona | B | R | N | Takeaway |
|---|---|---|---|---|
| Python Architect | 0 | 0 | 1 | Sound, narrowly scoped shim fix that preserves bidirectional Git I/O without introducing a parallel policy owner. |
| CLI Logging Expert | 0 | 0 | 0 | No CLI output concerns; the test-only shim preserves streaming without changing user-facing logging. |
| DevX UX Expert | 0 | 0 | 0 | No DevX UX concerns; the shim fix preserves responsive Git behavior without changing the CLI surface. |
| Supply Chain Security Expert | 0 | 0 | 0 | Credential handling remains test-scoped without widening token exposure or changing production auth. |
| OSS Growth Hacker | 0 | 0 | 0 | No conversion surface is affected; the regression guard strengthens contributor confidence. |
| Auth Expert | 0 | 0 | 0 | The shim preserves private GitHub credential retry while streaming non-remote Git commands. |
| Test Coverage Expert | 0 | 0 | 0 | Focused real-Git regression and exact-head lifecycle CI cover streaming and remote-capture paths. |
B = blocking-severity findings, R = recommended, N = nits.
Counts are signal strength, not gates. The maintainer ships.
Architecture
flowchart TD
A[Git shim invocation] --> B{Remote URL rewritten}
B -- no --> C[Inherit stdin stdout and stderr]
C --> D[Bidirectional Git response remains live]
B -- yes --> E[Capture finite command output]
E --> F{Localized unauthenticated failure}
F -- yes --> G[Emit localized auth stderr fixture]
F -- no --> H[Emit real Git stderr]
Folded in this run
- (panel) Preserve streaming for non-remote Git commands and add a focused
cross-platform regression guard -- resolved inb094243fd.
Copilot signals reviewed
tests/utils/git_credential_shim.py:126-- NOT-LEGIT: the fixture
deliberately exercises the two locale variables pinned by AuthResolver, and
the relevant lifecycle seeds both variables explicitly; broader locale
emulation is outside this streaming-only follow-up.
Regression-trap evidence (mutation-break gate)
tests/unit/test_git_credential_shim.py::test_git_shim_streams_bidirectional_commands
-- deleted theif not remotesstreaming branch; test FAILED with
_queue.Emptyafter five seconds; guard restored.
Lint contract
uv run --no-project --no-sync ruff check src/ tests/ and
uv run --no-project --no-sync ruff format --check src/ tests/ both passed.
The exact-head GitHub Lint job also passed.
CI
All checks passed for
https://github.com/microsoft/apm/actions/runs/32661154426 after 0 CI fix
iterations, including Windows Compatibility Gate, Lifecycle Smoke, both test
shards, architecture ratchets, CodeQL, and Merge Gate.
Mergeability status
| PR | head SHA | CEO stance | iters | folds | defers | Copilot rounds | CI | mergeable | mergeStateStatus | notes |
|---|---|---|---|---|---|---|---|---|---|---|
| #2673 | b094243 |
ship_now | 2 | 1 | 0 | 2 | green | MERGEABLE | BLOCKED | awaiting required review |
Recommendation
Ship at the reviewed head; the regression coverage, mutation-break result, and
full green CI provide sufficient evidence, with no substantive follow-up
identified.
Full per-persona findings
Python Architect
- [nit] Keep the streaming and capture dispatch policy inline.
The branch intests/utils/git_credential_shim.pyis the simplest correct
proxy design at this scope; another abstraction would add indirection without
a second policy owner.
CLI Logging Expert
No findings.
DevX UX Expert
No findings.
Supply Chain Security Expert
No findings.
OSS Growth Hacker
No findings.
Auth Expert
No findings.
Doc Writer -- inactive
The diff only changes test infrastructure and does not change documentation or
user-facing source behavior.
Test Coverage Expert
No findings.
Performance Expert -- inactive
The diff only changes test infrastructure and does not touch production
performance paths or make performance claims.
This panel is advisory. It does not block merge. Re-apply the
panel-review label after addressing feedback to re-run.
test(auth): preserve streaming Git shim commands
TL;DR
This follows up merged PR #2534 after the review panel found that its updated
installed-CLI Git shim buffered a long-lived
git cat-file --batch-checkprocess. The patch captures output only for finite remote operations and adds
a cross-platform regression test proving bidirectional Git responses remain
available before stdin closes.
Note
The production locale-normalization fix is already on
main. This PR is thebounded test-infrastructure follow-up discovered during post-merge review.
Problem (WHY)
capture_output=Truefor every Gitcommand so it could replace remote authentication stderr.
git cat-file --batch-checkprocesses.Capturing their stdout inside the shim withholds responses until process
exit, while GitPython waits for a response before sending the next request.
private-repository credential-retry assertions.
setup makes the streaming contract slower and less direct to diagnose.
The panel treated the failed E2E as load-bearing evidence rather than an
opinion: "Grounding outputs in deterministic tool execution transforms probabilistic generation into verifiable action."
Approach (WHAT)
subprocess.runwith inherited stdin, stdout, and stderr.fixture may replace localized unauthenticated stderr.
HEADtocat-file --batch-checkand requires the response before closing stdin.Implementation (HOW)
tests/utils/git_credential_shim.pytests/unit/test_git_credential_shim.pycat-file --batch-check, writes one request, and enforces a five-second response deadline before cleanup.Diagrams
Legend: The dashed streaming path is the new branch; finite remote operations
keep the existing captured-output path needed by the locale fixture.
flowchart LR G1[Git shim invocation] --> D1{Remote URL rewritten} D1 -->|yes| R1[Capture finite command output] R1 --> R2[Substitute localized auth stderr when needed] D1 -->|no| S1[Inherit stdin stdout and stderr] S1 --> S2[Bidirectional Git response remains live] classDef new stroke-dasharray: 5 5; class S1,S2 new;Trade-offs
remotes; reusing that fact avoids a fragile allowlist of currentbidirectional commands.
subprocess.runfor both branches. Replacing the local path withexecwould be more transparent but would skip the shim's normal exit-codehandling and complicate Windows behavior.
the buffering failure; the real
cat-fileprotocol is fast and hermetic.complements rather than replaces the full private-repository lifecycle.
Benefits
Validation
Exact-head targeted tests:
Mutation-break proof: removing the
if not remotesstreaming branch makestests/unit/test_git_credential_shim.py::test_git_shim_streams_bidirectional_commandsfail with
_queue.Emptyafter five seconds; restoring it returns the test togreen.
Local lint and guard evidence
uv run --no-project --no-sync ruff check src/ tests/:uv run --no-project --no-sync ruff format --check src/ tests/:python -m pylint --disable=all --enable=R0801 --min-similarity-lines=10 --fail-on=R0801 src/apm_cli/:bash scripts/lint-architecture-boundaries.shandbash scripts/lint-auth-signals.sh:The driver watches the GitHub check set for this exact head before reporting
completion.
Scenario Evidence
tests/unit/test_git_credential_shim.py::test_git_shim_streams_bidirectional_commands(regression-trap for #2534)apm installof a private github.com dependency under a non-English locale still reaches the authenticated retry and completestests/integration/test_public_github_anonymous_lifecycle_e2e.py::test_private_github_fallback_normalizes_locale_and_completes_lifecycleHow to test
python -m pytest -q tests/unit/test_git_credential_shim.py; expectone passing cross-platform streaming test.
if not remotesbranch and rerun that test; expect afive-second
_queue.Emptyfailure, then restore the branch.binary; expect install success, one credential fill, and both observed
locale variables equal to
C.auth-signal guards to complete successfully.
Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com