@@ -1148,6 +1148,85 @@ jobs:
11481148 })
11491149}
11501150
1151+ func TestCancelConcurrentRun (t * testing.T ) {
1152+ onGiteaRun (t , func (t * testing.T , u * url.URL ) {
1153+ user2 := unittest .AssertExistsAndLoadBean (t , & user_model.User {ID : 2 })
1154+ user2Session := loginUser (t , user2 .Name )
1155+ user2Token := getTokenForLoggedInUser (t , user2Session , auth_model .AccessTokenScopeWriteRepository , auth_model .AccessTokenScopeWriteUser )
1156+
1157+ apiRepo := createActionsTestRepo (t , user2Token , "actions-concurrency" , false )
1158+ repo := unittest .AssertExistsAndLoadBean (t , & repo_model.Repository {ID : apiRepo .ID })
1159+ user2APICtx := NewAPITestContext (t , repo .OwnerName , repo .Name , auth_model .AccessTokenScopeWriteRepository )
1160+ defer doAPIDeleteRepository (user2APICtx )(t )
1161+
1162+ runner := newMockRunner ()
1163+ runner .registerAsRepoRunner (t , repo .OwnerName , repo .Name , "mock-runner" , []string {"ubuntu-latest" }, false )
1164+
1165+ // init the workflow
1166+ wfTreePath := ".gitea/workflows/run.yml"
1167+ wfFileContent := `name: Cancel Run
1168+ on: push
1169+ concurrency:
1170+ group: cancel-run-group
1171+ cancel-in-progress: false
1172+ jobs:
1173+ wf1-job:
1174+ runs-on: ubuntu-latest
1175+ steps:
1176+ - run: echo 'test'
1177+ `
1178+ opts1 := getWorkflowCreateFileOptions (user2 , repo .DefaultBranch , "create %s" + wfTreePath , wfFileContent )
1179+ createWorkflowFile (t , user2Token , repo .OwnerName , repo .Name , wfTreePath , opts1 )
1180+
1181+ // fetch and check the first task
1182+ task1 := runner .fetchTask (t )
1183+ _ , _ , run1 := getTaskAndJobAndRunByTaskID (t , task1 .Id )
1184+ assert .Equal (t , "cancel-run-group" , run1 .ConcurrencyGroup )
1185+ assert .False (t , run1 .ConcurrencyCancel )
1186+ assert .Equal (t , actions_model .StatusRunning , run1 .Status )
1187+
1188+ // push another file to trigger the workflow again
1189+ doAPICreateFile (user2APICtx , "file1.txt" , & api.CreateFileOptions {
1190+ FileOptions : api.FileOptions {
1191+ Message : "create file1.txt" ,
1192+ Author : api.Identity {
1193+ Name : user2 .Name ,
1194+ Email : user2 .Email ,
1195+ },
1196+ Committer : api.Identity {
1197+ Name : user2 .Name ,
1198+ Email : user2 .Email ,
1199+ },
1200+ Dates : api.CommitDateOptions {
1201+ Author : time .Now (),
1202+ Committer : time .Now (),
1203+ },
1204+ },
1205+ ContentBase64 : base64 .StdEncoding .EncodeToString ([]byte ("file1" )),
1206+ })(t )
1207+
1208+ // cannot fetch the second task because the first task is not completed
1209+ runner .fetchNoTask (t )
1210+
1211+ // cancel the first run
1212+ req := NewRequestWithValues (t , "POST" , fmt .Sprintf ("/%s/%s/actions/runs/%d/cancel" , user2 .Name , repo .Name , run1 .Index ), map [string ]string {
1213+ "_csrf" : GetUserCSRFToken (t , user2Session ),
1214+ })
1215+ user2Session .MakeRequest (t , req , http .StatusOK )
1216+
1217+ // the first run has been cancelled
1218+ run1 = unittest .AssertExistsAndLoadBean (t , & actions_model.ActionRun {ID : run1 .ID })
1219+ assert .Equal (t , actions_model .StatusCancelled , run1 .Status )
1220+
1221+ // fetch and check the second task
1222+ task2 := runner .fetchTask (t )
1223+ _ , _ , run2 := getTaskAndJobAndRunByTaskID (t , task2 .Id )
1224+ assert .Equal (t , "cancel-run-group" , run2 .ConcurrencyGroup )
1225+ assert .False (t , run2 .ConcurrencyCancel )
1226+ assert .Equal (t , actions_model .StatusRunning , run2 .Status )
1227+ })
1228+ }
1229+
11511230func getTaskAndJobAndRunByTaskID (t * testing.T , taskID int64 ) (* actions_model.ActionTask , * actions_model.ActionRunJob , * actions_model.ActionRun ) {
11521231 actionTask := unittest .AssertExistsAndLoadBean (t , & actions_model.ActionTask {ID : taskID })
11531232 actionRunJob := unittest .AssertExistsAndLoadBean (t , & actions_model.ActionRunJob {ID : actionTask .JobID })
0 commit comments