fix(agentic): preserve issue labels on unlock

This commit is contained in:
Virgil 2026-04-02 18:23:35 +00:00
parent cf0885389a
commit 6e73fb6e8d
2 changed files with 27 additions and 5 deletions

View file

@ -31,9 +31,12 @@ type IssueDispatchInput struct {
}
type forgeIssue struct {
Title string `json:"title"`
Body string `json:"body"`
State string `json:"state"`
Title string `json:"title"`
Body string `json:"body"`
State string `json:"state"`
Labels []struct {
Name string `json:"name"`
} `json:"labels"`
Assignee *struct {
Login string `json:"login"`
} `json:"assignee"`
@ -88,7 +91,7 @@ func (s *PrepSubsystem) dispatchIssue(ctx context.Context, req *mcp.CallToolRequ
var dispatchErr error
defer func() {
if dispatchErr != nil {
_ = s.unlockIssue(ctx, input.Org, input.Repo, input.Issue)
_ = s.unlockIssue(ctx, input.Org, input.Repo, input.Issue, issue.Labels)
}
}()
@ -118,10 +121,23 @@ func (s *PrepSubsystem) dispatchIssue(ctx context.Context, req *mcp.CallToolRequ
})
}
func (s *PrepSubsystem) unlockIssue(ctx context.Context, org, repo string, issue int) error {
func (s *PrepSubsystem) unlockIssue(ctx context.Context, org, repo string, issue int, labels []struct {
Name string `json:"name"`
}) error {
updateURL := fmt.Sprintf("%s/api/v1/repos/%s/%s/issues/%d", s.forgeURL, org, repo, issue)
issueLabels := make([]string, 0, len(labels))
for _, label := range labels {
if label.Name == "in-progress" {
continue
}
issueLabels = append(issueLabels, label.Name)
}
if issueLabels == nil {
issueLabels = []string{}
}
payload, err := json.Marshal(map[string]any{
"assignees": []string{},
"labels": issueLabels,
})
if err != nil {
return coreerr.E("unlockIssue", "failed to encode issue unlock", err)

View file

@ -105,6 +105,9 @@ func TestDispatchIssue_Good_UnlocksOnPrepFailure(t *testing.T) {
"title": "Fix login crash",
"body": "details",
"state": "open",
"labels": []map[string]any{
{"name": "bug"},
},
})
case http.MethodPatch:
w.WriteHeader(http.StatusOK)
@ -148,6 +151,9 @@ func TestDispatchIssue_Good_UnlocksOnPrepFailure(t *testing.T) {
if !strings.Contains(bodies[2], `"assignees":[]`) {
t.Fatalf("expected unlock request to clear assignees, got %s", bodies[2])
}
if !strings.Contains(bodies[2], `"labels":["bug"]`) {
t.Fatalf("expected unlock request to preserve original labels, got %s", bodies[2])
}
}
func TestLockIssue_Good_RequestBody(t *testing.T) {