@@ -135,6 +135,228 @@ jobs:
135135 })
136136}
137137
138+ func TestWorkflowConcurrencyShort (t * testing.T ) {
139+ onGiteaRun (t , func (t * testing.T , u * url.URL ) {
140+ user2 := unittest .AssertExistsAndLoadBean (t , & user_model.User {ID : 2 })
141+ session := loginUser (t , user2 .Name )
142+ token := getTokenForLoggedInUser (t , session , auth_model .AccessTokenScopeWriteRepository , auth_model .AccessTokenScopeWriteUser )
143+
144+ apiRepo := createActionsTestRepo (t , token , "actions-concurrency" , false )
145+ repo := unittest .AssertExistsAndLoadBean (t , & repo_model.Repository {ID : apiRepo .ID })
146+ httpContext := NewAPITestContext (t , user2 .Name , repo .Name , auth_model .AccessTokenScopeWriteRepository )
147+ defer doAPIDeleteRepository (httpContext )(t )
148+
149+ runner := newMockRunner ()
150+ runner .registerAsRepoRunner (t , user2 .Name , repo .Name , "mock-runner" , []string {"ubuntu-latest" }, false )
151+
152+ // add a variable for test
153+ req := NewRequestWithJSON (t , "POST" ,
154+ fmt .Sprintf ("/api/v1/repos/%s/%s/actions/variables/myvar" , user2 .Name , repo .Name ), & api.CreateVariableOption {
155+ Value : "abc123" ,
156+ }).
157+ AddTokenAuth (token )
158+ MakeRequest (t , req , http .StatusCreated )
159+
160+ wf1TreePath := ".gitea/workflows/concurrent-workflow-1.yml"
161+ wf1FileContent := `name: concurrent-workflow-1
162+ on:
163+ push:
164+ paths:
165+ - '.gitea/workflows/concurrent-workflow-1.yml'
166+ concurrency: workflow-main-abc123-user2
167+ jobs:
168+ wf1-job:
169+ runs-on: ubuntu-latest
170+ steps:
171+ - run: echo 'job from workflow1'
172+ `
173+ wf2TreePath := ".gitea/workflows/concurrent-workflow-2.yml"
174+ wf2FileContent := `name: concurrent-workflow-2
175+ on:
176+ push:
177+ paths:
178+ - '.gitea/workflows/concurrent-workflow-2.yml'
179+ concurrency: workflow-${{ gitea.ref_name }}-${{ vars.myvar }}-${{ gitea.event.pusher.username }}
180+ jobs:
181+ wf2-job:
182+ runs-on: ubuntu-latest
183+ steps:
184+ - run: echo 'job from workflow2'
185+ `
186+ wf3TreePath := ".gitea/workflows/concurrent-workflow-3.yml"
187+ wf3FileContent := `name: concurrent-workflow-3
188+ on:
189+ push:
190+ paths:
191+ - '.gitea/workflows/concurrent-workflow-3.yml'
192+ concurrency: workflow-main-abc${{ 123 }}-${{ gitea.event.pusher.username }}
193+ jobs:
194+ wf3-job:
195+ runs-on: ubuntu-latest
196+ steps:
197+ - run: echo 'job from workflow3'
198+ `
199+ // push workflow1
200+ opts1 := getWorkflowCreateFileOptions (user2 , repo .DefaultBranch , "create " + wf1TreePath , wf1FileContent )
201+ createWorkflowFile (t , token , user2 .Name , repo .Name , wf1TreePath , opts1 )
202+ // fetch and exec workflow1
203+ task := runner .fetchTask (t )
204+ _ , _ , run := getTaskAndJobAndRunByTaskID (t , task .Id )
205+ assert .Equal (t , "workflow-main-abc123-user2" , run .ConcurrencyGroup )
206+ assert .Equal (t , "concurrent-workflow-1.yml" , run .WorkflowID )
207+ runner .fetchNoTask (t )
208+ runner .execTask (t , task , & mockTaskOutcome {
209+ result : runnerv1 .Result_RESULT_SUCCESS ,
210+ })
211+
212+ // push workflow2
213+ opts2 := getWorkflowCreateFileOptions (user2 , repo .DefaultBranch , "create " + wf2TreePath , wf2FileContent )
214+ createWorkflowFile (t , token , user2 .Name , repo .Name , wf2TreePath , opts2 )
215+ // fetch workflow2
216+ task = runner .fetchTask (t )
217+ _ , _ , run = getTaskAndJobAndRunByTaskID (t , task .Id )
218+ assert .Equal (t , "workflow-main-abc123-user2" , run .ConcurrencyGroup )
219+ assert .Equal (t , "concurrent-workflow-2.yml" , run .WorkflowID )
220+
221+ // push workflow3
222+ opts3 := getWorkflowCreateFileOptions (user2 , repo .DefaultBranch , "create " + wf3TreePath , wf3FileContent )
223+ createWorkflowFile (t , token , user2 .Name , repo .Name , wf3TreePath , opts3 )
224+ runner .fetchNoTask (t )
225+
226+ // exec workflow2
227+ runner .execTask (t , task , & mockTaskOutcome {
228+ result : runnerv1 .Result_RESULT_SUCCESS ,
229+ })
230+
231+ // fetch and exec workflow3
232+ task = runner .fetchTask (t )
233+ _ , _ , run = getTaskAndJobAndRunByTaskID (t , task .Id )
234+ assert .Equal (t , "workflow-main-abc123-user2" , run .ConcurrencyGroup )
235+ assert .Equal (t , "concurrent-workflow-3.yml" , run .WorkflowID )
236+ runner .fetchNoTask (t )
237+ runner .execTask (t , task , & mockTaskOutcome {
238+ result : runnerv1 .Result_RESULT_SUCCESS ,
239+ })
240+ })
241+ }
242+
243+ func TestWorkflowConcurrencyShortJson (t * testing.T ) {
244+ onGiteaRun (t , func (t * testing.T , u * url.URL ) {
245+ user2 := unittest .AssertExistsAndLoadBean (t , & user_model.User {ID : 2 })
246+ session := loginUser (t , user2 .Name )
247+ token := getTokenForLoggedInUser (t , session , auth_model .AccessTokenScopeWriteRepository , auth_model .AccessTokenScopeWriteUser )
248+
249+ apiRepo := createActionsTestRepo (t , token , "actions-concurrency" , false )
250+ repo := unittest .AssertExistsAndLoadBean (t , & repo_model.Repository {ID : apiRepo .ID })
251+ httpContext := NewAPITestContext (t , user2 .Name , repo .Name , auth_model .AccessTokenScopeWriteRepository )
252+ defer doAPIDeleteRepository (httpContext )(t )
253+
254+ runner := newMockRunner ()
255+ runner .registerAsRepoRunner (t , user2 .Name , repo .Name , "mock-runner" , []string {"ubuntu-latest" }, false )
256+
257+ // add a variable for test
258+ req := NewRequestWithJSON (t , "POST" ,
259+ fmt .Sprintf ("/api/v1/repos/%s/%s/actions/variables/myvar" , user2 .Name , repo .Name ), & api.CreateVariableOption {
260+ Value : "abc123" ,
261+ }).
262+ AddTokenAuth (token )
263+ MakeRequest (t , req , http .StatusCreated )
264+
265+ wf1TreePath := ".gitea/workflows/concurrent-workflow-1.yml"
266+ wf1FileContent := `name: concurrent-workflow-1
267+ on:
268+ push:
269+ paths:
270+ - '.gitea/workflows/concurrent-workflow-1.yml'
271+ concurrency: |-
272+ ${{ fromjson('{
273+ "group": "workflow-main-abc123-user2",
274+ "cancel-in-progress": false
275+ }') }}
276+ jobs:
277+ wf1-job:
278+ runs-on: ubuntu-latest
279+ steps:
280+ - run: echo 'job from workflow1'
281+ `
282+ wf2TreePath := ".gitea/workflows/concurrent-workflow-2.yml"
283+ wf2FileContent := `name: concurrent-workflow-2
284+ on:
285+ push:
286+ paths:
287+ - '.gitea/workflows/concurrent-workflow-2.yml'
288+ concurrency: |-
289+ ${{ fromjson('{
290+ "group": "workflow-main-abc123-user2",
291+ "cancel-in-progress": false
292+ }') }}
293+ jobs:
294+ wf2-job:
295+ runs-on: ubuntu-latest
296+ steps:
297+ - run: echo 'job from workflow2'
298+ `
299+ wf3TreePath := ".gitea/workflows/concurrent-workflow-3.yml"
300+ wf3FileContent := `name: concurrent-workflow-3
301+ on:
302+ push:
303+ paths:
304+ - '.gitea/workflows/concurrent-workflow-3.yml'
305+ concurrency: |-
306+ ${{ fromjson('{
307+ "group": "workflow-main-abc123-user2",
308+ "cancel-in-progress": false
309+ }') }}
310+ jobs:
311+ wf3-job:
312+ runs-on: ubuntu-latest
313+ steps:
314+ - run: echo 'job from workflow3'
315+ `
316+ // push workflow1
317+ opts1 := getWorkflowCreateFileOptions (user2 , repo .DefaultBranch , "create " + wf1TreePath , wf1FileContent )
318+ createWorkflowFile (t , token , user2 .Name , repo .Name , wf1TreePath , opts1 )
319+ // fetch and exec workflow1
320+ task := runner .fetchTask (t )
321+ _ , _ , run := getTaskAndJobAndRunByTaskID (t , task .Id )
322+ assert .Equal (t , "workflow-main-abc123-user2" , run .ConcurrencyGroup )
323+ assert .Equal (t , "concurrent-workflow-1.yml" , run .WorkflowID )
324+ runner .fetchNoTask (t )
325+ runner .execTask (t , task , & mockTaskOutcome {
326+ result : runnerv1 .Result_RESULT_SUCCESS ,
327+ })
328+
329+ // push workflow2
330+ opts2 := getWorkflowCreateFileOptions (user2 , repo .DefaultBranch , "create " + wf2TreePath , wf2FileContent )
331+ createWorkflowFile (t , token , user2 .Name , repo .Name , wf2TreePath , opts2 )
332+ // fetch workflow2
333+ task = runner .fetchTask (t )
334+ _ , _ , run = getTaskAndJobAndRunByTaskID (t , task .Id )
335+ assert .Equal (t , "workflow-main-abc123-user2" , run .ConcurrencyGroup )
336+ assert .Equal (t , "concurrent-workflow-2.yml" , run .WorkflowID )
337+
338+ // push workflow3
339+ opts3 := getWorkflowCreateFileOptions (user2 , repo .DefaultBranch , "create " + wf3TreePath , wf3FileContent )
340+ createWorkflowFile (t , token , user2 .Name , repo .Name , wf3TreePath , opts3 )
341+ runner .fetchNoTask (t )
342+
343+ // exec workflow2
344+ runner .execTask (t , task , & mockTaskOutcome {
345+ result : runnerv1 .Result_RESULT_SUCCESS ,
346+ })
347+
348+ // fetch and exec workflow3
349+ task = runner .fetchTask (t )
350+ _ , _ , run = getTaskAndJobAndRunByTaskID (t , task .Id )
351+ assert .Equal (t , "workflow-main-abc123-user2" , run .ConcurrencyGroup )
352+ assert .Equal (t , "concurrent-workflow-3.yml" , run .WorkflowID )
353+ runner .fetchNoTask (t )
354+ runner .execTask (t , task , & mockTaskOutcome {
355+ result : runnerv1 .Result_RESULT_SUCCESS ,
356+ })
357+ })
358+ }
359+
138360func TestPullRequestWorkflowConcurrency (t * testing.T ) {
139361 onGiteaRun (t , func (t * testing.T , u * url.URL ) {
140362 // user2 is the owner of the base repo
0 commit comments