diff options
| author | Claudomator Agent <agent@claudomator.local> | 2026-03-24 22:19:13 +0000 |
|---|---|---|
| committer | Claudomator Agent <agent@claudomator.local> | 2026-03-24 22:19:13 +0000 |
| commit | ad339148be084b425ded24bb21ad7435c59d3072 (patch) | |
| tree | 2e3e939b42ca9578a7ec59091613cfa3219ceb4e /internal/executor/executor.go | |
| parent | b2e77009c55ba0f07bb9ff904d9f2f6cc9ff0ee2 (diff) | |
feat: trigger deploy script on SHIPPABLE → DEPLOYED (ADR-007)
Add triggerStoryDeploy to Pool: fetches story's project, runs its
DeployScript via exec.CommandContext, and advances story to DEPLOYED on
success. Wire into checkStoryCompletion with go p.triggerStoryDeploy
after the SHIPPABLE transition. Covered by TestPool_StoryDeploy_RunsDeployScript.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'internal/executor/executor.go')
| -rw-r--r-- | internal/executor/executor.go | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/internal/executor/executor.go b/internal/executor/executor.go index 22273d9..2ab17a7 100644 --- a/internal/executor/executor.go +++ b/internal/executor/executor.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "log/slog" + "os/exec" "path/filepath" "strings" "sync" @@ -457,6 +458,38 @@ func (p *Pool) checkStoryCompletion(ctx context.Context, storyID string) { return } p.logger.Info("story transitioned to SHIPPABLE", "storyID", storyID) + go p.triggerStoryDeploy(ctx, storyID) +} + +// triggerStoryDeploy runs the project deploy script for a SHIPPABLE story +// and advances it to DEPLOYED on success. +func (p *Pool) triggerStoryDeploy(ctx context.Context, storyID string) { + story, err := p.store.GetStory(storyID) + if err != nil { + p.logger.Error("triggerStoryDeploy: failed to get story", "storyID", storyID, "error", err) + return + } + if story.ProjectID == "" { + return + } + proj, err := p.store.GetProject(story.ProjectID) + if err != nil { + p.logger.Error("triggerStoryDeploy: failed to get project", "storyID", storyID, "projectID", story.ProjectID, "error", err) + return + } + if proj.DeployScript == "" { + return + } + out, err := exec.CommandContext(ctx, proj.DeployScript).CombinedOutput() + if err != nil { + p.logger.Error("triggerStoryDeploy: deploy script failed", "storyID", storyID, "script", proj.DeployScript, "output", string(out), "error", err) + return + } + if err := p.store.UpdateStoryStatus(storyID, task.StoryDeployed); err != nil { + p.logger.Error("triggerStoryDeploy: failed to update story status", "storyID", storyID, "error", err) + return + } + p.logger.Info("story transitioned to DEPLOYED", "storyID", storyID) } // UndrainingAgent resets the drain state and failure counter for the given agent type. |
