Skip to content

fix: seed private mirror over gh-authenticated HTTPS to stop setup hang#43

Merged
cabljac merged 1 commit into
mainfrom
fix/setup-push-https-auth
May 15, 2026
Merged

fix: seed private mirror over gh-authenticated HTTPS to stop setup hang#43
cabljac merged 1 commit into
mainfrom
fix/setup-push-https-auth

Conversation

@cabljac
Copy link
Copy Markdown
Owner

@cabljac cabljac commented May 15, 2026

Problem

venfork setup hangs forever at the spinner Pushing <branch> to private mirror repository.

Root cause: the upstream clone uses gh repo clone (HTTPS + gh token), but the seeding push forced a raw SSH URL (git@github.com:...). When SSH is not usable (no key, passphrase-protected key, or github.com host key not in known_hosts), ssh emits an interactive prompt that is invisible behind the @Clack spinner. With no timeout and no progress, setup hangs indefinitely. Large monorepos (e.g. genkit-ai/genkit) make a working push look dead too, since there is zero feedback.

Changes (src/commands.ts)

  • netExec(cwd?) — execa $ bound with stdin: ignore (credential/host-key prompts fail fast instead of hanging), a hard timeout (VENFORK_GIT_TIMEOUT, default 10m), non-interactive env (GIT_TERMINAL_PROMPT=0, GCM_INTERACTIVE=never, GIT_SSH_COMMAND="ssh -o BatchMode=yes -o ConnectTimeout=15"), inherited stderr for live git --progress.
  • runNetOp(start, stop, op) — start/stop messaging; converts a timeout into a clear GitError instead of an indefinite hang.
  • Seeding push → gh-authenticated HTTPS: pushes to https://github.com/<owner>/<name>.git using gh as a per-invocation git credential helper, plus http.lowSpeedLimit/Time so a stalled transfer aborts in 60s. No SSH dependency, no global gitconfig mutation, no token in argv. Saved remote URLs (privateCloneUrl/publicForkUrl) are unchanged — only transient seeding traffic moves to HTTPS.
  • Both gh repo clone calls routed through runNetOp with -- --progress.

Tests (tests/commands.test.ts)

  • Extend the @Clack mock with log.success/log.step.
  • Assert the seeding push uses HTTPS + the gh credential helper + --progress and never the raw SSH URL.
  • Assert both clones pass --progress.

Verification

  • bunx tsc --noEmit — clean
  • bun run check (biome) — clean
  • bun test — 288 pass, 0 fail, 6 skip (e2e)

`venfork setup` hung forever at "Pushing <branch> to private mirror
repository". The upstream clone uses `gh repo clone` (HTTPS + gh token),
but the seeding push forced a raw SSH URL (git@github.com:...). When SSH
is not usable (no key, passphrase-protected key, or unknown host key),
ssh prints an interactive prompt that is invisible behind the @Clack
spinner, with no timeout and no progress, so setup hangs indefinitely.

- Add `netExec`: execa `$` bound with stdin ignored (credential/host-key
  prompts fail fast instead of hanging), a hard timeout
  (VENFORK_GIT_TIMEOUT, default 10m), non-interactive env
  (GIT_TERMINAL_PROMPT=0, GCM_INTERACTIVE=never,
  GIT_SSH_COMMAND="ssh -o BatchMode=yes -o ConnectTimeout=15"), and
  inherited stderr for live git progress.
- Add `runNetOp`: wraps a network op with start/stop messages and turns
  a timeout into a clear GitError instead of an indefinite hang.
- Seed the new mirror over gh-authenticated HTTPS using gh as a
  per-invocation git credential helper, with http.lowSpeedLimit/Time so
  a stalled transfer aborts in 60s. No SSH dependency, no global
  gitconfig mutation, no token in argv. Saved remote URLs are unchanged.
- Route both `gh repo clone` calls through `runNetOp` with --progress.

Tests: extend the @Clack mock with log.success/step; assert the seeding
push uses HTTPS + gh credential helper + --progress and never the raw
SSH URL, and that both clones pass --progress.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes a venfork setup hang where the seeding push to a new private mirror used a raw SSH URL while the rest of the flow uses gh-authenticated HTTPS. When SSH was unusable, an invisible interactive prompt blocked the push forever. The PR introduces a non-interactive, timeout-bounded execa wrapper for network git/gh operations, switches seeding to HTTPS using gh as a per-invocation credential helper, and adds --progress to clones so large transfers are visible.

Changes:

  • Adds netExec/runNetOp helpers with hard timeout, stdin: ignore, non-interactive env (GIT_TERMINAL_PROMPT=0, GCM_INTERACTIVE=never, GIT_SSH_COMMAND='ssh -o BatchMode=yes -o ConnectTimeout=15'), and a typed GitError on timeout.
  • Routes seeding push through HTTPS + credential.https://github.com.helper=!gh auth git-credential with http.lowSpeedLimit/Time guards; saved remote URLs remain SSH.
  • Adds --progress to upstream/private clones and adds tests asserting HTTPS seeding, credential helper, no SSH URL in seed push, and --progress on clones.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/commands.ts New netExec/runNetOp helpers; seed push moved to HTTPS via gh credential helper; clones get --progress.
tests/commands.test.ts Extends @clack mock with log.success/log.step; adds tests for HTTPS seeding and --progress clones.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@cabljac cabljac merged commit 241878e into main May 15, 2026
8 checks passed
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.

2 participants