@@ -14,6 +14,7 @@ import (
14
14
"code.gitea.io/gitea/models/unittest"
15
15
user_model "code.gitea.io/gitea/models/user"
16
16
api "code.gitea.io/gitea/modules/structs"
17
+
17
18
"github.com/stretchr/testify/assert"
18
19
)
19
20
@@ -23,7 +24,7 @@ func TestWorkflowConcurrency_NoCancellation(t *testing.T) {
23
24
session := loginUser (t , user2 .Name )
24
25
token := getTokenForLoggedInUser (t , session , auth_model .AccessTokenScopeWriteRepository , auth_model .AccessTokenScopeWriteUser )
25
26
26
- apiRepo := createActionsTestRepo (t , token , "actions-download-task-logs " , false )
27
+ apiRepo := createActionsTestRepo (t , token , "actions-concurrency " , false )
27
28
repo := unittest .AssertExistsAndLoadBean (t , & repo_model.Repository {ID : apiRepo .ID })
28
29
runner := newMockRunner ()
29
30
runner .registerAsRepoRunner (t , user2 .Name , repo .Name , "mock-runner" , []string {"ubuntu-latest" })
@@ -126,3 +127,87 @@ jobs:
126
127
doAPIDeleteRepository (httpContext )(t )
127
128
})
128
129
}
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