Skip to content

Commit ed2d5f6

Browse files
author
Earl Warren
committed
Merge pull request '[v9.0/forgejo] fix: labels are missing in the pull request payload removing a label' (go-gitea#5834) from bp-v9.0/forgejo-c801838 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5834 Reviewed-by: Earl Warren <[email protected]>
2 parents 09a35a7 + eda6b43 commit ed2d5f6

File tree

2 files changed

+133
-56
lines changed

2 files changed

+133
-56
lines changed

models/issues/issue_label.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,7 @@ func ReplaceIssueLabels(ctx context.Context, issue *Issue, labels []*Label, doer
496496
}
497497
}
498498

499+
issue.isLabelsLoaded = false
499500
issue.Labels = nil
500501
if err = issue.LoadLabels(ctx); err != nil {
501502
return err

tests/integration/actions_trigger_test.go

Lines changed: 132 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,23 @@ jobs:
8484
baseGitRepo.Close()
8585
}()
8686

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
88104
testEditFileToNewBranch(t, session, "user2", "repo-pull-request", "main", "wip-something", "README.md", "Hello, world 1")
89105
testPullCreate(t, session, "user2", "repo-pull-request", true, "main", "wip-something", "Commit status PR")
90106
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{BaseRepoID: baseRepo.ID})
@@ -94,24 +110,15 @@ jobs:
94110
issueURL := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%s", "user2", "repo-pull-request", fmt.Sprintf("%d", pr.Issue.Index))
95111

96112
// 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)
106113
labelURL := fmt.Sprintf("%s/labels", issueURL)
107114

108115
// prepare the milestone
109116
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{
111118
Title: "mymilestone",
112119
State: "open",
113120
}).AddTokenAuth(token)
114-
resp = MakeRequest(t, req, http.StatusCreated)
121+
resp := MakeRequest(t, req, http.StatusCreated)
115122
milestone := new(api.Milestone)
116123
DecodeJSON(t, resp, &milestone)
117124

@@ -128,47 +135,97 @@ jobs:
128135
return false
129136
}
130137

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+
132153
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
138160
}{
139161
{
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,
143167
},
144168
{
145169
onType: "synchronize",
146170
doSomething: func() {
147171
testEditFile(t, session, "user2", "repo-pull-request", "wip-something", "README.md", "Hello, world 2")
148172
},
149-
action: api.HookIssueSynchronized,
173+
actionRunCount: 1,
174+
action: api.HookIssueSynchronized,
175+
assert: assertActionRuns,
150176
},
151177
{
152178
onType: "labeled",
153179
doSomething: func() {
154180
req := NewRequestWithJSON(t, "POST", labelURL, &api.IssueLabelsOption{
155-
Labels: []any{label.ID},
181+
Labels: []any{labels[0].ID, labels[1].ID},
156182
}).AddTokenAuth(token)
157183
MakeRequest(t, req, http.StatusOK)
158184
},
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+
},
161191
},
162192
{
163193
onType: "unlabeled",
164194
doSomething: func() {
165195
req := NewRequestWithJSON(t, "PUT", labelURL, &api.IssueLabelsOption{
166-
Labels: []any{},
196+
Labels: []any{labels[0].ID},
167197
}).AddTokenAuth(token)
168198
MakeRequest(t, req, http.StatusOK)
169199
},
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+
},
172229
},
173230
{
174231
onType: "assigned",
@@ -178,7 +235,9 @@ jobs:
178235
}).AddTokenAuth(token)
179236
MakeRequest(t, req, http.StatusCreated)
180237
},
181-
action: api.HookIssueAssigned,
238+
actionRunCount: 1,
239+
action: api.HookIssueAssigned,
240+
assert: assertActionRuns,
182241
},
183242
{
184243
onType: "unassigned",
@@ -188,7 +247,9 @@ jobs:
188247
}).AddTokenAuth(token)
189248
MakeRequest(t, req, http.StatusCreated)
190249
},
191-
action: api.HookIssueUnassigned,
250+
actionRunCount: 1,
251+
action: api.HookIssueUnassigned,
252+
assert: assertActionRuns,
192253
},
193254
{
194255
onType: "milestoned",
@@ -198,7 +259,9 @@ jobs:
198259
}).AddTokenAuth(token)
199260
MakeRequest(t, req, http.StatusCreated)
200261
},
201-
action: api.HookIssueMilestoned,
262+
actionRunCount: 1,
263+
action: api.HookIssueMilestoned,
264+
assert: assertActionRuns,
202265
},
203266
{
204267
onType: "demilestoned",
@@ -209,7 +272,9 @@ jobs:
209272
}).AddTokenAuth(token)
210273
MakeRequest(t, req, http.StatusCreated)
211274
},
212-
action: api.HookIssueDemilestoned,
275+
actionRunCount: 1,
276+
action: api.HookIssueDemilestoned,
277+
assert: assertActionRuns,
213278
},
214279
{
215280
onType: "closed",
@@ -219,7 +284,9 @@ jobs:
219284
err = issue_service.ChangeStatus(db.DefaultContext, pr.Issue, user2, sha, true)
220285
require.NoError(t, err)
221286
},
222-
action: api.HookIssueClosed,
287+
actionRunCount: 1,
288+
action: api.HookIssueClosed,
289+
assert: assertActionRuns,
223290
},
224291
{
225292
onType: "reopened",
@@ -229,43 +296,52 @@ jobs:
229296
err = issue_service.ChangeStatus(db.DefaultContext, pr.Issue, user2, sha, false)
230297
require.NoError(t, err)
231298
},
232-
action: api.HookIssueReOpened,
299+
actionRunCount: 1,
300+
action: api.HookIssueReOpened,
301+
assert: assertActionRuns,
233302
},
234303
} {
235304
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+
236313
// trigger the onType event
237314
testCase.doSomething()
238-
count++
315+
count := testCase.actionRunCount
239316
context := fmt.Sprintf("%[1]s / %[1]s (pull_request)", testCase.onType)
240317

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)
244325
}, 30*time.Second, 1*time.Second)
245326

246-
// verify the expected ActionRun was created
327+
// verify the expected ActionRuns were created
247328
sha, err := baseGitRepo.GetRefCommitID(pr.GetGitRefName())
248329
require.NoError(t, err)
249-
actionRun := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{RepoID: baseRepo.ID, WorkflowID: fmt.Sprintf("%s.yml", testCase.onType)})
250-
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)
256-
}
257-
require.NoError(t, err)
258-
assert.Equal(t, testCase.action, event.Action)
259-
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-
264330
// verify the commit status changes to CommitStatusSuccess when the job changes to StatusSuccess
265331
assert.True(t, checkCommitStatus(sha, context, api.CommitStatusPending))
266-
job.Status = actions_model.StatusSuccess
267-
actions_service.CreateCommitStatus(db.DefaultContext, job)
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)
336+
337+
// change the state of the job to success
338+
job.Status = actions_model.StatusSuccess
339+
actions_service.CreateCommitStatus(db.DefaultContext, job)
340+
}
341+
// verify the commit status changed to CommitStatusSuccess because the job(s) changed to StatusSuccess
268342
assert.True(t, checkCommitStatus(sha, context, api.CommitStatusSuccess))
343+
344+
testCase.assert(t, sha, testCase.onType, testCase.action, actionRuns)
269345
})
270346
}
271347
})

0 commit comments

Comments
 (0)