@@ -14,6 +14,7 @@ import (
1414 "code.gitea.io/gitea/models/unittest"
1515 user_model "code.gitea.io/gitea/models/user"
1616 api "code.gitea.io/gitea/modules/structs"
17+
1718 "github.com/stretchr/testify/assert"
1819)
1920
@@ -23,7 +24,7 @@ func TestWorkflowConcurrency_NoCancellation(t *testing.T) {
2324 session := loginUser (t , user2 .Name )
2425 token := getTokenForLoggedInUser (t , session , auth_model .AccessTokenScopeWriteRepository , auth_model .AccessTokenScopeWriteUser )
2526
26- apiRepo := createActionsTestRepo (t , token , "actions-download-task-logs " , false )
27+ apiRepo := createActionsTestRepo (t , token , "actions-concurrency " , false )
2728 repo := unittest .AssertExistsAndLoadBean (t , & repo_model.Repository {ID : apiRepo .ID })
2829 runner := newMockRunner ()
2930 runner .registerAsRepoRunner (t , user2 .Name , repo .Name , "mock-runner" , []string {"ubuntu-latest" })
@@ -126,3 +127,87 @@ jobs:
126127 doAPIDeleteRepository (httpContext )(t )
127128 })
128129}
130+
131+ func TestWorkflowConcurrency_WithCancellation (t * testing.T ) {
132+ onGiteaRun (t , func (t * testing.T , u * url.URL ) {
133+ user2 := unittest .AssertExistsAndLoadBean (t , & user_model.User {ID : 2 })
134+ session := loginUser (t , user2 .Name )
135+ token := getTokenForLoggedInUser (t , session , auth_model .AccessTokenScopeWriteRepository , auth_model .AccessTokenScopeWriteUser )
136+
137+ apiRepo := createActionsTestRepo (t , token , "actions-concurrency" , false )
138+ repo := unittest .AssertExistsAndLoadBean (t , & repo_model.Repository {ID : apiRepo .ID })
139+ runner := newMockRunner ()
140+ runner .registerAsRepoRunner (t , user2 .Name , repo .Name , "mock-runner" , []string {"ubuntu-latest" })
141+
142+ req := NewRequestWithJSON (t , "POST" ,
143+ fmt .Sprintf ("/api/v1/repos/%s/%s/actions/variables/qwe" , user2 .Name , repo .Name ), & api.CreateVariableOption {
144+ Value : "abc123" ,
145+ }).
146+ AddTokenAuth (token )
147+ MakeRequest (t , req , http .StatusNoContent )
148+
149+ wf1TreePath := ".gitea/workflows/concurrent-workflow-1.yml"
150+ wf1FileContent := `name: concurrent-workflow-1
151+ on:
152+ push:
153+ paths:
154+ - '.gitea/workflows/concurrent-workflow-1.yml'
155+ concurrency:
156+ group: workflow-main-abc123
157+ jobs:
158+ wf1-job:
159+ runs-on: ubuntu-latest
160+ steps:
161+ - run: echo 'job from workflow1'
162+ `
163+ wf2TreePath := ".gitea/workflows/concurrent-workflow-2.yml"
164+ wf2FileContent := `name: concurrent-workflow-2
165+ on:
166+ push:
167+ paths:
168+ - '.gitea/workflows/concurrent-workflow-2.yml'
169+ concurrency:
170+ group: workflow-${{ github.ref_name }}-${{ vars.qwe }}
171+ cancel-in-progress: ${{ github.ref_name == 'main' }}
172+ jobs:
173+ wf2-job:
174+ runs-on: ubuntu-latest
175+ steps:
176+ - run: echo 'job from workflow2'
177+ `
178+
179+ // push workflow1
180+ opts1 := getWorkflowCreateFileOptions (user2 , repo .DefaultBranch , fmt .Sprintf ("create %s" , wf1TreePath ), wf1FileContent )
181+ createWorkflowFile (t , token , user2 .Name , repo .Name , wf1TreePath , opts1 )
182+ // fetch the task of workflow1
183+ task1 := runner .fetchTask (t )
184+ actionTask1 := unittest .AssertExistsAndLoadBean (t , & actions_model.ActionTask {ID : task1 .Id })
185+ actionRunJob1 := unittest .AssertExistsAndLoadBean (t , & actions_model.ActionRunJob {ID : actionTask1 .JobID })
186+ actionRun1 := unittest .AssertExistsAndLoadBean (t , & actions_model.ActionRun {ID : actionRunJob1 .RunID })
187+ assert .Equal (t , "workflow-main-abc123" , actionRun1 .ConcurrencyGroup )
188+ assert .Equal (t , "concurrent-workflow-1.yml" , actionRun1 .WorkflowID )
189+ assert .False (t , actionRun1 .ConcurrencyCancel )
190+ assert .True (t , actionRun1 .Status .IsRunning ())
191+
192+ // push workflow2
193+ opts2 := getWorkflowCreateFileOptions (user2 , repo .DefaultBranch , fmt .Sprintf ("create %s" , wf2TreePath ), wf2FileContent )
194+ createWorkflowFile (t , token , user2 .Name , repo .Name , wf2TreePath , opts2 )
195+ // fetch the task of workflow2
196+ task2 := runner .fetchTask (t )
197+ actionTask2 := unittest .AssertExistsAndLoadBean (t , & actions_model.ActionTask {ID : task2 .Id })
198+ actionRunJob2 := unittest .AssertExistsAndLoadBean (t , & actions_model.ActionRunJob {ID : actionTask2 .JobID })
199+ actionRun2 := unittest .AssertExistsAndLoadBean (t , & actions_model.ActionRun {ID : actionRunJob2 .RunID })
200+ assert .Equal (t , "workflow-main-abc123" , actionRun2 .ConcurrencyGroup )
201+ assert .Equal (t , "concurrent-workflow-2.yml" , actionRun2 .WorkflowID )
202+ assert .True (t , actionRun2 .ConcurrencyCancel )
203+ assert .True (t , actionRun2 .Status .IsRunning ())
204+
205+ // after pushing workflow2, the status of the run of workflow1 should be "cancelled"
206+ // fetch the last workflow (workflow2 or workflow3)
207+ actionRun1 = unittest .AssertExistsAndLoadBean (t , & actions_model.ActionRun {ID : actionRunJob1 .RunID })
208+ assert .True (t , actionRun1 .Status .IsCancelled ())
209+
210+ httpContext := NewAPITestContext (t , user2 .Name , repo .Name , auth_model .AccessTokenScopeWriteRepository )
211+ doAPIDeleteRepository (httpContext )(t )
212+ })
213+ }
0 commit comments