enhance(actions): add pending job status and align job statuses with GitHub (#39376)

This commit is contained in:
silverwind
2026-09-27 20:30:42 +02:00
committed by GitHub
parent 0d09986790
commit 9e7b302bd3
45 changed files with 397 additions and 189 deletions
@@ -603,6 +603,11 @@ jobs:
})
// cannot fetch wf2-job2 because wf1-job1 is running
runner1.fetchNoTask(t)
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/actions/jobs?status=pending", user2.Name, repo.Name)).AddTokenAuth(token)
pendingJobs := DecodeJSON(t, MakeRequest(t, req, http.StatusOK), &api.ActionWorkflowJobsResponse{})
require.Len(t, pendingJobs.Entries, 1)
assert.Equal(t, "wf2-job2", pendingJobs.Entries[0].Name)
assert.Equal(t, "pending", pendingJobs.Entries[0].Status)
// exec wf1-job1
runner1.execTask(t, wf1Job1Task, &mockTaskOutcome{
result: runnerv1.Result_RESULT_SUCCESS,
+1 -1
View File
@@ -411,7 +411,7 @@ jobs:
require.Contains(t, rerunJobsByJobID, "job1")
require.Contains(t, rerunJobsByJobID, "job2")
assert.Equal(t, actions_model.StatusWaiting, rerunJobsByJobID["job1"].Status)
assert.Equal(t, actions_model.StatusBlocked, rerunJobsByJobID["job2"].Status)
assert.Equal(t, actions_model.StatusPending, rerunJobsByJobID["job2"].Status)
// fetch job1 rerun task
job1TaskR1 := runner.fetchTask(t)
@@ -184,13 +184,13 @@ jobs:
callerJob2 := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunJob{RunID: runID, JobID: "caller_job2"})
callerJob2ID = callerJob2.ID
callerJob2AttemptJobID = callerJob2.AttemptJobID
assert.Equal(t, actions_model.StatusBlocked, callerJob2.Status)
assert.Equal(t, actions_model.StatusPending, callerJob2.Status)
assert.True(t, callerJob2.IsReusableCaller)
// caller_job3
callerJob3 := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunJob{RunID: runID, JobID: "caller_job3"})
callerJob3AttemptJobID = callerJob3.AttemptJobID
assert.Equal(t, actions_model.StatusBlocked, callerJob3.Status)
assert.Equal(t, actions_model.StatusPending, callerJob3.Status)
assert.False(t, callerJob3.IsReusableCaller)
})
@@ -230,9 +230,8 @@ jobs:
result: runnerv1.Result_RESULT_SUCCESS,
})
// reusable1_job3 (a nested caller) needs reusable1_job2, so it stays Blocked until r1j2 succeeds.
r1Job3Pre := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunJob{RunID: runID, JobID: "reusable1_job3"})
assert.Equal(t, actions_model.StatusBlocked, r1Job3Pre.Status)
assert.Equal(t, actions_model.StatusPending, r1Job3Pre.Status)
assert.False(t, r1Job3Pre.IsExpanded)
assert.Equal(t, 0, unittest.GetCount(t, &actions_model.ActionRunJob{RunID: runID, JobID: "reusable2_job1"}))
@@ -308,11 +307,11 @@ jobs:
callerJob2 := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunJob{RunID: runID, RunAttemptID: attempt2.ID, AttemptJobID: callerJob2AttemptJobID})
assert.Equal(t, actions_model.StatusWaiting, callerJob2.Status)
callerJob3 := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunJob{RunID: runID, RunAttemptID: attempt2.ID, AttemptJobID: callerJob3AttemptJobID})
assert.Equal(t, actions_model.StatusBlocked, callerJob3.Status)
assert.Equal(t, actions_model.StatusPending, callerJob3.Status)
// reusable1_job3 needs reusable1_job2, so rerunning r1j2 pulls r1j3 (and its subtree) into the rerun set
r1Job3Attempt2 := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunJob{RunID: runID, RunAttemptID: attempt2.ID, AttemptJobID: r1Job3AttemptJobID})
assert.Equal(t, actions_model.StatusBlocked, r1Job3Attempt2.Status)
assert.Equal(t, actions_model.StatusPending, r1Job3Attempt2.Status)
assert.True(t, r1Job3Attempt2.IsReusableCaller)
assert.False(t, r1Job3Attempt2.IsExpanded)
assert.Equal(t, 0, unittest.GetCount(t, &actions_model.ActionRunJob{RunID: runID, RunAttemptID: attempt2.ID, JobID: "reusable2_job1"}))
@@ -606,12 +605,11 @@ jobs:
uses: ./.gitea/workflows/does-not-exist.yml
`)
// plain_job runs first; bad_caller is Blocked on needs and is NOT expanded at creation.
plainTask := runner.fetchTask(t)
_, plainJob, run := getTaskAndJobAndRunByTaskID(t, plainTask.Id)
assert.Equal(t, "plain_job", plainJob.JobID)
badCallerPre := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunJob{RunID: run.ID, JobID: "bad_caller"})
assert.Equal(t, actions_model.StatusBlocked, badCallerPre.Status)
assert.Equal(t, actions_model.StatusPending, badCallerPre.Status)
assert.False(t, badCallerPre.IsExpanded)
runner.execTask(t, plainTask, &mockTaskOutcome{result: runnerv1.Result_RESULT_SUCCESS})
@@ -975,7 +973,6 @@ jobs:
innerChild := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunJob{RunID: runID, JobID: "inner"})
assert.Equal(t, willRun.ID, innerChild.ParentJobID)
// after_skip: a dependent of the skipped caller resolves to Skipped instead of staying Blocked.
afterSkip := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunJob{RunID: runID, JobID: "after_skip"})
assert.Equal(t, actions_model.StatusSkipped, afterSkip.Status)
})
+38 -38
View File
@@ -1045,7 +1045,7 @@ jobs:
// 3. validate the webhook is triggered
assert.Equal(t, "workflow_job", triggeredEvent)
assert.Len(t, payloads, 2)
assert.Len(t, payloads, 1)
assert.Equal(t, "queued", payloads[0].Action)
assert.Equal(t, "queued", payloads[0].WorkflowJob.Status)
assert.Equal(t, []string{"ubuntu-latest"}, payloads[0].WorkflowJob.Labels)
@@ -1053,11 +1053,11 @@ jobs:
assert.Equal(t, "repo1", payloads[0].Repo.Name)
assert.Equal(t, "user2/repo1", payloads[0].Repo.FullName)
assert.Equal(t, "waiting", payloads[1].Action)
assert.Equal(t, "waiting", payloads[1].WorkflowJob.Status)
assert.Equal(t, commitID, payloads[1].WorkflowJob.HeadSha)
assert.Equal(t, "repo1", payloads[1].Repo.Name)
assert.Equal(t, "user2/repo1", payloads[1].Repo.FullName)
req := NewRequest(t, "GET", "/api/v1/repos/user2/repo1/actions/jobs?status=requested").AddTokenAuth(token)
requestedJobs := DecodeJSON(t, MakeRequest(t, req, http.StatusOK), &api.ActionWorkflowJobsResponse{})
require.Len(t, requestedJobs.Entries, 1)
assert.Equal(t, "wf2-job", requestedJobs.Entries[0].Name)
assert.Equal(t, "requested", requestedJobs.Entries[0].Status)
// 4. Execute a single Job
task := runner.fetchTask(t)
@@ -1068,31 +1068,31 @@ jobs:
// 5. validate the webhook is triggered
assert.Equal(t, "workflow_job", triggeredEvent)
assert.Len(t, payloads, 5)
assert.Equal(t, "in_progress", payloads[2].Action)
assert.Equal(t, "in_progress", payloads[2].WorkflowJob.Status)
assert.Len(t, payloads, 4)
assert.Equal(t, "in_progress", payloads[1].Action)
assert.Equal(t, "in_progress", payloads[1].WorkflowJob.Status)
assert.Equal(t, "mock-runner", payloads[1].WorkflowJob.RunnerName)
assert.Equal(t, commitID, payloads[1].WorkflowJob.HeadSha)
assert.Equal(t, "repo1", payloads[1].Repo.Name)
assert.Equal(t, "user2/repo1", payloads[1].Repo.FullName)
assert.Equal(t, "completed", payloads[2].Action)
assert.Equal(t, "completed", payloads[2].WorkflowJob.Status)
assert.Equal(t, "mock-runner", payloads[2].WorkflowJob.RunnerName)
assert.Equal(t, "success", payloads[2].WorkflowJob.Conclusion)
assert.Equal(t, commitID, payloads[2].WorkflowJob.HeadSha)
assert.Equal(t, "repo1", payloads[2].Repo.Name)
assert.Equal(t, "user2/repo1", payloads[2].Repo.FullName)
assert.Contains(t, payloads[2].WorkflowJob.URL, fmt.Sprintf("/actions/jobs/%d", payloads[2].WorkflowJob.ID))
assert.Contains(t, payloads[2].WorkflowJob.HTMLURL, fmt.Sprintf("/jobs/%d", payloads[2].WorkflowJob.ID))
assert.Len(t, payloads[2].WorkflowJob.Steps, 1)
assert.Equal(t, "completed", payloads[3].Action)
assert.Equal(t, "completed", payloads[3].WorkflowJob.Status)
assert.Equal(t, "mock-runner", payloads[3].WorkflowJob.RunnerName)
assert.Equal(t, "success", payloads[3].WorkflowJob.Conclusion)
assert.Equal(t, "queued", payloads[3].Action)
assert.Equal(t, "queued", payloads[3].WorkflowJob.Status)
assert.Equal(t, []string{"ubuntu-latest"}, payloads[3].WorkflowJob.Labels)
assert.Equal(t, commitID, payloads[3].WorkflowJob.HeadSha)
assert.Equal(t, "repo1", payloads[3].Repo.Name)
assert.Equal(t, "user2/repo1", payloads[3].Repo.FullName)
assert.Contains(t, payloads[3].WorkflowJob.URL, fmt.Sprintf("/actions/jobs/%d", payloads[3].WorkflowJob.ID))
assert.Contains(t, payloads[3].WorkflowJob.HTMLURL, fmt.Sprintf("/jobs/%d", payloads[3].WorkflowJob.ID))
assert.Len(t, payloads[3].WorkflowJob.Steps, 1)
assert.Equal(t, "queued", payloads[4].Action)
assert.Equal(t, "queued", payloads[4].WorkflowJob.Status)
assert.Equal(t, []string{"ubuntu-latest"}, payloads[4].WorkflowJob.Labels)
assert.Equal(t, commitID, payloads[4].WorkflowJob.HeadSha)
assert.Equal(t, "repo1", payloads[4].Repo.Name)
assert.Equal(t, "user2/repo1", payloads[4].Repo.FullName)
// 6. Execute a single Job
task = runner.fetchTask(t)
@@ -1103,25 +1103,25 @@ jobs:
// 7. validate the webhook is triggered
assert.Equal(t, "workflow_job", triggeredEvent)
assert.Len(t, payloads, 7)
assert.Equal(t, "in_progress", payloads[5].Action)
assert.Equal(t, "in_progress", payloads[5].WorkflowJob.Status)
assert.Equal(t, "mock-runner", payloads[5].WorkflowJob.RunnerName)
assert.Len(t, payloads, 6)
assert.Equal(t, "in_progress", payloads[4].Action)
assert.Equal(t, "in_progress", payloads[4].WorkflowJob.Status)
assert.Equal(t, "mock-runner", payloads[4].WorkflowJob.RunnerName)
assert.Equal(t, commitID, payloads[4].WorkflowJob.HeadSha)
assert.Equal(t, "repo1", payloads[4].Repo.Name)
assert.Equal(t, "user2/repo1", payloads[4].Repo.FullName)
assert.Equal(t, "completed", payloads[5].Action)
assert.Equal(t, "completed", payloads[5].WorkflowJob.Status)
assert.Equal(t, "failure", payloads[5].WorkflowJob.Conclusion)
assert.Equal(t, "mock-runner", payloads[5].WorkflowJob.RunnerName)
assert.Equal(t, commitID, payloads[5].WorkflowJob.HeadSha)
assert.Equal(t, "repo1", payloads[5].Repo.Name)
assert.Equal(t, "user2/repo1", payloads[5].Repo.FullName)
assert.Equal(t, "completed", payloads[6].Action)
assert.Equal(t, "completed", payloads[6].WorkflowJob.Status)
assert.Equal(t, "failure", payloads[6].WorkflowJob.Conclusion)
assert.Equal(t, "mock-runner", payloads[6].WorkflowJob.RunnerName)
assert.Equal(t, commitID, payloads[6].WorkflowJob.HeadSha)
assert.Equal(t, "repo1", payloads[6].Repo.Name)
assert.Equal(t, "user2/repo1", payloads[6].Repo.FullName)
assert.Contains(t, payloads[6].WorkflowJob.URL, fmt.Sprintf("/actions/jobs/%d", payloads[6].WorkflowJob.ID))
assert.Contains(t, payloads[6].WorkflowJob.HTMLURL, fmt.Sprintf("/jobs/%d", payloads[6].WorkflowJob.ID))
assert.Len(t, payloads[6].WorkflowJob.Steps, 2)
assert.Contains(t, payloads[5].WorkflowJob.URL, fmt.Sprintf("/actions/jobs/%d", payloads[5].WorkflowJob.ID))
assert.Contains(t, payloads[5].WorkflowJob.HTMLURL, fmt.Sprintf("/jobs/%d", payloads[5].WorkflowJob.ID))
assert.Len(t, payloads[5].WorkflowJob.Steps, 2)
})
}