Skip to content

fix(repo): backfill fork upstream for SSH repos on connect - #12970

Open
Jinwoo-H wants to merge 4 commits into
mainfrom
fix-ssh-fork-upstream-backfill
Open

Jinwoo-H wants to merge 4 commits into
mainfrom
fix-ssh-fork-upstream-backfill

Conversation

@Jinwoo-H

@Jinwoo-H Jinwoo-H commented Aug 7, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Legacy fork repos on SSH hosts could remain upstream === undefined forever. Startup backfill skipped remote repos because their hosts were not connected yet, and no later hook retried them. Since repo.upstream drives GitHub Project matching, the fork badge, and auto-detected avatar migration, affected repos showed an empty Projects board and no fork indicator until the user happened to open that repo's Settings page.

This PR runs the existing fork-upstream migration when an SSH connection becomes ready. It stays off the connection critical path and persists only a positively identified upstream for SSH repos.

Fixes #12967.

Behavior

  • connected schedules a fire-and-forget pass for unresolved repos belonging to that SSH connection.
  • Provider generations are checked before and after each probe, so disconnect/reconnect races cannot persist stale results.
  • Reconnects that arrive while an older attempt is settling drain the newest provider generation.
  • Startup and SSH passes share two FIFO permits: migration work is bounded, but one stalled host does not block every other host.
  • Repos remain sequential within each pass, avoiding subprocess fan-out on one host.
  • SSH null is not persisted because the existing API cannot distinguish a confirmed non-fork from a transient Git/gh failure. Positive upstreams are persisted; ambiguous repos retry on the next app launch or explicit Settings lookup.
  • Folder workspaces, already-resolved repos, and runtime-owned ephemeral SSH targets remain excluded.
  • Auto-detected GitHub avatars migrate to the upstream owner; user-selected icons are untouched.
  • No RPC, stream, or remote-wire shape changes.

Reproduction

The regression invariant is: after a ready SSH provider publishes connected, a legacy repo with upstream === undefined must be probed and persisted without opening Settings.

The focused runtime test passes with this PR. Temporarily removing only the connected -> backfillForkUpstreamsForConnection edge makes the same test fail with zero upstream probes; restoring the edge makes it pass again.

The Docker E2E recreates the real user sequence with an sshd container and deployed relay: add a remote fork, strip its persisted upstream to model legacy state, restart Electron, verify the badge is absent, connect, then verify the upstream is persisted and Fork of stablyai/orca appears. It is deterministic and offline because the configured Git remotes determine the answer before any GitHub API call.

Testing

  • Six affected Vitest files: 1,184 passed, 1 existing skip
  • Focused post-rebase runtime and Windows runner tests: 14 passed
  • pnpm typecheck
  • pnpm lint (only nine pre-existing WorktreeJumpPalette.tsx hook warnings from main)
  • pnpm run check:code-quality:changed — 0 findings
  • pnpm test:e2e:ssh-docker-fork-upstream-backfill — 1 passed against Docker SSH + Electron
  • git diff --check

Review follow-ups

CodeRabbit's two valid findings were fixed:

  • The avatar test now asserts the exact upstream avatar URL.
  • The Windows E2E launcher no longer uses shell: true; it invokes pnpm's JS CLI through Node and tests whitespace-bearing forwarded arguments.

Three internal review/fix rounds found no remaining in-scope correctness, performance, compatibility, or regression issues.

Known limitations

  • getRepoUpstream still lacks a strict found / confirmed-not-fork / unavailable result. SSH therefore leaves ambiguous null unresolved instead of persisting a potentially false negative.
  • Two stalled hosts can occupy both migration permits; that is the bounded-load tradeoff.
  • Headless orca serve does not run the notifier-owned startup migration. That trigger-plumbing gap should be a separate PR.
  • The live E2E covers macOS client to Linux SSH target, not physical Windows/WSL.
  • A live GitHub Projects E2E would require real GitHub auth/project state; this suite validates the persisted field and fork badge that consume the same upstream value.

@coderabbitai

coderabbitai Bot commented Aug 7, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

