mirror of
https://github.com/go-gitea/gitea.git
synced 2026-08-01 01:20:17 +00:00
fix(actions): correctness and hardening fixes (#38518)
Various fixes to actions 1. **Cap total jobs per run in reusable-workflow expansion** — only nesting depth was capped, so fan-out + nested reusable workflows could explode job-row inserts and exhaust the DB from a single push. Now enforces `MaxJobNumPerRun` in the insert path. 2. **Reject rerun-failed when a run has no failed jobs** — an empty job list meant "re-run everything", so `rerun-failed` on a green run re-ran all jobs. Now errors (web + API). 3. **Don't adopt external commit statuses into the legacy hash** — the pre-#35699 Context-only hash matched API-posted statuses too, collapsing two same-named workflows into one check. Now limited to Actions-user rows. 4. **Don't cut post-cancel cleanup short in `StopEndlessTasks`** — the sweep force-stopped just-cancelled jobs mid-cleanup. Now targets `StatusRunning` only; stalled cancels stay covered by `StopZombieTasks`. 5. **Avoid redundant run reload in `GenerateGiteaContext`** — resolving `github.triggering_actor` reloaded the run already passed in. Now loads only the trigger user via new `ActionRunAttempt.LoadTriggerUser`. --------- Co-authored-by: Zettat123 <zettat123@gmail.com> Co-authored-by: silverwind <me@silverwind.io> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
@@ -143,6 +143,28 @@ jobs:
|
||||
job2LatestAttempt := getLatestAttemptJobByTemplateJobID(t, run.ID, job2.ID)
|
||||
assert.Equal(t, runLatestAttempt.LatestAttemptID, job2LatestAttempt.RunAttemptID)
|
||||
|
||||
t.Run("RerunFailedWithNoFailedJobs", func(t *testing.T) {
|
||||
// The run is fully successful, so an empty failed-job list must be rejected rather than fall
|
||||
// through to re-running the whole run.
|
||||
before := getRunLatestAttemptNum(t, run.ID)
|
||||
req := NewRequest(t, "POST", fmt.Sprintf("/%s/%s/actions/runs/%d/rerun-failed", user2.Name, repo.Name, run.ID))
|
||||
resp := session.MakeRequest(t, req, http.StatusBadRequest)
|
||||
assert.Contains(t, resp.Body.String(), "no failed jobs")
|
||||
assert.Equal(t, before, getRunLatestAttemptNum(t, run.ID))
|
||||
runner.fetchNoTask(t) // no new tasks were scheduled
|
||||
})
|
||||
|
||||
t.Run("RerunFailedWithNoFailedJobsAPI", func(t *testing.T) {
|
||||
// Same rejection on the API route: an empty failed-job list must not fall through to a full re-run.
|
||||
before := getRunLatestAttemptNum(t, run.ID)
|
||||
req := NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/actions/runs/%d/rerun-failed-jobs", user2.Name, repo.Name, run.ID)).
|
||||
AddTokenAuth(token)
|
||||
resp := MakeRequest(t, req, http.StatusBadRequest)
|
||||
assert.Contains(t, resp.Body.String(), "no failed jobs")
|
||||
assert.Equal(t, before, getRunLatestAttemptNum(t, run.ID))
|
||||
runner.fetchNoTask(t)
|
||||
})
|
||||
|
||||
t.Run("AttemptAPI", func(t *testing.T) {
|
||||
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/actions/runs/%d/attempts/2", user2.Name, repo.Name, run.ID)).
|
||||
AddTokenAuth(token)
|
||||
|
||||
Reference in New Issue
Block a user