-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Open
Labels
dev-experiencefeature-requestp2Non-showstopper bug or popular feature requestNon-showstopper bug or popular feature request
Description
Background
PR #937 reverted fork PR support (#851) and unique branch naming (#931) to fix a P1 bug where commits were pushed to wrong branches. This blocks major OSS adoption (e.g., PyTorch where 90%+ PRs are from forks).
Opening this discussion to align on design approach before implementation.
Related: #851, #930, #931, #936, #937
Problem
Three conflicting requirements:
- Local branch name must match PR's head ref for
git pushto work (as raised in Claude fails to make commits to PR branch #936) - Unique local naming (
pr-{number}) needed to avoid conflicts (the concern in PR checkout fails due to branch name collision after #851 #930) - Fork PRs require fetching from
pull/{number}/headrefs (the issue noted in Fix PR checkout to support fork PRs #851)
Design Decisions Needed
1. Environment Setup Philosophy
Should claude-code-action remain self-contained or delegate to user setup?
Option A: Self-Contained
- Action handles all git setup automatically
- Pros: Zero config, consistent behavior, better UX
- Cons: More complex implementation
Option B: Delegated Setup
- Users run
actions/checkout - Pros: Simpler action code
- Cons: Higher user burden, inconsistent setups
2. Fork PR Support Implementation
Assuming self-contained approach, propose the following solution:
Proposed Solution
Explicit Push Target + Conditional Handling
// Key changes in setupBranch()
if (isForkPR) {
const localBranch = `pr-${entityNumber}`;
execGit(["fetch", "origin", `pull/${entityNumber}/head:${localBranch}`]);
execGit(["checkout", localBranch, "--"]);
return { currentBranch: localBranch, originalBranchRef: headRefName };
} else {
// Same-repo: keep current behavior
execGit(["fetch", "origin", `--depth=${fetchDepth}`, headRefName]);
execGit(["checkout", headRefName, "--"]);
return { currentBranch: headRefName };
}
// In push logic
const target = originalBranchRef || currentBranch;
execGit(["push", "origin", `HEAD:${target}`]);Changes needed:
- Add
originalBranchRef?: stringtoBranchInfotype - Implement fork detection:
headRepository.id !== baseRepository.id - Update push commands to use explicit target
- Add GraphQL fields for repository IDs
Why it works:
- Fork PRs: unique local name (
pr-123) + explicit push target - Same-repo PRs: no change (keeps current behavior)
- Avoids branch conflicts while fixing push destination
Discussion Points
Feedback needed on these key decisions:
- Environment setup: Should we keep the self-contained approach or allow delegated setup?
- Fork detection: Is
headRepository.id !== baseRepository.idsufficient, or do we need additional checks? - Fork support enablement: Should fork PR support be opt-out (default enabled) or opt-in?
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
dev-experiencefeature-requestp2Non-showstopper bug or popular feature requestNon-showstopper bug or popular feature request