Skip to content

test(github): re-probe tracked upstreams after SSH reconnect - #12979

Closed
dcieslak19973 wants to merge 2 commits into
stablyai:mainfrom
dcieslak19973:dcieslak19973/ssh-provider-local-fallthrough
Closed

dcieslak19973 wants to merge 2 commits into
stablyai:mainfrom
dcieslak19973:dcieslak19973/ssh-provider-local-fallthrough

Conversation

@dcieslak19973

@dcieslak19973 dcieslak19973 commented Aug 7, 2026 •

Copy link
Copy Markdown
Contributor

What

Adds the missing regression coverage for tracked-upstream discovery across an SSH disconnect/reconnect. The test proves that a disconnected lookup does not invoke local Git and that the next lookup reaches the restored SSH provider instead of reusing a disconnected empty result.

The original production fix from this PR was independently merged in #14945 and is already on main. During rebase, client.ts had been split into focused modules, so the obsolete source hunk was resolved in favor of current main; the one unique reconnect regression test remains.

Refs #12977.

Verification

  • macOS, final head 4a7f33b348e:
    • focused SSH-boundary Vitest files — 29 passed
  • macOS, identical 22-line test diff before the final base-only rebase (f113eb5338c):
    • pnpm exec vitest run src/main/github — 675 passed
    • pnpm run typecheck:node — passed
    • pnpm run lint — passed
    • pnpm run build:electron-vite — passed (two existing CSS optimizer warnings)
  • Linux openclaw, final head 4a7f33b348e:
    • focused SSH-boundary Vitest files — 29 passed
    • real source-path runtime probe with an actual colliding Git repository path — disconnected helpers failed closed; after provider registration, rev-parse and for-each-ref both routed through the provider and returned the exact head

Compatibility

Test-only change. No production runtime, persisted data, mobile surface, RPC/wire contract, dependency, packaging, Git-provider, or UI behavior changes.

Visual proof

N/A — test-only main-process coverage with no rendered UI change.

@coderabbitai

coderabbitai Bot commented Aug 7, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a5656514-2155-4896-b7f2-2bea5b72a23e

📥 Commits

Reviewing files that changed from the base of the PR and between f405969781216a257157935a519a82c961f04689 and 3fb41b4.

📒 Files selected for processing (1)
  • src/main/github/client-tracked-upstream-snapshot.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/github/client-tracked-upstream-snapshot.test.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

Added a test for SSH tracked-upstream probing. The test confirms that a disconnected repository does not invoke local Git. After reconnection, the repository probes tracked upstreams through the SSH provider.

Merge Risk: ⚪ Minimal · up to 3fb41

This test-only change adds regression coverage without changing production behavior, and the supplied validation passes. No actionable merge-blocking risk remains beyond normal checks and review.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: regression coverage for re-probing tracked upstreams after an SSH reconnect.
Description check ✅ Passed The description explains the change, motivation, test-only scope, linked issue, verification results, compatibility impact, and visual proof. It omits several template headings and checklist items, bu…
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 1…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description explains the change, motivation, test-only scope, linked issue, verification results, compatibility impact, and visual proof. It omits several template headings and checklist items, but the required context is substantially present.

Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 1 files.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (2)
src/main/github/client.test.ts (2)

1955-1971: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Test the reconnect retry path.

This test covers only the first disconnected lookup. It does not prove that probeFailed: true keeps the empty upstream map out of the snapshot cache. After the provider becomes available, repeat the lookup and assert that the provider is queried again.


1973-1985: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Assert both local probe commands.

localProbes.length > 0 can pass when only one helper invokes local Git. Assert that both rev-parse and for-each-ref appear in the captured calls.

Suggested assertion
-    expect(localProbes.length).toBeGreaterThan(0)
+    const localProbeCommands = localProbes.map(([args]) => (args as string[])[0])
+    expect(localProbeCommands.some(command => command === 'rev-parse')).toBe(true)
+    expect(localProbeCommands.some(command => command === 'for-each-ref')).toBe(true)

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 7f8bdc5b-897b-4724-aebe-0dfe1a8ed833

📥 Commits

Reviewing files that changed from the base of the PR and between cb96040 and 412ab91.

📒 Files selected for processing (2)
  • src/main/github/client.test.ts
  • src/main/github/client.ts

