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 '[BUG] Fix pull request reopen conditions' (#2373) from gusted/forgejo-reopen-pr into forgejo

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

+233 -10
+2
options/locale/locale_en-US.ini
··· 1859 1859 pulls.cmd_instruction_merge_desc = Merge the changes and update on Forgejo. 1860 1860 pulls.clear_merge_message = Clear merge message 1861 1861 pulls.clear_merge_message_hint = Clearing the merge message will only remove the commit message content and keep generated git trailers such as "Co-Authored-By …". 1862 + pulls.reopen_failed.head_branch = The pull request cannot be reopened, because the head branch doesn't exist anymore. 1863 + pulls.reopen_failed.base_branch = The pull request cannot be reopened, because the base branch doesn't exist anymore. 1862 1864 1863 1865 pulls.auto_merge_button_when_succeed = (When checks succeed) 1864 1866 pulls.auto_merge_when_succeed = Auto merge when all checks succeed
+17 -10
routers/web/repo/issue.go
··· 3028 3028 // check whether the ref of PR <refs/pulls/pr_index/head> in base repo is consistent with the head commit of head branch in the head repo 3029 3029 // get head commit of PR 3030 3030 if pull.Flow == issues_model.PullRequestFlowGithub { 3031 - prHeadRef := pull.GetGitRefName() 3032 3031 if err := pull.LoadBaseRepo(ctx); err != nil { 3033 3032 ctx.ServerError("Unable to load base repo", err) 3034 3033 return 3035 3034 } 3036 - prHeadCommitID, err := git.GetFullCommitID(ctx, pull.BaseRepo.RepoPath(), prHeadRef) 3037 - if err != nil { 3038 - ctx.ServerError("Get head commit Id of pr fail", err) 3035 + if err := pull.LoadHeadRepo(ctx); err != nil { 3036 + ctx.ServerError("Unable to load head repo", err) 3039 3037 return 3040 3038 } 3041 3039 3042 - // get head commit of branch in the head repo 3043 - if err := pull.LoadHeadRepo(ctx); err != nil { 3044 - ctx.ServerError("Unable to load head repo", err) 3040 + // Check if the base branch of the pull request still exists. 3041 + if ok := git.IsBranchExist(ctx, pull.BaseRepo.RepoPath(), pull.BaseBranch); !ok { 3042 + ctx.JSONError(ctx.Tr("repo.pulls.reopen_failed.base_branch")) 3043 + return 3044 + } 3045 + 3046 + // Check if the head branch of the pull request still exists. 3047 + if ok := git.IsBranchExist(ctx, pull.HeadRepo.RepoPath(), pull.HeadBranch); !ok { 3048 + ctx.JSONError(ctx.Tr("repo.pulls.reopen_failed.head_branch")) 3045 3049 return 3046 3050 } 3047 - if ok := git.IsBranchExist(ctx, pull.HeadRepo.RepoPath(), pull.BaseBranch); !ok { 3048 - // todo localize 3049 - ctx.JSONError("The origin branch is delete, cannot reopen.") 3051 + 3052 + prHeadRef := pull.GetGitRefName() 3053 + prHeadCommitID, err := git.GetFullCommitID(ctx, pull.BaseRepo.RepoPath(), prHeadRef) 3054 + if err != nil { 3055 + ctx.ServerError("Get head commit Id of pr fail", err) 3050 3056 return 3051 3057 } 3058 + 3052 3059 headBranchRef := pull.GetGitHeadBranchRefName() 3053 3060 headBranchCommitID, err := git.GetFullCommitID(ctx, pull.HeadRepo.RepoPath(), headBranchRef) 3054 3061 if err != nil {
+214
tests/integration/pull_reopen_test.go
··· 1 + // Copyright 2024 The Forgejo Authors. All rights reserved. 2 + // SPDX-License-Identifier: MIT 3 + 4 + package integration 5 + 6 + import ( 7 + "fmt" 8 + "net/http" 9 + "net/http/httptest" 10 + "net/url" 11 + "strings" 12 + "testing" 13 + "time" 14 + 15 + "code.gitea.io/gitea/models/db" 16 + git_model "code.gitea.io/gitea/models/git" 17 + issues_model "code.gitea.io/gitea/models/issues" 18 + unit_model "code.gitea.io/gitea/models/unit" 19 + "code.gitea.io/gitea/models/unittest" 20 + user_model "code.gitea.io/gitea/models/user" 21 + gitea_context "code.gitea.io/gitea/modules/context" 22 + "code.gitea.io/gitea/modules/git" 23 + "code.gitea.io/gitea/modules/translation" 24 + issue_service "code.gitea.io/gitea/services/issue" 25 + pull_service "code.gitea.io/gitea/services/pull" 26 + repo_service "code.gitea.io/gitea/services/repository" 27 + files_service "code.gitea.io/gitea/services/repository/files" 28 + "code.gitea.io/gitea/tests" 29 + "github.com/stretchr/testify/assert" 30 + ) 31 + 32 + func TestPullrequestReopen(t *testing.T) { 33 + onGiteaRun(t, func(t *testing.T, u *url.URL) { 34 + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) 35 + org26 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 26}) 36 + 37 + // Create an base repository. 38 + baseRepo, _, f := CreateDeclarativeRepo(t, user2, "reopen-base", 39 + []unit_model.Type{unit_model.TypePullRequests}, nil, nil, 40 + ) 41 + defer f() 42 + 43 + // Create a new branch on the base branch, so it can be deleted later. 44 + _, err := files_service.ChangeRepoFiles(git.DefaultContext, baseRepo, user2, &files_service.ChangeRepoFilesOptions{ 45 + Files: []*files_service.ChangeRepoFile{ 46 + { 47 + Operation: "update", 48 + TreePath: "README.md", 49 + ContentReader: strings.NewReader("New README.md"), 50 + }, 51 + }, 52 + Message: "Modify README for base", 53 + OldBranch: "main", 54 + NewBranch: "base-branch", 55 + Author: &files_service.IdentityOptions{ 56 + Name: user2.Name, 57 + Email: user2.Email, 58 + }, 59 + Committer: &files_service.IdentityOptions{ 60 + Name: user2.Name, 61 + Email: user2.Email, 62 + }, 63 + Dates: &files_service.CommitDateOptions{ 64 + Author: time.Now(), 65 + Committer: time.Now(), 66 + }, 67 + }) 68 + assert.NoError(t, err) 69 + 70 + // Create an head repository. 71 + headRepo, err := repo_service.ForkRepository(git.DefaultContext, user2, org26, repo_service.ForkRepoOptions{ 72 + BaseRepo: baseRepo, 73 + Name: "reopen-head", 74 + }) 75 + assert.NoError(t, err) 76 + assert.NotEmpty(t, headRepo) 77 + 78 + // Add a change to the head repository, so a pull request can be opened. 79 + _, err = files_service.ChangeRepoFiles(git.DefaultContext, headRepo, user2, &files_service.ChangeRepoFilesOptions{ 80 + Files: []*files_service.ChangeRepoFile{ 81 + { 82 + Operation: "update", 83 + TreePath: "README.md", 84 + ContentReader: strings.NewReader("Updated README.md"), 85 + }, 86 + }, 87 + Message: "Modify README for head", 88 + OldBranch: "main", 89 + NewBranch: "head-branch", 90 + Author: &files_service.IdentityOptions{ 91 + Name: user2.Name, 92 + Email: user2.Email, 93 + }, 94 + Committer: &files_service.IdentityOptions{ 95 + Name: user2.Name, 96 + Email: user2.Email, 97 + }, 98 + Dates: &files_service.CommitDateOptions{ 99 + Author: time.Now(), 100 + Committer: time.Now(), 101 + }, 102 + }) 103 + assert.NoError(t, err) 104 + 105 + // Create the pull reuqest. 106 + pullIssue := &issues_model.Issue{ 107 + RepoID: baseRepo.ID, 108 + Title: "Testing reopen functionality", 109 + PosterID: user2.ID, 110 + Poster: user2, 111 + IsPull: true, 112 + } 113 + pullRequest := &issues_model.PullRequest{ 114 + HeadRepoID: headRepo.ID, 115 + BaseRepoID: baseRepo.ID, 116 + HeadBranch: "head-branch", 117 + BaseBranch: "base-branch", 118 + HeadRepo: headRepo, 119 + BaseRepo: baseRepo, 120 + Type: issues_model.PullRequestGitea, 121 + } 122 + err = pull_service.NewPullRequest(git.DefaultContext, baseRepo, pullIssue, nil, nil, pullRequest, nil) 123 + assert.NoError(t, err) 124 + 125 + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{Title: "Testing reopen functionality"}) 126 + 127 + // Close the PR. 128 + err = issue_service.ChangeStatus(db.DefaultContext, issue, user2, "", true) 129 + assert.NoError(t, err) 130 + 131 + session := loginUser(t, "user2") 132 + 133 + reopenPR := func(t *testing.T, expectedStatus int) *httptest.ResponseRecorder { 134 + t.Helper() 135 + 136 + link := fmt.Sprintf("%s/pulls/%d/comments", baseRepo.FullName(), issue.Index) 137 + req := NewRequestWithValues(t, "POST", link, map[string]string{ 138 + "_csrf": GetCSRF(t, session, fmt.Sprintf("%s/pulls/%d", baseRepo.FullName(), issue.Index)), 139 + "status": "reopen", 140 + }) 141 + return session.MakeRequest(t, req, expectedStatus) 142 + } 143 + 144 + restoreBranch := func(t *testing.T, repoName, branchName string, branchID int64) { 145 + t.Helper() 146 + 147 + link := fmt.Sprintf("/%s/branches", repoName) 148 + req := NewRequestWithValues(t, "POST", fmt.Sprintf("%s/restore?branch_id=%d&name=%s", link, branchID, branchName), map[string]string{ 149 + "_csrf": GetCSRF(t, session, link), 150 + }) 151 + session.MakeRequest(t, req, http.StatusOK) 152 + 153 + flashCookie := session.GetCookie(gitea_context.CookieNameFlash) 154 + assert.NotNil(t, flashCookie) 155 + assert.Contains(t, flashCookie.Value, "success%3DBranch%2B%2522"+branchName+"%2522%2Bhas%2Bbeen%2Brestored.") 156 + } 157 + 158 + deleteBranch := func(t *testing.T, repoName, branchName string) { 159 + t.Helper() 160 + 161 + link := fmt.Sprintf("/%s/branches", repoName) 162 + req := NewRequestWithValues(t, "POST", fmt.Sprintf("%s/delete?name=%s", link, branchName), map[string]string{ 163 + "_csrf": GetCSRF(t, session, link), 164 + }) 165 + session.MakeRequest(t, req, http.StatusOK) 166 + 167 + flashCookie := session.GetCookie(gitea_context.CookieNameFlash) 168 + assert.NotNil(t, flashCookie) 169 + assert.Contains(t, flashCookie.Value, "success%3DBranch%2B%2522"+branchName+"%2522%2Bhas%2Bbeen%2Bdeleted.") 170 + } 171 + 172 + type errorJSON struct { 173 + Error string `json:"errorMessage"` 174 + } 175 + 176 + t.Run("Base branch deleted", func(t *testing.T) { 177 + defer tests.PrintCurrentTest(t)() 178 + 179 + branch := unittest.AssertExistsAndLoadBean(t, &git_model.Branch{Name: "base-branch", RepoID: baseRepo.ID}) 180 + defer func() { 181 + restoreBranch(t, baseRepo.FullName(), branch.Name, branch.ID) 182 + }() 183 + 184 + deleteBranch(t, baseRepo.FullName(), branch.Name) 185 + resp := reopenPR(t, http.StatusBadRequest) 186 + 187 + var errorResp errorJSON 188 + DecodeJSON(t, resp, &errorResp) 189 + assert.EqualValues(t, translation.NewLocale("en-US").Tr("repo.pulls.reopen_failed.base_branch"), errorResp.Error) 190 + }) 191 + 192 + t.Run("Head branch deleted", func(t *testing.T) { 193 + defer tests.PrintCurrentTest(t)() 194 + 195 + branch := unittest.AssertExistsAndLoadBean(t, &git_model.Branch{Name: "head-branch", RepoID: headRepo.ID}) 196 + defer func() { 197 + restoreBranch(t, headRepo.FullName(), branch.Name, branch.ID) 198 + }() 199 + 200 + deleteBranch(t, headRepo.FullName(), branch.Name) 201 + resp := reopenPR(t, http.StatusBadRequest) 202 + 203 + var errorResp errorJSON 204 + DecodeJSON(t, resp, &errorResp) 205 + assert.EqualValues(t, translation.NewLocale("en-US").Tr("repo.pulls.reopen_failed.head_branch"), errorResp.Error) 206 + }) 207 + 208 + t.Run("Normal", func(t *testing.T) { 209 + defer tests.PrintCurrentTest(t)() 210 + 211 + reopenPR(t, http.StatusOK) 212 + }) 213 + }) 214 + }