Skip to content

Commit 91fccb7

Browse files
committed
Fix and Test rerun single jobs
1 parent b012126 commit 91fccb7

File tree

2 files changed

+152
-1
lines changed

2 files changed

+152
-1
lines changed

routers/web/repo/actions/view.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@ func Rerun(ctx *context_module.Context) {
473473
for _, j := range rerunJobs {
474474
// jobs other than the specified one should be set to "blocked" status
475475
// TODO respect blockRunByConcurrency here?
476-
shouldBlock := j.JobID != job.JobID
476+
shouldBlock := j.JobID != job.JobID || blockRunByConcurrency
477477
if err := rerunJob(ctx, j, shouldBlock); err != nil {
478478
ctx.ServerError("RerunJob", err)
479479
return

tests/integration/actions_concurrency_test.go

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,157 @@ jobs:
725725
})
726726
}
727727

728+
func TestWorkflowDispatchRerunSingleJobConcurrency(t *testing.T) {
729+
onGiteaRun(t, func(t *testing.T, u *url.URL) {
730+
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
731+
session := loginUser(t, user2.Name)
732+
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser)
733+
734+
apiRepo := createActionsTestRepo(t, token, "actions-concurrency", false)
735+
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: apiRepo.ID})
736+
httpContext := NewAPITestContext(t, user2.Name, repo.Name, auth_model.AccessTokenScopeWriteRepository)
737+
defer doAPIDeleteRepository(httpContext)(t)
738+
739+
runner := newMockRunner()
740+
runner.registerAsRepoRunner(t, user2.Name, repo.Name, "mock-runner", []string{"ubuntu-latest"}, false)
741+
742+
wf1TreePath := ".gitea/workflows/workflow-dispatch-concurrency.yml"
743+
wf1FileContent := `name: workflow-dispatch-concurrency
744+
on:
745+
workflow_dispatch:
746+
inputs:
747+
appVersion:
748+
description: 'APP version'
749+
required: true
750+
default: 'v1.23'
751+
type: choice
752+
options:
753+
- v1.21
754+
- v1.22
755+
- v1.23
756+
cancel:
757+
description: 'Cancel running workflows'
758+
required: false
759+
type: boolean
760+
default: false
761+
concurrency:
762+
group: workflow-dispatch-${{ inputs.appVersion }}
763+
cancel-in-progress: ${{ inputs.cancel }}
764+
jobs:
765+
job:
766+
runs-on: ubuntu-latest
767+
steps:
768+
- run: echo 'workflow dispatch job'
769+
`
770+
771+
opts1 := getWorkflowCreateFileOptions(user2, repo.DefaultBranch, "create %s"+wf1TreePath, wf1FileContent)
772+
createWorkflowFile(t, token, user2.Name, repo.Name, wf1TreePath, opts1)
773+
774+
// run the workflow with appVersion=v1.21 and cancel=false
775+
urlStr := fmt.Sprintf("/%s/%s/actions/run?workflow=%s", user2.Name, repo.Name, "workflow-dispatch-concurrency.yml")
776+
req := NewRequestWithValues(t, "POST", urlStr, map[string]string{
777+
"_csrf": GetUserCSRFToken(t, session),
778+
"ref": "refs/heads/main",
779+
"appVersion": "v1.21",
780+
})
781+
session.MakeRequest(t, req, http.StatusSeeOther)
782+
task1 := runner.fetchTask(t)
783+
_, _, run1 := getTaskAndJobAndRunByTaskID(t, task1.Id)
784+
assert.Equal(t, "workflow-dispatch-v1.21", run1.ConcurrencyGroup)
785+
786+
req = NewRequestWithValues(t, "POST", urlStr, map[string]string{
787+
"_csrf": GetUserCSRFToken(t, session),
788+
"ref": "refs/heads/main",
789+
"appVersion": "v1.22",
790+
})
791+
session.MakeRequest(t, req, http.StatusSeeOther)
792+
task2 := runner.fetchTask(t)
793+
_, _, run2 := getTaskAndJobAndRunByTaskID(t, task2.Id)
794+
assert.Equal(t, "workflow-dispatch-v1.22", run2.ConcurrencyGroup)
795+
796+
// run the workflow with appVersion=v1.22 and cancel=false again
797+
req = NewRequestWithValues(t, "POST", urlStr, map[string]string{
798+
"_csrf": GetUserCSRFToken(t, session),
799+
"ref": "refs/heads/main",
800+
"appVersion": "v1.22",
801+
})
802+
session.MakeRequest(t, req, http.StatusSeeOther)
803+
804+
runner.fetchNoTask(t) // cannot fetch task because task2 is not completed
805+
806+
// run the workflow with appVersion=v1.22 and cancel=true
807+
req = NewRequestWithValues(t, "POST", urlStr, map[string]string{
808+
"_csrf": GetUserCSRFToken(t, session),
809+
"ref": "refs/heads/main",
810+
"appVersion": "v1.22",
811+
"cancel": "on",
812+
})
813+
session.MakeRequest(t, req, http.StatusSeeOther)
814+
task4 := runner.fetchTask(t)
815+
_, _, run4 := getTaskAndJobAndRunByTaskID(t, task4.Id)
816+
assert.Equal(t, actions_model.StatusRunning, run4.Status)
817+
assert.Equal(t, "workflow-dispatch-v1.22", run4.ConcurrencyGroup)
818+
_, _, run2 = getTaskAndJobAndRunByTaskID(t, task2.Id)
819+
assert.Equal(t, actions_model.StatusCancelled, run2.Status)
820+
821+
runner.execTask(t, task4, &mockTaskOutcome{
822+
result: runnerv1.Result_RESULT_SUCCESS,
823+
})
824+
825+
// rerun cancel true scenario
826+
827+
req = NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/%s/actions/runs/%d/jobs/%d/rerun", user2.Name, apiRepo.Name, run2.Index, 1), map[string]string{
828+
"_csrf": GetUserCSRFToken(t, session),
829+
})
830+
_ = session.MakeRequest(t, req, http.StatusOK)
831+
832+
req = NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/%s/actions/runs/%d/jobs/%d/rerun", user2.Name, apiRepo.Name, run4.Index, 1), map[string]string{
833+
"_csrf": GetUserCSRFToken(t, session),
834+
})
835+
_ = session.MakeRequest(t, req, http.StatusOK)
836+
837+
task5 := runner.fetchTask(t)
838+
_, _, run4_1 := getTaskAndJobAndRunByTaskID(t, task5.Id)
839+
assert.Equal(t, "workflow-dispatch-v1.22", run4_1.ConcurrencyGroup)
840+
assert.Equal(t, run4.ID, run4_1.ID)
841+
_, _, run2_1 := getTaskAndJobAndRunByTaskID(t, task2.Id)
842+
assert.Equal(t, actions_model.StatusCancelled, run2_1.Status)
843+
844+
runner.execTask(t, task5, &mockTaskOutcome{
845+
result: runnerv1.Result_RESULT_CANCELLED,
846+
})
847+
848+
// rerun cancel false scenario
849+
850+
req = NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/%s/actions/runs/%d/jobs/%d/rerun", user2.Name, apiRepo.Name, run2.Index, 1), map[string]string{
851+
"_csrf": GetUserCSRFToken(t, session),
852+
})
853+
_ = session.MakeRequest(t, req, http.StatusOK)
854+
855+
req = NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/%s/actions/runs/%d/jobs/%d/rerun", user2.Name, apiRepo.Name, run2.Index+1, 1), map[string]string{
856+
"_csrf": GetUserCSRFToken(t, session),
857+
})
858+
_ = session.MakeRequest(t, req, http.StatusOK)
859+
860+
task6 := runner.fetchTask(t)
861+
_, _, run2_2 := getTaskAndJobAndRunByTaskID(t, task6.Id)
862+
assert.Equal(t, "workflow-dispatch-v1.22", run2_2.ConcurrencyGroup)
863+
864+
runner.fetchNoTask(t) // cannot fetch task because task2 is not completed
865+
866+
runner.execTask(t, task6, &mockTaskOutcome{
867+
result: runnerv1.Result_RESULT_SUCCESS,
868+
})
869+
870+
task7 := runner.fetchTask(t)
871+
_, _, run3 := getTaskAndJobAndRunByTaskID(t, task7.Id)
872+
assert.Equal(t, "workflow-dispatch-v1.22", run3.ConcurrencyGroup)
873+
runner.execTask(t, task7, &mockTaskOutcome{
874+
result: runnerv1.Result_RESULT_SUCCESS,
875+
})
876+
})
877+
}
878+
728879
func TestScheduleConcurrency(t *testing.T) {
729880
onGiteaRun(t, func(t *testing.T, u *url.URL) {
730881
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})

0 commit comments

Comments
 (0)