@dcieslak19973

Copy link
Copy Markdown
Contributor Author

Upstream PR Checks is still awaiting workflow approval, so I ran the identical suite on my fork against this PR's exact head (412ab91dc):

https://github.com/dcieslak19973/orca/actions/runs/31215871344 — all 43 jobs green: typecheck, static analysis, packaging (linux + windows), Git compatibility, shell contracts, cross-version wire compatibility, and all 16 test shards.

Posting so the suite result is visible without needing the approval click first.

@dcieslak19973

Copy link
Copy Markdown
Contributor Author

Upstream PR Checks is awaiting workflow approval, so I ran the identical suite on my fork against this PR's exact head (412ab91dc):

https://github.com/dcieslak19973/orca/actions/runs/31291648841 — all 30 jobs green.

The fork's main was synced to upstream e172a5164 (post-v1.4.177) first, so this ran against current main, not a stale base. Posting so the suite result is available without spending an approval.

@dcieslak19973
dcieslak19973 force-pushed the dcieslak19973/ssh-provider-local-fallthrough branch from 4d95d4b to 3383cd9 Compare August 15, 2026 16:01
@coderabbitai

coderabbitai Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 893d0bb9-7a4c-4e87-9228-f26a42584a5d

📥 Commits

Reviewing files that changed from the base of the PR and between c0a7754 and 3383cd93c6d96c81ea0bb1c864b31908f4c9c2cb.

📒 Files selected for processing (2)
  • src/main/github/client-tracked-upstream-snapshot.test.ts
  • src/main/github/client.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/github/client.ts

@nwparker nwparker removed the P1 label Aug 19, 2026
@nwparker
nwparker force-pushed the dcieslak19973/ssh-provider-local-fallthrough branch from 3383cd9 to d81e43f Compare August 23, 2026 22:25
@nwparker nwparker changed the title fix(github): never read a disconnected SSH repo with local git test(github): re-probe tracked upstreams after SSH reconnect Aug 23, 2026
@nwparker
nwparker force-pushed the dcieslak19973/ssh-provider-local-fallthrough branch 2 times, most recently from f113eb5 to f405969 Compare August 23, 2026 23:02
@coderabbitai

coderabbitai Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (1)
src/main/github/client-tracked-upstream-snapshot.test.ts (1)

744-744: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use a platform-safe repository path.

'/repo-root' assumes POSIX path syntax. Define repoPath with the repository’s Node/Electron path utility and reuse it for both lookups and assertions.

