Stop the Gitea source ingesting Orchestra's own pull requests
The issues endpoint returns pull requests alongside issues, and nothing filtered them. The first submission this deployment ever made, kami/test-e2e#8, came straight back as task 06G4E83E4KRXM8DS90M2648MGM with the submission packet as its description. That task would have implemented, reviewed and submitted again, opening a pull request per cycle. The webhook had the same hole from the other side: a pull_request delivery leaves the issue key empty, so it would have appended a task numbered 0 with no title. Both routes now refuse a pull request, and the poll count reports what was ingested rather than what was listed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CVbaKucEYBjMqVeUgJUsc1
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
@@ -134,3 +135,46 @@ func TestLoadGiteaConfigsValidatesAndRejectsDuplicates(t *testing.T) {
|
||||
t.Fatal("expected missing-field rejection")
|
||||
}
|
||||
}
|
||||
|
||||
// Orchestra opens pull requests itself. The Gitea issues endpoint returns them
|
||||
// alongside issues, so a poller that accepts them ingests its own submission
|
||||
// back as a task whose description is the submission packet, and that task
|
||||
// submits again. Seen live on 2026-08-28: pull request #8 became task
|
||||
// 06G4E83E4KRXM8DS90M2648MGM.
|
||||
func TestPollIgnoresPullRequests(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
json.NewEncoder(w).Encode([]map[string]any{
|
||||
{"number": 7, "title": "a real issue", "body": "", "state": "open"},
|
||||
{"number": 8, "title": "orchestra submission", "body": "", "state": "open",
|
||||
"pull_request": map[string]any{"merged": false}},
|
||||
})
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
sk := &sink{}
|
||||
n, err := (Gitea{BaseURL: srv.URL, Owner: "kami", Repo: "test-e2e"}).Poll(context.Background(), sk)
|
||||
if err != nil {
|
||||
t.Fatalf("poll: %v", err)
|
||||
}
|
||||
if n != 1 || len(sk.events) != 1 {
|
||||
t.Fatalf("ingested %d events (reported %d), want exactly the issue", len(sk.events), n)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIngestWebhookIgnoresAPullRequestDelivery(t *testing.T) {
|
||||
g := Gitea{Owner: "kami", Repo: "test-e2e", WebhookSecret: "s3cret"}
|
||||
body, _ := json.Marshal(map[string]any{
|
||||
"action": "opened",
|
||||
"pull_request": map[string]any{"number": 8, "title": "orchestra submission", "state": "open"},
|
||||
})
|
||||
mac := hmac.New(sha256.New, []byte("s3cret"))
|
||||
mac.Write(body)
|
||||
|
||||
sk := &sink{}
|
||||
if err := g.IngestWebhook(body, hex.EncodeToString(mac.Sum(nil)), sk); err != nil {
|
||||
t.Fatalf("ingest: %v", err)
|
||||
}
|
||||
if len(sk.events) != 0 {
|
||||
t.Fatalf("expected no task from a pull request delivery, got %d", len(sk.events))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user