OrcaRuntimeService now performs fork-upstream backfills through a serialized queue. Local repositories are processed at startup. SSH repositories are processed asynchronously after connection. The backfill tracks provider generations, limits concurrency, skips unsupported or resolved repositories, retries incomplete work, and reports completion status. Vitest and Docker-backed E2E tests cover the behavior.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes satisfy issue #12967 by backfilling SSH repository upstreams after connection without blocking or processing excluded repositories.
Out of Scope Changes check ✅ Passed The implementation, tests, E2E runner, and package script directly support the SSH fork-upstream backfill objective.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.
Title check ✅ Passed The title clearly and concisely describes the main change: backfilling fork upstream data for SSH repositories when they connect.
Description check ✅ Passed The description clearly covers the user-visible change, behavior, testing, limitations, and review follow-ups; it is detailed and relevant to the pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/main/runtime/orca-runtime-fork-upstream-ssh-backfill.test.ts (1)

1-6: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Shorten the test comments.

Replace each multi-line comment with one concise line, or remove it when the test or helper name states the intent.

  • src/main/runtime/orca-runtime-fork-upstream-ssh-backfill.test.ts#L1-L6: Reduce the file header to one concise comment.
  • src/main/runtime/orca-runtime-fork-upstream-ssh-backfill.test.ts#L61-L62: Reduce the queue-drain explanation to one concise comment.

As per coding guidelines, comments must be concise, limited to non-obvious information, and preferably one line.

Source: Coding guidelines


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 42953ec4-8ac9-48b9-ae8b-79c9043d89e0

📥 Commits

Reviewing files that changed from the base of the PR and between e68831f and 363a685.

📒 Files selected for processing (2)
  • src/main/runtime/orca-runtime-fork-upstream-ssh-backfill.test.ts
  • src/main/runtime/orca-runtime.ts

Comment thread src/main/runtime/orca-runtime-fork-upstream-ssh-backfill.test.ts Outdated

@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

🧹 Nitpick comments (1)
tests/e2e/ssh-docker-fork-upstream-backfill.spec.ts (1)

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

Shorten the file header comment.

The header repeats issue history and the test flow. Keep only the non-obvious fixture constraint, or move issue context to test metadata.

As per coding guidelines, “Comments must be concise, limited to non-obvious information, and preferably one line.”

Source: Coding guidelines


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 10da00d2-6152-4f10-b90d-566ad33a4426

📥 Commits

Reviewing files that changed from the base of the PR and between 363a685 and 0cf46c4.

📒 Files selected for processing (3)
  • config/scripts/run-ssh-docker-fork-upstream-backfill-e2e.mjs
  • package.json
  • tests/e2e/ssh-docker-fork-upstream-backfill.spec.ts

Comment thread config/scripts/run-ssh-docker-fork-upstream-backfill-e2e.mjs Outdated
A fork on an SSH host kept `upstream === undefined` until someone opened
its settings page, so its GitHub Project rows stayed hidden and its fork
badge never rendered. Run the one-shot backfill for a connection's repos
when that connection reports `connected` — the first moment the probe can
succeed — instead of skipping SSH repos outright.

All passes now share one chain, so a burst of connects queues behind the
startup pass rather than fanning out `gh repo view` past its semaphore.

Fixes #12967
Drives the actual #12967 sequence end to end: a legacy repo whose
persisted `upstream` was stripped, an app relaunch, then an SSH connect
that must backfill it and render the fork badge with no settings visit.

Deterministic and offline — getRepoUpstream short-circuits on the
`upstream` git remote before it reaches `gh`, so the container's two
remotes decide the answer with no GitHub auth or network.

Verified by revert: with the fix backed out, upstream stays unresolved
for the full 90s after connect.
@Jinwoo-H
Jinwoo-H force-pushed the fix-ssh-fork-upstream-backfill branch from fd6573d to 665ca63 Compare August 10, 2026 04:28
@coderabbitai

coderabbitai Bot commented Aug 10, 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.

This branch has not been deployed

No deployments
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.

[Bug] Fork upstream is never backfilled for SSH/remote repos, so Project rows stay hidden

1 participant