As per coding guidelines, **/*.{ts,tsx,js,jsx}: Use path.join or Electron/Node path utilities for file paths; never assume / or \.

Also applies to: 754-754

Source: Coding guidelines


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f14bac2b-42cb-4647-bb96-9cf3102d4c04

📥 Commits

Reviewing files that changed from the base of the PR and between 6989c92 and f405969781216a257157935a519a82c961f04689.

📒 Files selected for processing (1)
  • src/main/github/client-tracked-upstream-snapshot.test.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 4 remain after this review.

@nwparker
nwparker force-pushed the dcieslak19973/ssh-provider-local-fallthrough branch from f405969 to 4a7f33b Compare August 23, 2026 23:12
@nwparker

Copy link
Copy Markdown
Contributor

Readiness verdict: READY TO MERGE

Standalone readiness review of head 4a7f33b348e. Scope is a test-only 22-line addition to src/main/github/client-tracked-upstream-snapshot.test.ts; no production file changes.

Why this is a real guard, not a passing-by-default test

The production behavior under test lives in src/main/github/client/lookup/tracked-upstream-branch.ts:

const provider = connectionId ? getSshGitProvider(connectionId) : null
if (connectionId && !provider) {
  throw new Error(SSH_GIT_PROVIDER_UNAVAILABLE_MESSAGE)
}

I mutation-tested that guard against the new test rather than trusting a green run:

# Mutation Result
A Delete the guard entirely (restore local-Git fallthrough while disconnected) KILLED — fails on expect(gitExecFileAsyncMock).not.toHaveBeenCalled()
C Disconnected path returns a cacheable snapshot that contains the branch KILLED — fails on expect(sshGitProvider.exec).toHaveBeenCalled()
B Disconnected path returns a cacheable empty snapshot survived — benign, see below

Both assertions are load-bearing: A covers the local-fallthrough guard, C covers stale reuse across reconnect. Mutation B survives only because an empty snapshot misses the upstreamsByBranchName.has(branchName) check in getTrackedUpstreamBranch, so that branch re-probes correctly anyway — no behavioral regression escapes. One wording note for the record: the regression actually guarded is reuse of a disconnected snapshot that covers the branch, which is slightly narrower than the PR body's "reusing a disconnected empty result."

Disconnected-SSH / network-failure evidence (Linux openclaw)

Real on-disk Git repository, real for-each-ref, no mocks — run at head 4a7f33b348e on Linux 7.0.0-28-generic x86_64, git 2.43.0, Node v26.1.0:

  1. Baseline — the repo reads fine through local Git (probeFailed=false, upstream origin/feature), proving a fallthrough would have silently succeeded and returned plausible data.
  2. Disconnected (connectionId set, no provider registered) — threw / failed closed. Local Git was never consulted, so a disconnected SSH repo cannot be answered from a colliding local path.
  3. Reconnected (provider registered) — routed through the provider with the exact expected argv ["for-each-ref","--format=%(refname)%00%(upstream)","refs/heads"], and the returned head matched the repo head exactly (4702415bf87).

This is the case that matters for the SSH execution boundary: loss of contact yields a hard failure, never a local-host answer misattributed to the remote.

Gates run at final head 4a7f33b348e

Gate macOS Linux openclaw
vitest run src/main/github 675 passed (61 files) 675 passed (61 files)
Focused client-tracked-upstream-snapshot.test.ts 19 passed 19 passed
Real-repo disconnected/reconnect runtime probe — passed
typecheck:node passed —
lint passed —

This closes the gap in the PR description, where the full src/main/github suite, typecheck, and lint had been run against the identical diff at an earlier commit (f113eb5338c) rather than the final head — all now re-confirmed at 4a7f33b348e.

Compatibility

Test-only. No production runtime, persisted data, RPC/wire contract, stream opcode, mobile surface, dependency, packaging, Git-provider, or UI change. Git usage is limited to for-each-ref --format (well below the Git 2.25 baseline; exercised here on 2.43.0). Nothing a paired client and remote host exchange is altered, so mixed-version pairs are unaffected.

Visual proof

N/A — justified. Main-process test coverage only; no renderer code, component, token, or rendered surface is touched, so there is no UI state to screenshot. Confirmed by the diff touching exactly one src/main/** test file.

CI and mergeability

MERGEABLE / mergeStateStatus=CLEAN, not a draft. 46 checks SUCCESS, 1 SKIPPED (e2e, correctly skipped — "detect changed e2e specs" found no e2e spec changes). Both workflows green.

Residual issues

None found. No code changes were required; local HEAD is identical to the PR head, so nothing was pushed.

@greptile-apps

greptile-apps Bot commented Aug 31, 2026

Copy link
Copy Markdown

Greptile Summary

Adds regression coverage ensuring tracked-upstream discovery does not invoke local Git while an SSH provider is disconnected and re-probes through the restored provider after reconnection.

  • Simulates an unavailable SSH Git provider for the initial lookup.
  • Verifies the disconnected lookup does not fall back to local Git.
  • Restores the provider and verifies the next lookup executes the remote for-each-ref probe.

Confidence Score: 5/5

The test-only change appears safe to merge.

The added test directly exercises the disconnect/reconnect sequence and verifies both the absence of local Git fallback and the restored SSH-provider probe, with no production behavior changed.

Important Files Changed

Filename Overview
src/main/github/client-tracked-upstream-snapshot.test.ts Adds focused regression coverage for SSH reconnect behavior without changing production code.

Reviews (1): Last reviewed commit: "test(github): assert SSH upstream reprob..." | Re-trigger Greptile

@dcieslak19973

Copy link
Copy Markdown
Contributor Author

Closing: this is test-only and the behavior it covers (re-probing tracked upstreams via the SSH git provider after reconnect in getPRForBranch) already exists on main. The branch also predates the client.ts module split, so it would need a full rebase for a single added it(...). Not worth carrying — closing to reduce open-PR noise. Happy to re-land the extra coverage against the post-split client-tracked-upstream-snapshot.test.ts if we decide it's wanted.

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.

4 participants