anthropics / anthropics/claude-code-action
feat: Implement idempotent branch operations to improve reliability
- Lingua principale
- TypeScript
- Stelle
- 8.9k
- Fork
- 2.1k
- Merge medio
- 3g 9h
- PR unite (30g)
- 10
Descrizione
## Problem
When a GitHub Actions job fails and is retried, the current implementation creates a **new branch** because branch names include timestamps:
```
claude/issue-123-20250103-1430
claude/issue-123-20250103-1445 <- retry creates new branch
claude/issue-123-20250103-1500 <- another new branch
```
This causes:
1. **Branch sprawl** - Accumulation of orphan branches
2. **Lost work** - Previous progress not continued
3. **Confusion** - Multiple branches for same issue/PR
## Root Cause
The current approach uses unique timestamps to **avoid** conflicts rather than **solving** them. This is accidental complexity.
The fundamental question: **Why does the same issue/PR need multiple branches?**
In most cases, one issue = one Claude branch. Multiple triggers on the same issue should continue on the same branch, not create new ones.
## Proposed Solution
### 1. Simplified Branch Naming
**Before:**
```
{prefix}{entity_type}-{entity_number}-{timestamp}
Example: claude/issue-123-20250103-1430
```
**After:**
```
{prefix}{entity_type}-{entity_number}
Example: claude/issue-123
```
### 2. Idempotent Branch Creation (check-before-create)
```typescript
async function setupBranch(...): Promise {
const branchName = `${branchPrefix}${entityType}-${entityNumber}`;
const branchExists = await checkBranchExists(octokit, owner, repo, branchName);
if (branchExists) {
// Branch exists -> checkout and continue
execGit(["fetch", "origin", branchName]);
execGit(["checkout", branchName]);
} else {
// Branch doesn't exist -> create
execGit(["fetch", "origin", sourceBranch, "--depth=1"]);
execGit(["checkout", sourceBranch]);
execGit(["checkout", "-b", branchName]);
}
return { baseBranch: sourceBranch, claudeBranch: branchName, currentBranch: branchName };
}
```
### 3. Documentation for Concurrency Control
Users should configure workflow-level concurrency to prevent simultaneous executions:
```yaml
concurrency:
group: claude-${{ github.event.issue.number || github.event.pull_request.number }}
cancel-in-progress: false
```
## Files to Modify
| File | Change |
|------|--------|
| `src/github/operations/branch.ts` | Remove timestamp, add check-before-create |
| `src/mcp/github-file-ops-server.ts` | Idempotent handling for commit signing mode |
| `README.md` or `docs/` | Concurrency configuration docs |
| `test/branch.test.ts` | Add idempotency tests |
## Benefits
1. **Reliability** - Retries work correctly without creating duplicate branches
2. **Simplicity** - One branch per issue/PR, easy to understand
3. **No sprawl** - Eliminates accumulation of orphan branches
Guida per i contributori
Apri la guida per i contributori
Valutazione
Questa issue non è ancora stata valutata.