Skip to content

fix(stage): validate public remote URL parsing and surface gh pr create stderr#19

Open
andyma-star wants to merge 2 commits into
mainfrom
feature/stage-optional-pr-body-copy
Open

fix(stage): validate public remote URL parsing and surface gh pr create stderr#19
andyma-star wants to merge 2 commits into
mainfrom
feature/stage-optional-pr-body-copy

Conversation

@andyma-star
Copy link
Copy Markdown
Contributor

@andyma-star andyma-star commented Apr 1, 2026

Two gaps in error handling for venfork stage: unparseable public remote URLs silently produced malformed commands, and gh pr create failures swallowed the underlying error reason.

Changes

  • Remote URL validation — after parsing the public remote, fail fast with a clear message if publicRepoPath is empty (always) or publicOwner is empty (when --create-pr is set), before any URL/command construction
  • gh pr create failure diagnostics — when gh pr create exits non-zero, emit stderr via p.log.warn so users see the actual failure reason (duplicate PR, missing permissions, invalid head/base, etc.)

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

Adds opt-in enhancements to venfork stage to optionally create a draft upstream PR and (optionally) copy title/body from the corresponding open private PR on origin, reducing manual copy/paste when staging work.

Changes:

  • Introduces stage-specific CLI arg parsing for --create-pr and --copy-pr-body (with validation).
  • Updates CLI routing to parse stage flags and pass options into stageCommand.
  • Extends stageCommand to optionally run gh pr create --draft, and optionally prefill title/body from a private PR; adds docs and tests.

Reviewed changes

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

Show a summary per file
File Description
src/stage-args.ts Adds parsing/validation for new stage flags.
src/index.ts Routes stage through the new parser and passes options to stageCommand.
src/commands.ts Implements optional draft PR creation and private PR title/body copy in stageCommand.
tests/stage-args.test.ts Adds unit tests for stage arg parsing and validation behavior.
tests/commands.test.ts Adds tests covering draft PR creation and copy-PR-body flow.
README.md Documents new stage flags and updated behavior.
Comments suppressed due to low confidence (1)

src/commands.ts:794

  • git remote get-url upstream is executed with reject:false but the exit code is not checked. If the upstream remote is missing or the command fails, upstreamRepoPath becomes empty and both the compare URL and gh pr create --repo will be invalid. Consider mirroring the public remote handling here (check exitCode and throw RemoteNotFoundError('upstream'), and/or validate parseRepoPath(upstreamUrl) before continuing).
    const upstreamUrlResult = await $({
      reject: false,
    })`git remote get-url upstream`;
    const upstreamUrl = upstreamUrlResult.stdout.trim();
    const upstreamRepoPath = parseRepoPath(upstreamUrl);


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

Comment thread src/commands.ts
const publicUrl = publicUrlResult.stdout.trim();
const publicRepoPath = parseRepoPath(publicUrl);
const publicOwner = parseOwner(publicUrl);

Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

publicRepoPath/publicOwner are used to build the compare URL and to set gh pr create --head, but neither value is validated. If the public remote URL isn’t a parseable github.com URL, parseRepoPath/parseOwner will return an empty string and --head ${publicOwner}:${branch} will be malformed. Add validation (e.g., if !publicRepoPath or (when --create-pr) !publicOwner, fail with a clear error) before constructing URLs/commands.

Suggested change
if (!publicRepoPath) {
p.log.error(
"Could not determine the GitHub repository path from the 'public' remote URL. " +
"Please ensure the 'public' remote points to a valid github.com repository.",
);
process.exit(1);
}
if (createPr && !publicOwner) {
p.log.error(
"Could not determine the GitHub owner from the 'public' remote URL required for --create-pr. " +
"Please ensure the 'public' remote points to a valid github.com repository.",
);
process.exit(1);
}

Copilot uses AI. Check for mistakes.
Comment thread src/commands.ts
createdPrUrl = createResult.stdout.trim() || null;
s.stop('Draft PR created');
} else {
s.stop('Draft PR not created');
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

When gh pr create fails, the code only stops the spinner with "Draft PR not created" and discards the actual stderr/exit reason. This makes it hard to diagnose common cases (already-open PR, missing permissions, invalid head/base). Consider logging createResult.stderr as a warning (or including it in the error path) so users know what to do next.

Suggested change
s.stop('Draft PR not created');
s.stop('Draft PR not created');
const stderr = createResult.stderr?.toString().trim();
if (stderr) {
p.log.warn(`gh pr create failed: ${stderr}`);
}

Copilot uses AI. Check for mistakes.
@cabljac
Copy link
Copy Markdown
Owner

cabljac commented Apr 8, 2026

@copilot apply changes based on the comments in this thread

…err on pr create failure

Agent-Logs-Url: https://github.com/cabljac/venfork/sessions/5618afc1-cacc-494f-9b7d-fbea1d72946a

Co-authored-by: cabljac <32874567+cabljac@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 8, 2026

@copilot apply changes based on the comments in this thread

Applied both review changes in commit bf9b528:

  1. Added validation for publicRepoPath (unconditional) and publicOwner (when --create-pr is set) with clear error messages before constructing any URLs or commands.
  2. Logs createResult.stderr as a warning when gh pr create fails so users can diagnose the issue.

Copilot AI changed the title feat(stage): add optional draft PR creation with private PR body copy fix(stage): validate public remote URL parsing and surface gh pr create stderr Apr 8, 2026
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