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 '[gitea] webhooks openproject compatible (gitea#28435)' (#4027) from oliverpool/forgejo:gitea-cp-28435 into forgejo

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/4027
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>

+150 -23
+15
models/issues/pull.go
··· 431 431 return fmt.Sprintf("%s%s", git.BranchPrefix, pr.HeadBranch) 432 432 } 433 433 434 + // GetReviewCommentsCount returns the number of review comments made on the diff of a PR review (not including comments on commits or issues in a PR) 435 + func (pr *PullRequest) GetReviewCommentsCount(ctx context.Context) int { 436 + opts := FindCommentsOptions{ 437 + Type: CommentTypeReview, 438 + IssueID: pr.IssueID, 439 + } 440 + conds := opts.ToConds() 441 + 442 + count, err := db.GetEngine(ctx).Where(conds).Count(new(Comment)) 443 + if err != nil { 444 + return 0 445 + } 446 + return int(count) 447 + } 448 + 434 449 // IsChecking returns true if this pull request is still checking conflict. 435 450 func (pr *PullRequest) IsChecking() bool { 436 451 return pr.Status == PullRequestStatusChecking
+1
modules/structs/issue.go
··· 30 30 HasMerged bool `json:"merged"` 31 31 Merged *time.Time `json:"merged_at"` 32 32 IsWorkInProgress bool `json:"draft"` 33 + HTMLURL string `json:"html_url"` 33 34 } 34 35 35 36 // RepositoryMeta basic repository information
+6
modules/structs/pull.go
··· 21 21 Assignees []*User `json:"assignees"` 22 22 RequestedReviewers []*User `json:"requested_reviewers"` 23 23 State StateType `json:"state"` 24 + Draft bool `json:"draft"` 24 25 IsLocked bool `json:"is_locked"` 25 26 Comments int `json:"comments"` 27 + // number of review comments made on the diff of a PR review (not including comments on commits or issues in a PR) 28 + ReviewComments int `json:"review_comments"` 29 + Additions int `json:"additions"` 30 + Deletions int `json:"deletions"` 31 + ChangedFiles int `json:"changed_files"` 26 32 27 33 HTMLURL string `json:"html_url"` 28 34 DiffURL string `json:"diff_url"`
+2
modules/structs/user.go
··· 27 27 Email string `json:"email"` 28 28 // URL to the user's avatar 29 29 AvatarURL string `json:"avatar_url"` 30 + // URL to the user's gitea page 31 + HTMLURL string `json:"html_url"` 30 32 // User locale 31 33 Language string `json:"language"` 32 34 // Is the user an administrator
+1
release-notes/8.0.0/feat/4027.md
··· 1 + - Gitea/Forgejo webhook payload include additional fields (`html_url`, `additions`, `deletions`, `review_comments`...) for better compatbility with [OpenProject](https://www.openproject.org/), ported from [gitea#28435](https://github.com/go-gitea/gitea/pull/28435).
+2
services/convert/issue.go
··· 107 107 if issue.PullRequest.HasMerged { 108 108 apiIssue.PullRequest.Merged = issue.PullRequest.MergedUnix.AsTimePtr() 109 109 } 110 + // Add pr's html url 111 + apiIssue.PullRequest.HTMLURL = issue.HTMLURL() 110 112 } 111 113 } 112 114 if issue.DeadlineUnix != 0 {
+41 -23
services/convert/pull.go
··· 61 61 } 62 62 63 63 apiPullRequest := &api.PullRequest{ 64 - ID: pr.ID, 65 - URL: pr.Issue.HTMLURL(), 66 - Index: pr.Index, 67 - Poster: apiIssue.Poster, 68 - Title: apiIssue.Title, 69 - Body: apiIssue.Body, 70 - Labels: apiIssue.Labels, 71 - Milestone: apiIssue.Milestone, 72 - Assignee: apiIssue.Assignee, 73 - Assignees: apiIssue.Assignees, 74 - State: apiIssue.State, 75 - IsLocked: apiIssue.IsLocked, 76 - Comments: apiIssue.Comments, 77 - HTMLURL: pr.Issue.HTMLURL(), 78 - DiffURL: pr.Issue.DiffURL(), 79 - PatchURL: pr.Issue.PatchURL(), 80 - HasMerged: pr.HasMerged, 81 - MergeBase: pr.MergeBase, 82 - Mergeable: pr.Mergeable(ctx), 83 - Deadline: apiIssue.Deadline, 84 - Created: pr.Issue.CreatedUnix.AsTimePtr(), 85 - Updated: pr.Issue.UpdatedUnix.AsTimePtr(), 86 - PinOrder: apiIssue.PinOrder, 64 + ID: pr.ID, 65 + URL: pr.Issue.HTMLURL(), 66 + Index: pr.Index, 67 + Poster: apiIssue.Poster, 68 + Title: apiIssue.Title, 69 + Body: apiIssue.Body, 70 + Labels: apiIssue.Labels, 71 + Milestone: apiIssue.Milestone, 72 + Assignee: apiIssue.Assignee, 73 + Assignees: apiIssue.Assignees, 74 + State: apiIssue.State, 75 + Draft: pr.IsWorkInProgress(ctx), 76 + IsLocked: apiIssue.IsLocked, 77 + Comments: apiIssue.Comments, 78 + ReviewComments: pr.GetReviewCommentsCount(ctx), 79 + HTMLURL: pr.Issue.HTMLURL(), 80 + DiffURL: pr.Issue.DiffURL(), 81 + PatchURL: pr.Issue.PatchURL(), 82 + HasMerged: pr.HasMerged, 83 + MergeBase: pr.MergeBase, 84 + Mergeable: pr.Mergeable(ctx), 85 + Deadline: apiIssue.Deadline, 86 + Created: pr.Issue.CreatedUnix.AsTimePtr(), 87 + Updated: pr.Issue.UpdatedUnix.AsTimePtr(), 88 + PinOrder: apiIssue.PinOrder, 87 89 88 90 AllowMaintainerEdit: pr.AllowMaintainerEdit, 89 91 ··· 178 180 return nil 179 181 } 180 182 183 + // Outer scope variables to be used in diff calculation 184 + var ( 185 + startCommitID string 186 + endCommitID string 187 + ) 188 + 181 189 if git.IsErrBranchNotExist(err) { 182 190 headCommitID, err := headGitRepo.GetRefCommitID(apiPullRequest.Head.Ref) 183 191 if err != nil && !git.IsErrNotExist(err) { ··· 186 194 } 187 195 if err == nil { 188 196 apiPullRequest.Head.Sha = headCommitID 197 + endCommitID = headCommitID 189 198 } 190 199 } else { 191 200 commit, err := headBranch.GetCommit() ··· 196 205 if err == nil { 197 206 apiPullRequest.Head.Ref = pr.HeadBranch 198 207 apiPullRequest.Head.Sha = commit.ID.String() 208 + endCommitID = commit.ID.String() 199 209 } 210 + } 211 + 212 + // Calculate diff 213 + startCommitID = pr.MergeBase 214 + 215 + apiPullRequest.ChangedFiles, apiPullRequest.Additions, apiPullRequest.Deletions, err = gitRepo.GetDiffShortStat(startCommitID, endCommitID) 216 + if err != nil { 217 + log.Error("GetDiffShortStat: %v", err) 200 218 } 201 219 } 202 220
+1
services/convert/user.go
··· 53 53 FullName: user.FullName, 54 54 Email: user.GetPlaceholderEmail(), 55 55 AvatarURL: user.AvatarLink(ctx), 56 + HTMLURL: user.HTMLURL(), 56 57 Created: user.CreatedUnix.AsTime(), 57 58 Restricted: user.IsRestricted, 58 59 Location: user.Location,
+36
services/webhook/default_test.go
··· 11 11 "code.gitea.io/gitea/modules/json" 12 12 webhook_module "code.gitea.io/gitea/modules/webhook" 13 13 14 + jsoniter "github.com/json-iterator/go" 14 15 "github.com/stretchr/testify/assert" 15 16 "github.com/stretchr/testify/require" 16 17 ) ··· 222 223 assert.Equal(t, "refs/heads/test", body.Ref) // full ref 223 224 }) 224 225 } 226 + 227 + func TestOpenProjectPayload(t *testing.T) { 228 + t.Run("PullRequest", func(t *testing.T) { 229 + p := pullRequestTestPayload() 230 + data, err := p.JSONPayload() 231 + require.NoError(t, err) 232 + 233 + // adapted from https://github.com/opf/openproject/blob/4c5c45fe995da0060902bc8dd5f1bf704d0b8737/modules/github_integration/lib/open_project/github_integration/services/upsert_pull_request.rb#L56 234 + j := jsoniter.Get(data, "pull_request") 235 + 236 + assert.Equal(t, 12, j.Get("id").MustBeValid().ToInt()) 237 + assert.Equal(t, "user1", j.Get("user", "login").MustBeValid().ToString()) 238 + assert.Equal(t, 12, j.Get("number").MustBeValid().ToInt()) 239 + assert.Equal(t, "http://localhost:3000/test/repo/pulls/12", j.Get("html_url").MustBeValid().ToString()) 240 + assert.Equal(t, jsoniter.NilValue, j.Get("updated_at").ValueType()) 241 + assert.Equal(t, "", j.Get("state").MustBeValid().ToString()) 242 + assert.Equal(t, "Fix bug", j.Get("title").MustBeValid().ToString()) 243 + assert.Equal(t, "fixes bug #2", j.Get("body").MustBeValid().ToString()) 244 + 245 + assert.Equal(t, "test/repo", j.Get("base", "repo", "full_name").MustBeValid().ToString()) 246 + assert.Equal(t, "http://localhost:3000/test/repo", j.Get("base", "repo", "html_url").MustBeValid().ToString()) 247 + 248 + assert.Equal(t, false, j.Get("draft").MustBeValid().ToBool()) 249 + assert.Equal(t, jsoniter.NilValue, j.Get("merge_commit_sha").ValueType()) 250 + assert.Equal(t, false, j.Get("merged").MustBeValid().ToBool()) 251 + assert.Equal(t, jsoniter.NilValue, j.Get("merged_by").ValueType()) 252 + assert.Equal(t, jsoniter.NilValue, j.Get("merged_at").ValueType()) 253 + assert.Equal(t, 0, j.Get("comments").MustBeValid().ToInt()) 254 + assert.Equal(t, 0, j.Get("review_comments").MustBeValid().ToInt()) 255 + assert.Equal(t, 0, j.Get("additions").MustBeValid().ToInt()) 256 + assert.Equal(t, 0, j.Get("deletions").MustBeValid().ToInt()) 257 + assert.Equal(t, 0, j.Get("changed_files").MustBeValid().ToInt()) 258 + // assert.Equal(t,"labels:", j.Get("labels").map { |values| extract_label_values(values) ) 259 + }) 260 + }
+11
services/webhook/general_test.go
··· 281 281 Title: "Milestone Title", 282 282 Description: "Milestone Description", 283 283 }, 284 + Base: &api.PRBranchInfo{ 285 + Name: "branch1", 286 + Ref: "refs/pull/2/head", 287 + Sha: "4a357436d925b5c974181ff12a994538ddc5a269", 288 + RepoID: 1, 289 + Repository: &api.Repository{ 290 + HTMLURL: "http://localhost:3000/test/repo", 291 + Name: "repo", 292 + FullName: "test/repo", 293 + }, 294 + }, 284 295 }, 285 296 Review: &api.ReviewPayload{ 286 297 Content: "good job",
+34
templates/swagger/v1_json.tmpl
··· 23413 23413 "description": "PullRequest represents a pull request", 23414 23414 "type": "object", 23415 23415 "properties": { 23416 + "additions": { 23417 + "type": "integer", 23418 + "format": "int64", 23419 + "x-go-name": "Additions" 23420 + }, 23416 23421 "allow_maintainer_edit": { 23417 23422 "type": "boolean", 23418 23423 "x-go-name": "AllowMaintainerEdit" ··· 23434 23439 "type": "string", 23435 23440 "x-go-name": "Body" 23436 23441 }, 23442 + "changed_files": { 23443 + "type": "integer", 23444 + "format": "int64", 23445 + "x-go-name": "ChangedFiles" 23446 + }, 23437 23447 "closed_at": { 23438 23448 "type": "string", 23439 23449 "format": "date-time", ··· 23448 23458 "type": "string", 23449 23459 "format": "date-time", 23450 23460 "x-go-name": "Created" 23461 + }, 23462 + "deletions": { 23463 + "type": "integer", 23464 + "format": "int64", 23465 + "x-go-name": "Deletions" 23451 23466 }, 23452 23467 "diff_url": { 23453 23468 "type": "string", 23454 23469 "x-go-name": "DiffURL" 23455 23470 }, 23471 + "draft": { 23472 + "type": "boolean", 23473 + "x-go-name": "Draft" 23474 + }, 23456 23475 "due_date": { 23457 23476 "type": "string", 23458 23477 "format": "date-time", ··· 23529 23548 }, 23530 23549 "x-go-name": "RequestedReviewers" 23531 23550 }, 23551 + "review_comments": { 23552 + "description": "number of review comments made on the diff of a PR review (not including comments on commits or issues in a PR)", 23553 + "type": "integer", 23554 + "format": "int64", 23555 + "x-go-name": "ReviewComments" 23556 + }, 23532 23557 "state": { 23533 23558 "$ref": "#/definitions/StateType" 23534 23559 }, ··· 23558 23583 "draft": { 23559 23584 "type": "boolean", 23560 23585 "x-go-name": "IsWorkInProgress" 23586 + }, 23587 + "html_url": { 23588 + "type": "string", 23589 + "x-go-name": "HTMLURL" 23561 23590 }, 23562 23591 "merged": { 23563 23592 "type": "boolean", ··· 24903 24932 "description": "the user's full name", 24904 24933 "type": "string", 24905 24934 "x-go-name": "FullName" 24935 + }, 24936 + "html_url": { 24937 + "description": "URL to the user's gitea page", 24938 + "type": "string", 24939 + "x-go-name": "HTMLURL" 24906 24940 }, 24907 24941 "id": { 24908 24942 "description": "the user's id",