diff options
| author | Peter Stone <thepeterstone@gmail.com> | 2026-03-26 06:36:32 +0000 |
|---|---|---|
| committer | Peter Stone <thepeterstone@gmail.com> | 2026-03-26 06:36:32 +0000 |
| commit | 44521cc50e304b61c44b9a269a8239fd0fef49cd (patch) | |
| tree | f4c09def154fce8de6803ad376aca6676bebc05e /internal/api/stories.go | |
| parent | ba6a83ae5a62c3e93d7a119c5d8e6690bee7c099 (diff) | |
fix: story branch push to bare repo; drain at 3 consecutive failures
createStoryBranch was pushing to 'origin' which doesn't exist — branches
never landed in the bare repo so agents couldn't clone them. Now uses
the project's RemoteURL (bare repo path) directly for fetch and push.
Raise drain threshold from 2 to 3 consecutive failures to reduce false
positives from transient errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'internal/api/stories.go')
| -rw-r--r-- | internal/api/stories.go | 22 |
1 files changed, 9 insertions, 13 deletions
diff --git a/internal/api/stories.go b/internal/api/stories.go index 3d9d25a..629ea7a 100644 --- a/internal/api/stories.go +++ b/internal/api/stories.go @@ -14,25 +14,21 @@ import ( "github.com/thepeterstone/claudomator/internal/task" ) -// createStoryBranch creates a new git branch in localPath from origin/main -// and pushes it to origin. Idempotent: treats "already exists" as success. -func createStoryBranch(localPath, branchName string) error { - // Fetch latest from origin so origin/main is up to date. - if out, err := exec.Command("git", "-C", localPath, "fetch", "origin").CombinedOutput(); err != nil { +// createStoryBranch creates a new git branch in localPath from the latest main +// and pushes it to remoteURL (the bare repo). Idempotent: treats "already exists" as success. +func createStoryBranch(localPath, branchName, remoteURL string) error { + // Fetch latest from the bare repo so we have an up-to-date base. + if out, err := exec.Command("git", "-C", localPath, "fetch", remoteURL, "main").CombinedOutput(); err != nil { return fmt.Errorf("git fetch: %w (output: %s)", err, string(out)) } - base := "origin/main" + base := "FETCH_HEAD" out, err := exec.Command("git", "-C", localPath, "checkout", "-b", branchName, base).CombinedOutput() if err != nil { if !strings.Contains(string(out), "already exists") { return fmt.Errorf("git checkout -b: %w (output: %s)", err, string(out)) } - // Branch exists; switch to it — idempotent. - if out2, err2 := exec.Command("git", "-C", localPath, "checkout", branchName).CombinedOutput(); err2 != nil { - return fmt.Errorf("git checkout: %w (output: %s)", err2, string(out2)) - } } - if out, err := exec.Command("git", "-C", localPath, "push", "origin", branchName).CombinedOutput(); err != nil { + if out, err := exec.Command("git", "-C", localPath, "push", remoteURL, branchName).CombinedOutput(); err != nil { return fmt.Errorf("git push: %w (output: %s)", err, string(out)) } return nil @@ -313,8 +309,8 @@ func (s *Server) handleApproveStory(w http.ResponseWriter, r *http.Request) { // Create the story branch (non-fatal if it fails). if input.BranchName != "" && input.ProjectID != "" { - if proj, err := s.store.GetProject(input.ProjectID); err == nil && proj.LocalPath != "" { - if err := createStoryBranch(proj.LocalPath, input.BranchName); err != nil { + if proj, err := s.store.GetProject(input.ProjectID); err == nil && proj.LocalPath != "" && proj.RemoteURL != "" { + if err := createStoryBranch(proj.LocalPath, input.BranchName, proj.RemoteURL); err != nil { s.logger.Warn("story approve: failed to create branch", "error", err, "branch", input.BranchName) } } |
