Add testable task descriptions: T0.1 through T0.9
Each task includes: - Scope: what to build - Implementation: code sketches + details - Verification: concrete test criteria - Done criteria: acceptance checklist
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
# T0.3: Git & Locking
|
||||
|
||||
## Scope
|
||||
Implement `action/git.go` + `internal/lock/flock.go` for repo cloning, worktree management, and squash-merge.
|
||||
|
||||
## Implementation
|
||||
|
||||
### File: `internal/lock/flock.go`
|
||||
```go
|
||||
package lock
|
||||
|
||||
// Acquire advisory file lock (blocking)
|
||||
func Acquire(path string) error
|
||||
|
||||
// Release advisory file lock
|
||||
func Release(path string) error
|
||||
```
|
||||
|
||||
### File: `action/git.go`
|
||||
```go
|
||||
type CloneRepoInput struct {
|
||||
RemoteURL string
|
||||
TargetRepoPath string
|
||||
}
|
||||
|
||||
func CloneRepoActivity(ctx context.Context, in CloneRepoInput) error
|
||||
// If $TargetRepoPath/.git exists: git -C $TargetRepoPath fetch origin
|
||||
// Else: git clone $RemoteURL $TargetRepoPath
|
||||
|
||||
type GitWorktreeAddInput struct {
|
||||
RepoPath string
|
||||
TaskID string
|
||||
}
|
||||
|
||||
func GitWorktreeAddActivity(ctx context.Context, in GitWorktreeAddInput) (string, error)
|
||||
// Guarded by orchestrator.lock
|
||||
// git worktree add -b task/<TaskID> ../worktrees/<id> origin/main
|
||||
// Return worktree path
|
||||
|
||||
type GitCommitInput struct {
|
||||
WorktreePath string
|
||||
Message string
|
||||
}
|
||||
|
||||
func GitCommitActivity(ctx context.Context, in GitCommitInput) error
|
||||
// No lock needed; safe within isolated worktree
|
||||
// git -C $WorktreePath add -A
|
||||
// git -C $WorktreePath commit -m "$Message"
|
||||
|
||||
type GitPushInput struct {
|
||||
RepoPath string
|
||||
}
|
||||
|
||||
func GitPushActivity(ctx context.Context, in GitPushInput) error
|
||||
// Guarded by orchestrator.lock
|
||||
// git -C $RepoPath push origin main
|
||||
|
||||
type GitSquashMergeInput struct {
|
||||
RepoPath string
|
||||
Branches []string // ["task/T0.1", "task/T0.2", ...]
|
||||
Message string
|
||||
}
|
||||
|
||||
func GitSquashMergeActivity(ctx context.Context, in GitSquashMergeInput) error
|
||||
// Guarded by orchestrator.lock
|
||||
// fetch origin main
|
||||
// checkout main && pull --ff-only origin main
|
||||
// for b in branches: merge --squash $b
|
||||
// commit -m $Message
|
||||
// push origin main
|
||||
// for b in branches: worktree remove + branch -D
|
||||
```
|
||||
|
||||
## Verification
|
||||
```bash
|
||||
cd /Users/rockliang/workplace/Poimen/workflows
|
||||
go test -v ./tests -run TestGit
|
||||
|
||||
# Test script: tests/git_test.go
|
||||
```
|
||||
|
||||
Test cases:
|
||||
- Clone into empty path → creates .git
|
||||
- Clone into existing path → fetches instead of re-cloning
|
||||
- Worktree add → returns valid path
|
||||
- Commit in worktree → file changes staged
|
||||
- Squash-merge → one commit on main, branches cleaned up
|
||||
|
||||
## Done Criteria
|
||||
- `go test ./tests -run TestGit` passes
|
||||
- Tested against local scratch git repo (not real remote)
|
||||
- No lock deadlocks on concurrent calls
|
||||
- Squash-merge produces exactly one commit
|
||||
Reference in New Issue
Block a user