aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGiteabot <teabot@gitea.io>2025-05-12 21:26:31 +0800
committerGitHub <noreply@github.com>2025-05-12 15:26:31 +0200
commitec146b420044d7a57458955a6aa33d9da0dd2373 (patch)
tree8dc8506246f646f7e1a194cf535c1aceb60afcf6
parent51fa86f0fa4f46ab84f7ff8b8f7660bb8f08b495 (diff)
downloadgitea-ec146b420044d7a57458955a6aa33d9da0dd2373.tar.gz
gitea-ec146b420044d7a57458955a6aa33d9da0dd2373.zip
Fix bug webhook milestone is not right. (#34419) (#34429)
Backport #34419 by @lunny Fix #34400 --------- Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: silverwind <me@silverwind.io>
-rw-r--r--routers/api/v1/repo/issue.go9
-rw-r--r--routers/api/v1/repo/pull.go5
-rw-r--r--routers/web/repo/issue.go10
-rw-r--r--tests/integration/issue_test.go9
-rw-r--r--tests/integration/repo_webhook_test.go72
5 files changed, 105 insertions, 0 deletions
diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go
index cbe709c030..da949a56fd 100644
--- a/routers/api/v1/repo/issue.go
+++ b/routers/api/v1/repo/issue.go
@@ -895,6 +895,15 @@ func EditIssue(ctx *context.APIContext) {
issue.MilestoneID != *form.Milestone {
oldMilestoneID := issue.MilestoneID
issue.MilestoneID = *form.Milestone
+ if issue.MilestoneID > 0 {
+ issue.Milestone, err = issues_model.GetMilestoneByRepoID(ctx, ctx.Repo.Repository.ID, *form.Milestone)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "GetMilestoneByRepoID", err)
+ return
+ }
+ } else {
+ issue.Milestone = nil
+ }
if err = issue_service.ChangeMilestoneAssign(ctx, issue, ctx.Doer, oldMilestoneID); err != nil {
ctx.Error(http.StatusInternalServerError, "ChangeMilestoneAssign", err)
return
diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go
index 75db2bd55b..cb6479e097 100644
--- a/routers/api/v1/repo/pull.go
+++ b/routers/api/v1/repo/pull.go
@@ -694,6 +694,11 @@ func EditPullRequest(ctx *context.APIContext) {
issue.MilestoneID != form.Milestone {
oldMilestoneID := issue.MilestoneID
issue.MilestoneID = form.Milestone
+ issue.Milestone, err = issues_model.GetMilestoneByRepoID(ctx, ctx.Repo.Repository.ID, form.Milestone)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "GetMilestoneByRepoID", err)
+ return
+ }
if err = issue_service.ChangeMilestoneAssign(ctx, issue, ctx.Doer, oldMilestoneID); err != nil {
ctx.Error(http.StatusInternalServerError, "ChangeMilestoneAssign", err)
return
diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go
index 5397411b59..93f57b6dc5 100644
--- a/routers/web/repo/issue.go
+++ b/routers/web/repo/issue.go
@@ -418,6 +418,16 @@ func UpdateIssueMilestone(ctx *context.Context) {
continue
}
issue.MilestoneID = milestoneID
+ if milestoneID > 0 {
+ var err error
+ issue.Milestone, err = issues_model.GetMilestoneByRepoID(ctx, ctx.Repo.Repository.ID, milestoneID)
+ if err != nil {
+ ctx.ServerError("GetMilestoneByRepoID", err)
+ return
+ }
+ } else {
+ issue.Milestone = nil
+ }
if err := issue_service.ChangeMilestoneAssign(ctx, issue, ctx.Doer, oldMilestoneID); err != nil {
ctx.ServerError("ChangeMilestoneAssign", err)
return
diff --git a/tests/integration/issue_test.go b/tests/integration/issue_test.go
index bd0cedd300..065a220406 100644
--- a/tests/integration/issue_test.go
+++ b/tests/integration/issue_test.go
@@ -185,6 +185,15 @@ func testIssueAddComment(t *testing.T, session *TestSession, issueURL, content,
return int64(id)
}
+func testIssueChangeMilestone(t *testing.T, session *TestSession, repoLink string, issueID, milestoneID int64) {
+ req := NewRequestWithValues(t, "POST", fmt.Sprintf(repoLink+"/issues/milestone?issue_ids=%d", issueID), map[string]string{
+ "_csrf": GetUserCSRFToken(t, session),
+ "id": strconv.FormatInt(milestoneID, 10),
+ })
+ resp := session.MakeRequest(t, req, http.StatusOK)
+ assert.Equal(t, `{"ok":true}`, strings.TrimSpace(resp.Body.String()))
+}
+
func TestNewIssue(t *testing.T) {
defer tests.PrepareTestEnv(t)()
session := loginUser(t, "user2")
diff --git a/tests/integration/repo_webhook_test.go b/tests/integration/repo_webhook_test.go
index 0952263968..76565e3c45 100644
--- a/tests/integration/repo_webhook_test.go
+++ b/tests/integration/repo_webhook_test.go
@@ -353,6 +353,78 @@ func Test_WebhookIssue(t *testing.T) {
})
}
+func Test_WebhookIssueMilestone(t *testing.T) {
+ var payloads []api.IssuePayload
+ var triggeredEvent string
+ provider := newMockWebhookProvider(func(r *http.Request) {
+ content, _ := io.ReadAll(r.Body)
+ var payload api.IssuePayload
+ err := json.Unmarshal(content, &payload)
+ assert.NoError(t, err)
+ payloads = append(payloads, payload)
+ triggeredEvent = "issues"
+ }, http.StatusOK)
+ defer provider.Close()
+
+ onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
+ // create a new webhook with special webhook for repo1
+ session := loginUser(t, "user2")
+ repo1 := unittest.AssertExistsAndLoadBean(t, &repo.Repository{ID: 1})
+ testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "issue_milestone")
+
+ t.Run("assign a milestone", func(t *testing.T) {
+ // trigger the webhook
+ testIssueChangeMilestone(t, session, repo1.Link(), 1, 1)
+
+ // validate the webhook is triggered
+ assert.Equal(t, "issues", triggeredEvent)
+ assert.Len(t, payloads, 1)
+ assert.Equal(t, "milestoned", string(payloads[0].Action))
+ assert.Equal(t, "repo1", payloads[0].Issue.Repo.Name)
+ assert.Equal(t, "user2/repo1", payloads[0].Issue.Repo.FullName)
+ assert.Equal(t, "issue1", payloads[0].Issue.Title)
+ assert.Equal(t, "content for the first issue", payloads[0].Issue.Body)
+ assert.EqualValues(t, 1, payloads[0].Issue.Milestone.ID)
+ })
+
+ t.Run("change a milestong", func(t *testing.T) {
+ // trigger the webhook again
+ triggeredEvent = ""
+ payloads = make([]api.IssuePayload, 0, 1)
+ // change milestone to 2
+ testIssueChangeMilestone(t, session, repo1.Link(), 1, 2)
+
+ // validate the webhook is triggered
+ assert.Equal(t, "issues", triggeredEvent)
+ assert.Len(t, payloads, 1)
+ assert.Equal(t, "milestoned", string(payloads[0].Action))
+ assert.Equal(t, "repo1", payloads[0].Issue.Repo.Name)
+ assert.Equal(t, "user2/repo1", payloads[0].Issue.Repo.FullName)
+ assert.Equal(t, "issue1", payloads[0].Issue.Title)
+ assert.Equal(t, "content for the first issue", payloads[0].Issue.Body)
+ assert.EqualValues(t, 2, payloads[0].Issue.Milestone.ID)
+ })
+
+ t.Run("remove a milestone", func(t *testing.T) {
+ // trigger the webhook again
+ triggeredEvent = ""
+ payloads = make([]api.IssuePayload, 0, 1)
+ // change milestone to 0
+ testIssueChangeMilestone(t, session, repo1.Link(), 1, 0)
+
+ // validate the webhook is triggered
+ assert.Equal(t, "issues", triggeredEvent)
+ assert.Len(t, payloads, 1)
+ assert.Equal(t, "demilestoned", string(payloads[0].Action))
+ assert.Equal(t, "repo1", payloads[0].Issue.Repo.Name)
+ assert.Equal(t, "user2/repo1", payloads[0].Issue.Repo.FullName)
+ assert.Equal(t, "issue1", payloads[0].Issue.Title)
+ assert.Equal(t, "content for the first issue", payloads[0].Issue.Body)
+ assert.Nil(t, payloads[0].Issue.Milestone)
+ })
+ })
+}
+
func Test_WebhookPullRequest(t *testing.T) {
var payloads []api.PullRequestPayload
var triggeredEvent string