fix(gh): bypass the stale run cache with a created filter

GitHub answered the confirming run query with a weeks-old cached result
even with page=1, so alerts for fixed workflows stayed. A created filter
changes the query each day and reads current runs.
This commit is contained in:
2026-10-05 11:16:37 +01:00
parent 06922abe05
commit 0a2469ef7d
2 changed files with 16 additions and 12 deletions
+14 -10
View File
@@ -14,14 +14,16 @@ import (
) )
const ( const (
maxFailingNames = 5 maxFailingNames = 5
runsPerWorkflow = 5 runsPerWorkflow = 5
maxWorkflows = 100 // freshRunsWindowDays bounds the created filter of the confirming run query.
eventPullRequest = "pull_request" freshRunsWindowDays = 30
eventPullReqTgt = "pull_request_target" maxWorkflows = 100
statusStateFail = "failure" eventPullRequest = "pull_request"
statusStateError = "error" eventPullReqTgt = "pull_request_target"
statusStatePend = "pending" statusStateFail = "failure"
statusStateError = "error"
statusStatePend = "pending"
) )
// backgroundEvents are triggers that run without a person pushing code. // backgroundEvents are triggers that run without a person pushing code.
@@ -374,9 +376,11 @@ func (c *Client) workflowRuns(ctx context.Context, full string, id int64, branch
path := fmt.Sprintf("/repos/%s/actions/workflows/%d/runs", full, id) path := fmt.Sprintf("/repos/%s/actions/workflows/%d/runs", full, id)
get := c.getJSON get := c.getJSON
if fresh { if fresh {
// GitHub can keep answering one exact query from an old cached result, for weeks, whatever // GitHub can keep answering a branch query from an old cached result, for weeks, whatever
// the connection. A different query string skips that entry and reads current runs. // the connection, and page=1 alone does not skip it. A created filter changes the query
// every day and reads current runs.
q.Set("page", "1") q.Set("page", "1")
q.Set("created", ">="+c.now().UTC().AddDate(0, 0, -freshRunsWindowDays).Format(time.DateOnly))
get = c.getJSONFresh get = c.getJSONFresh
} }
if err := get(ctx, full, path, q, &out); err != nil { if err := get(ctx, full, path, q, &out); err != nil {
+2 -2
View File
@@ -461,12 +461,12 @@ func TestAPIErrorMessageParsing(t *testing.T) {
} }
// staleThenFresh models GitHub answering one exact query from an old cached result: the plain // staleThenFresh models GitHub answering one exact query from an old cached result: the plain
// query returns an old failing run every time, and the same query with page=1 returns current runs. // query returns an old failing run every time, and the same query with a created filter returns current runs.
func staleThenFresh(f *fakeGitHub, path string) *atomic.Int64 { func staleThenFresh(f *fakeGitHub, path string) *atomic.Int64 {
var calls atomic.Int64 var calls atomic.Int64
f.routes[path] = func(w http.ResponseWriter, r *http.Request) { f.routes[path] = func(w http.ResponseWriter, r *http.Request) {
calls.Add(1) calls.Add(1)
if r.URL.Query().Get("page") == "" { if r.URL.Query().Get("created") == "" {
_, _ = w.Write([]byte(`{"workflow_runs":[ _, _ = w.Write([]byte(`{"workflow_runs":[
{"id":1,"html_url":"old","event":"schedule","head_branch":"main","status":"completed","conclusion":"failure","created_at":"2026-09-11T03:02:00Z"}]}`)) {"id":1,"html_url":"old","event":"schedule","head_branch":"main","status":"completed","conclusion":"failure","created_at":"2026-09-11T03:02:00Z"}]}`))
return return