fix: drop queued job updates for deleted runs instead of requeueing forever (#39037)

When a repository is deleted while one of its Actions runs still has a
pending job update in the emitter queue, `checkJobsByRunID` returns an
error because the run no longer exists. The queue handler in
`jobEmitterQueueHandler` treats every error as unhandled and requeues
the item, creating an infinite retry loop that fills the log with error
messages.

### Changes

1. **`services/actions/job_emitter.go`** — swap the `!exist`/`err` check
order so a database error is reported first, then treat a non-existent
run as handled (nil error). The queue consumer drops the item instead of
requeueing it.

2. **`services/actions/job_emitter_test.go`** — add
`Test_checkJobsByRunID_DeletedRunIsHandled`, which verifies that a
deleted run produces nil (handled, not requeued).

### Related issue

Fixes #39034

---------

Co-authored-by: bircni <bircni@icloud.com>
This commit is contained in:
water
2026-08-22 21:55:08 +08:00
committed by GitHub
parent 66d6f74cb0
commit 51e42d4b11
2 changed files with 13 additions and 3 deletions

View File

@@ -64,12 +64,14 @@ func jobEmitterQueueHandler(items ...*jobUpdate) []*jobUpdate {
func checkJobsByRunID(ctx context.Context, runID int64) error {
run, exist, err := db.GetByID[actions_model.ActionRun](ctx, runID)
if !exist {
return fmt.Errorf("run %d does not exist", runID)
}
if err != nil {
return fmt.Errorf("get action run: %w", err)
}
if !exist {
// a deleted run never comes back, returning an error here would requeue the update forever
log.Debug("check run %d: run no longer exists, dropping the queued update", runID)
return nil
}
var result jobsCheckResult
if err := db.WithTx(ctx, func(ctx context.Context) error {
// check jobs of the current run

View File

@@ -685,3 +685,11 @@ func Test_jobStatusResolverStopsAfterMatrixInsert(t *testing.T) {
"report must wait for the re-emit, which sees the sibling combinations too")
})
}
// https://github.com/go-gitea/gitea/issues/39034
func Test_jobEmitterQueueHandler_DeletedRunIsNotRequeued(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
assert.Empty(t, jobEmitterQueueHandler(&jobUpdate{RunID: unittest.NonexistentID}),
"an update for a deleted run must be dropped, not returned as unhandled")
}