@@ -21,7 +21,7 @@ import (
21
21
"github.com/stretchr/testify/assert"
22
22
)
23
23
24
- func TestWorkflowConcurrency_NoCancellation (t * testing.T ) {
24
+ func TestWorkflowConcurrency (t * testing.T ) {
25
25
onGiteaRun (t , func (t * testing.T , u * url.URL ) {
26
26
user2 := unittest .AssertExistsAndLoadBean (t , & user_model.User {ID : 2 })
27
27
session := loginUser (t , user2 .Name )
@@ -34,7 +34,7 @@ func TestWorkflowConcurrency_NoCancellation(t *testing.T) {
34
34
35
35
// add a variable for test
36
36
req := NewRequestWithJSON (t , "POST" ,
37
- fmt .Sprintf ("/api/v1/repos/%s/%s/actions/variables/qwe " , user2 .Name , repo .Name ), & api.CreateVariableOption {
37
+ fmt .Sprintf ("/api/v1/repos/%s/%s/actions/variables/myvar " , user2 .Name , repo .Name ), & api.CreateVariableOption {
38
38
Value : "abc123" ,
39
39
}).
40
40
AddTokenAuth (token )
61
61
paths:
62
62
- '.gitea/workflows/concurrent-workflow-2.yml'
63
63
concurrency:
64
- group: workflow-${{ github.ref_name }}-${{ vars.qwe }}
64
+ group: workflow-${{ github.ref_name }}-${{ vars.myvar }}
65
65
jobs:
66
66
wf2-job:
67
67
runs-on: ubuntu-latest
@@ -126,7 +126,7 @@ jobs:
126
126
})
127
127
}
128
128
129
- func TestWorkflowConcurrency_WithCancellation (t * testing.T ) {
129
+ func TestWorkflowConcurrency_WithPullRequest (t * testing.T ) {
130
130
onGiteaRun (t , func (t * testing.T , u * url.URL ) {
131
131
// user2 is the owner of the base repo
132
132
user2 := unittest .AssertExistsAndLoadBean (t , & user_model.User {ID : 2 })
@@ -276,6 +276,101 @@ jobs:
276
276
})
277
277
}
278
278
279
+ func TestJobConcurrency (t * testing.T ) {
280
+ onGiteaRun (t , func (t * testing.T , u * url.URL ) {
281
+ user2 := unittest .AssertExistsAndLoadBean (t , & user_model.User {ID : 2 })
282
+ session := loginUser (t , user2 .Name )
283
+ token := getTokenForLoggedInUser (t , session , auth_model .AccessTokenScopeWriteRepository , auth_model .AccessTokenScopeWriteUser )
284
+
285
+ apiRepo := createActionsTestRepo (t , token , "actions-concurrency" , false )
286
+ repo := unittest .AssertExistsAndLoadBean (t , & repo_model.Repository {ID : apiRepo .ID })
287
+ runner1 := newMockRunner ()
288
+ runner1 .registerAsRepoRunner (t , user2 .Name , repo .Name , "mock-runner-1" , []string {"runner1" })
289
+ runner2 := newMockRunner ()
290
+ runner2 .registerAsRepoRunner (t , user2 .Name , repo .Name , "mock-runner-2" , []string {"runner2" })
291
+
292
+ // add a variable for test
293
+ req := NewRequestWithJSON (t , "POST" ,
294
+ fmt .Sprintf ("/api/v1/repos/%s/%s/actions/variables/version_var" , user2 .Name , repo .Name ), & api.CreateVariableOption {
295
+ Value : "v1.23.0" ,
296
+ }).
297
+ AddTokenAuth (token )
298
+ MakeRequest (t , req , http .StatusNoContent )
299
+
300
+ wf1TreePath := ".gitea/workflows/concurrent-workflow-1.yml"
301
+ wf1FileContent := `name: concurrent-workflow-1
302
+ on:
303
+ push:
304
+ paths:
305
+ - '.gitea/workflows/concurrent-workflow-1.yml'
306
+ jobs:
307
+ wf1-job1:
308
+ runs-on: runner1
309
+ concurrency:
310
+ group: job-main-${{ vars.version_var }}
311
+ steps:
312
+ - run: echo 'wf1-job1'
313
+ `
314
+ wf2TreePath := ".gitea/workflows/concurrent-workflow-2.yml"
315
+ wf2FileContent := `name: concurrent-workflow-2
316
+ on:
317
+ push:
318
+ paths:
319
+ - '.gitea/workflows/concurrent-workflow-2.yml'
320
+ jobs:
321
+ wf2-job1:
322
+ runs-on: runner2
323
+ outputs:
324
+ version: ${{ steps.version_step.outputs.app_version }}
325
+ steps:
326
+ - id: version_step
327
+ run: echo "app_version=v1.23.0" >> "$GITHUB_OUTPUT"
328
+ wf2-job2:
329
+ runs-on: runner1
330
+ needs: [wf2-job1]
331
+ concurrency:
332
+ group: job-main-${{ needs.wf2-job1.outputs.version }}
333
+ steps:
334
+ - run: echo 'wf2-job2'
335
+ `
336
+
337
+ opts1 := getWorkflowCreateFileOptions (user2 , repo .DefaultBranch , fmt .Sprintf ("create %s" , wf1TreePath ), wf1FileContent )
338
+ createWorkflowFile (t , token , user2 .Name , repo .Name , wf1TreePath , opts1 )
339
+ opts2 := getWorkflowCreateFileOptions (user2 , repo .DefaultBranch , fmt .Sprintf ("create %s" , wf2TreePath ), wf2FileContent )
340
+ createWorkflowFile (t , token , user2 .Name , repo .Name , wf2TreePath , opts2 )
341
+ // opts3 := getWorkflowCreateFileOptions(user2, repo.DefaultBranch, fmt.Sprintf("create %s", wf3TreePath), wf3FileContent)
342
+ // createWorkflowFile(t, token, user2.Name, repo.Name, wf3TreePath, opts3)
343
+
344
+ // fetch wf1-job1
345
+ wf1Job1Task := runner1 .fetchTask (t )
346
+ _ , wf1Job1ActionJob , _ := getTaskAndJobAndRunByTaskID (t , wf1Job1Task .Id )
347
+ assert .Equal (t , "job-main-v1.23.0" , wf1Job1ActionJob .ConcurrencyGroup )
348
+ assert .True (t , wf1Job1ActionJob .Status .IsRunning ())
349
+ // fetch and exec wf2-job1
350
+ wf2Job1Task := runner2 .fetchTask (t )
351
+ runner2 .execTask (t , wf2Job1Task , & mockTaskOutcome {
352
+ result : runnerv1 .Result_RESULT_SUCCESS ,
353
+ outputs : map [string ]string {
354
+ "version" : "v1.23.0" ,
355
+ },
356
+ })
357
+ // cannot fetch wf2-job2 because wf1-job1 is running
358
+ runner1 .fetchNoTask (t )
359
+ // exec wf1-job1
360
+ runner1 .execTask (t , wf1Job1Task , & mockTaskOutcome {
361
+ result : runnerv1 .Result_RESULT_SUCCESS ,
362
+ })
363
+ // fetch wf2-job2
364
+ wf2Job2Task := runner2 .fetchTask (t )
365
+ _ , wf2Job2ActionJob , _ := getTaskAndJobAndRunByTaskID (t , wf2Job2Task .Id )
366
+ assert .Equal (t , "job-main-v1.23.0" , wf2Job2ActionJob .ConcurrencyGroup )
367
+ assert .True (t , wf1Job1ActionJob .Status .IsRunning ())
368
+
369
+ httpContext := NewAPITestContext (t , user2 .Name , repo .Name , auth_model .AccessTokenScopeWriteRepository )
370
+ doAPIDeleteRepository (httpContext )(t )
371
+ })
372
+ }
373
+
279
374
func getTaskAndJobAndRunByTaskID (t * testing.T , taskID int64 ) (* actions_model.ActionTask , * actions_model.ActionRunJob , * actions_model.ActionRun ) {
280
375
actionTask := unittest .AssertExistsAndLoadBean (t , & actions_model.ActionTask {ID : taskID })
281
376
actionRunJob := unittest .AssertExistsAndLoadBean (t , & actions_model.ActionRunJob {ID : actionTask .JobID })
0 commit comments