loading up the forgejo repo on tangled to test page performance
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request 'fix: labels are missing in the pull request payload removing a label' (#5831) from earl-warren/forgejo:wip-unlabeled into forgejo

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5831
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>

+133 -56
+1
models/issues/issue_label.go
··· 496 496 } 497 497 } 498 498 499 + issue.isLabelsLoaded = false 499 500 issue.Labels = nil 500 501 if err = issue.LoadLabels(ctx); err != nil { 501 502 return err
+132 -56
tests/integration/actions_trigger_test.go
··· 84 84 baseGitRepo.Close() 85 85 }() 86 86 87 - // prepare the pull request 87 + // prepare the repository labels 88 + labelStr := "/api/v1/repos/user2/repo-pull-request/labels" 89 + labelsCount := 2 90 + labels := make([]*api.Label, labelsCount) 91 + for i := 0; i < labelsCount; i++ { 92 + color := "abcdef" 93 + req := NewRequestWithJSON(t, "POST", labelStr, &api.CreateLabelOption{ 94 + Name: fmt.Sprintf("label%d", i), 95 + Color: color, 96 + }).AddTokenAuth(token) 97 + resp := MakeRequest(t, req, http.StatusCreated) 98 + labels[i] = new(api.Label) 99 + DecodeJSON(t, resp, &labels[i]) 100 + assert.Equal(t, color, labels[i].Color) 101 + } 102 + 103 + // create the pull request 88 104 testEditFileToNewBranch(t, session, "user2", "repo-pull-request", "main", "wip-something", "README.md", "Hello, world 1") 89 105 testPullCreate(t, session, "user2", "repo-pull-request", true, "main", "wip-something", "Commit status PR") 90 106 pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{BaseRepoID: baseRepo.ID}) ··· 94 110 issueURL := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%s", "user2", "repo-pull-request", fmt.Sprintf("%d", pr.Issue.Index)) 95 111 96 112 // prepare the labels 97 - labelStr := "/api/v1/repos/user2/repo-pull-request/labels" 98 - req := NewRequestWithJSON(t, "POST", labelStr, &api.CreateLabelOption{ 99 - Name: "mylabel", 100 - Color: "abcdef", 101 - Description: "description mylabel", 102 - }).AddTokenAuth(token) 103 - resp := MakeRequest(t, req, http.StatusCreated) 104 - label := new(api.Label) 105 - DecodeJSON(t, resp, &label) 106 113 labelURL := fmt.Sprintf("%s/labels", issueURL) 107 114 108 115 // prepare the milestone 109 116 milestoneStr := "/api/v1/repos/user2/repo-pull-request/milestones" 110 - req = NewRequestWithJSON(t, "POST", milestoneStr, &api.CreateMilestoneOption{ 117 + req := NewRequestWithJSON(t, "POST", milestoneStr, &api.CreateMilestoneOption{ 111 118 Title: "mymilestone", 112 119 State: "open", 113 120 }).AddTokenAuth(token) 114 - resp = MakeRequest(t, req, http.StatusCreated) 121 + resp := MakeRequest(t, req, http.StatusCreated) 115 122 milestone := new(api.Milestone) 116 123 DecodeJSON(t, resp, &milestone) 117 124 ··· 128 135 return false 129 136 } 130 137 131 - count := 0 138 + assertActionRun := func(t *testing.T, sha, onType string, action api.HookIssueAction, actionRun *actions_model.ActionRun) { 139 + assert.Equal(t, fmt.Sprintf("%s.yml", onType), actionRun.WorkflowID) 140 + assert.Equal(t, sha, actionRun.CommitSHA) 141 + assert.Equal(t, actions_module.GithubEventPullRequest, actionRun.TriggerEvent) 142 + event, err := actionRun.GetPullRequestEventPayload() 143 + require.NoError(t, err) 144 + assert.Equal(t, action, event.Action) 145 + } 146 + 147 + type assertType func(t *testing.T, sha, onType string, action api.HookIssueAction, actionRuns []*actions_model.ActionRun) 148 + assertActionRuns := func(t *testing.T, sha, onType string, action api.HookIssueAction, actionRuns []*actions_model.ActionRun) { 149 + require.Len(t, actionRuns, 1) 150 + assertActionRun(t, sha, onType, action, actionRuns[0]) 151 + } 152 + 132 153 for _, testCase := range []struct { 133 - onType string 134 - jobID string 135 - doSomething func() 136 - action api.HookIssueAction 137 - hasLabel bool 154 + onType string 155 + jobID string 156 + doSomething func() 157 + actionRunCount int 158 + action api.HookIssueAction 159 + assert assertType 138 160 }{ 139 161 { 140 - onType: "opened", 141 - doSomething: func() {}, 142 - action: api.HookIssueOpened, 162 + onType: "opened", 163 + doSomething: func() {}, 164 + actionRunCount: 1, 165 + action: api.HookIssueOpened, 166 + assert: assertActionRuns, 143 167 }, 144 168 { 145 169 onType: "synchronize", 146 170 doSomething: func() { 147 171 testEditFile(t, session, "user2", "repo-pull-request", "wip-something", "README.md", "Hello, world 2") 148 172 }, 149 - action: api.HookIssueSynchronized, 173 + actionRunCount: 1, 174 + action: api.HookIssueSynchronized, 175 + assert: assertActionRuns, 150 176 }, 151 177 { 152 178 onType: "labeled", 153 179 doSomething: func() { 154 180 req := NewRequestWithJSON(t, "POST", labelURL, &api.IssueLabelsOption{ 155 - Labels: []any{label.ID}, 181 + Labels: []any{labels[0].ID, labels[1].ID}, 156 182 }).AddTokenAuth(token) 157 183 MakeRequest(t, req, http.StatusOK) 158 184 }, 159 - action: api.HookIssueLabelUpdated, 160 - hasLabel: true, 185 + actionRunCount: 2, 186 + action: api.HookIssueLabelUpdated, 187 + assert: func(t *testing.T, sha, onType string, action api.HookIssueAction, actionRuns []*actions_model.ActionRun) { 188 + assertActionRun(t, sha, onType, api.HookIssueLabelUpdated, actionRuns[0]) 189 + assertActionRun(t, sha, onType, api.HookIssueLabelUpdated, actionRuns[1]) 190 + }, 161 191 }, 162 192 { 163 193 onType: "unlabeled", 164 194 doSomething: func() { 165 195 req := NewRequestWithJSON(t, "PUT", labelURL, &api.IssueLabelsOption{ 166 - Labels: []any{}, 196 + Labels: []any{labels[0].ID}, 167 197 }).AddTokenAuth(token) 168 198 MakeRequest(t, req, http.StatusOK) 169 199 }, 170 - action: api.HookIssueLabelCleared, 171 - hasLabel: true, 200 + actionRunCount: 3, 201 + action: api.HookIssueLabelCleared, 202 + assert: func(t *testing.T, sha, onType string, action api.HookIssueAction, actionRuns []*actions_model.ActionRun) { 203 + foundPayloadWithLabels := false 204 + knownLabels := []string{"label0", "label1"} 205 + for _, actionRun := range actionRuns { 206 + assert.Equal(t, sha, actionRun.CommitSHA) 207 + assert.Equal(t, actions_module.GithubEventPullRequest, actionRun.TriggerEvent) 208 + event, err := actionRun.GetPullRequestEventPayload() 209 + require.NoError(t, err) 210 + switch event.Action { 211 + case api.HookIssueLabelUpdated: 212 + assert.Equal(t, "labeled.yml", actionRun.WorkflowID) 213 + assert.Equal(t, "label0", event.Label.Name) 214 + require.Len(t, event.PullRequest.Labels, 1) 215 + assert.Contains(t, "label0", event.PullRequest.Labels[0].Name) 216 + case api.HookIssueLabelCleared: 217 + assert.Equal(t, "unlabeled.yml", actionRun.WorkflowID) 218 + assert.Contains(t, knownLabels, event.Label.Name) 219 + if len(event.PullRequest.Labels) > 0 { 220 + foundPayloadWithLabels = true 221 + assert.Contains(t, knownLabels, event.PullRequest.Labels[0].Name) 222 + } 223 + default: 224 + require.Fail(t, fmt.Sprintf("unexpected action '%s'", event.Action)) 225 + } 226 + } 227 + assert.True(t, foundPayloadWithLabels, "expected at least one clear label payload with non empty labels") 228 + }, 172 229 }, 173 230 { 174 231 onType: "assigned", ··· 178 235 }).AddTokenAuth(token) 179 236 MakeRequest(t, req, http.StatusCreated) 180 237 }, 181 - action: api.HookIssueAssigned, 238 + actionRunCount: 1, 239 + action: api.HookIssueAssigned, 240 + assert: assertActionRuns, 182 241 }, 183 242 { 184 243 onType: "unassigned", ··· 188 247 }).AddTokenAuth(token) 189 248 MakeRequest(t, req, http.StatusCreated) 190 249 }, 191 - action: api.HookIssueUnassigned, 250 + actionRunCount: 1, 251 + action: api.HookIssueUnassigned, 252 + assert: assertActionRuns, 192 253 }, 193 254 { 194 255 onType: "milestoned", ··· 198 259 }).AddTokenAuth(token) 199 260 MakeRequest(t, req, http.StatusCreated) 200 261 }, 201 - action: api.HookIssueMilestoned, 262 + actionRunCount: 1, 263 + action: api.HookIssueMilestoned, 264 + assert: assertActionRuns, 202 265 }, 203 266 { 204 267 onType: "demilestoned", ··· 209 272 }).AddTokenAuth(token) 210 273 MakeRequest(t, req, http.StatusCreated) 211 274 }, 212 - action: api.HookIssueDemilestoned, 275 + actionRunCount: 1, 276 + action: api.HookIssueDemilestoned, 277 + assert: assertActionRuns, 213 278 }, 214 279 { 215 280 onType: "closed", ··· 219 284 err = issue_service.ChangeStatus(db.DefaultContext, pr.Issue, user2, sha, true) 220 285 require.NoError(t, err) 221 286 }, 222 - action: api.HookIssueClosed, 287 + actionRunCount: 1, 288 + action: api.HookIssueClosed, 289 + assert: assertActionRuns, 223 290 }, 224 291 { 225 292 onType: "reopened", ··· 229 296 err = issue_service.ChangeStatus(db.DefaultContext, pr.Issue, user2, sha, false) 230 297 require.NoError(t, err) 231 298 }, 232 - action: api.HookIssueReOpened, 299 + actionRunCount: 1, 300 + action: api.HookIssueReOpened, 301 + assert: assertActionRuns, 233 302 }, 234 303 } { 235 304 t.Run(testCase.onType, func(t *testing.T) { 305 + defer func() { 306 + // cleanup leftovers, start from scratch 307 + _, err = db.DeleteByBean(db.DefaultContext, actions_model.ActionRun{RepoID: baseRepo.ID}) 308 + require.NoError(t, err) 309 + _, err = db.DeleteByBean(db.DefaultContext, actions_model.ActionRunJob{RepoID: baseRepo.ID}) 310 + require.NoError(t, err) 311 + }() 312 + 236 313 // trigger the onType event 237 314 testCase.doSomething() 238 - count++ 315 + count := testCase.actionRunCount 239 316 context := fmt.Sprintf("%[1]s / %[1]s (pull_request)", testCase.onType) 240 317 241 - // wait for a new ActionRun to be created 242 - assert.Eventually(t, func() bool { 243 - return count == unittest.GetCount(t, &actions_model.ActionRun{RepoID: baseRepo.ID}) 318 + var actionRuns []*actions_model.ActionRun 319 + 320 + // wait for ActionRun(s) to be created 321 + require.Eventually(t, func() bool { 322 + actionRuns = make([]*actions_model.ActionRun, 0) 323 + require.NoError(t, db.GetEngine(db.DefaultContext).Where("repo_id=?", baseRepo.ID).Find(&actionRuns)) 324 + return assert.Len(t, actionRuns, count) 244 325 }, 30*time.Second, 1*time.Second) 245 326 246 - // verify the expected ActionRun was created 327 + // verify the expected ActionRuns were created 247 328 sha, err := baseGitRepo.GetRefCommitID(pr.GetGitRefName()) 248 329 require.NoError(t, err) 249 - actionRun := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{RepoID: baseRepo.ID, WorkflowID: fmt.Sprintf("%s.yml", testCase.onType)}) 330 + // verify the commit status changes to CommitStatusSuccess when the job changes to StatusSuccess 331 + assert.True(t, checkCommitStatus(sha, context, api.CommitStatusPending)) 332 + for _, actionRun := range actionRuns { 333 + // verify the expected ActionRunJob was created and is StatusWaiting 334 + job := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunJob{RunID: actionRun.ID, CommitSHA: sha}) 335 + assert.Equal(t, actions_model.StatusWaiting, job.Status) 250 336 251 - assert.Equal(t, sha, actionRun.CommitSHA) 252 - assert.Equal(t, actions_module.GithubEventPullRequest, actionRun.TriggerEvent) 253 - event, err := actionRun.GetPullRequestEventPayload() 254 - if testCase.hasLabel { 255 - assert.NotNil(t, event.Label) 337 + // change the state of the job to success 338 + job.Status = actions_model.StatusSuccess 339 + actions_service.CreateCommitStatus(db.DefaultContext, job) 256 340 } 257 - require.NoError(t, err) 258 - assert.Equal(t, testCase.action, event.Action) 341 + // verify the commit status changed to CommitStatusSuccess because the job(s) changed to StatusSuccess 342 + assert.True(t, checkCommitStatus(sha, context, api.CommitStatusSuccess)) 259 343 260 - // verify the expected ActionRunJob was created and is StatusWaiting 261 - job := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunJob{JobID: testCase.onType, CommitSHA: sha}) 262 - assert.Equal(t, actions_model.StatusWaiting, job.Status) 263 - 264 - // verify the commit status changes to CommitStatusSuccess when the job changes to StatusSuccess 265 - assert.True(t, checkCommitStatus(sha, context, api.CommitStatusPending)) 266 - job.Status = actions_model.StatusSuccess 267 - actions_service.CreateCommitStatus(db.DefaultContext, job) 268 - assert.True(t, checkCommitStatus(sha, context, api.CommitStatusSuccess)) 344 + testCase.assert(t, sha, testCase.onType, testCase.action, actionRuns) 269 345 }) 270 346 } 271 347 })