Skip to content

Commit 758dfa7

Browse files
committed
Merge branch 'master' into viewed-files
2 parents 9acfe6f + 59b30f0 commit 758dfa7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+997
-65
lines changed

integrations/api_helper_for_declarative_test.go

+31
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,37 @@ func doAPIManuallyMergePullRequest(ctx APITestContext, owner, repo, commitID str
314314
}
315315
}
316316

317+
func doAPIAutoMergePullRequest(ctx APITestContext, owner, repo string, index int64) func(*testing.T) {
318+
return func(t *testing.T) {
319+
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/merge?token=%s",
320+
owner, repo, index, ctx.Token)
321+
req := NewRequestWithJSON(t, http.MethodPost, urlStr, &forms.MergePullRequestForm{
322+
MergeMessageField: "doAPIMergePullRequest Merge",
323+
Do: string(repo_model.MergeStyleMerge),
324+
MergeWhenChecksSucceed: true,
325+
})
326+
327+
if ctx.ExpectedCode != 0 {
328+
ctx.Session.MakeRequest(t, req, ctx.ExpectedCode)
329+
return
330+
}
331+
ctx.Session.MakeRequest(t, req, 200)
332+
}
333+
}
334+
335+
func doAPICancelAutoMergePullRequest(ctx APITestContext, owner, repo string, index int64) func(*testing.T) {
336+
return func(t *testing.T) {
337+
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/merge?token=%s",
338+
owner, repo, index, ctx.Token)
339+
req := NewRequest(t, http.MethodDelete, urlStr)
340+
if ctx.ExpectedCode != 0 {
341+
ctx.Session.MakeRequest(t, req, ctx.ExpectedCode)
342+
return
343+
}
344+
ctx.Session.MakeRequest(t, req, 204)
345+
}
346+
}
347+
317348
func doAPIGetBranch(ctx APITestContext, branch string, callback ...func(*testing.T, api.Branch)) func(*testing.T) {
318349
return func(t *testing.T) {
319350
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/branches/%s?token=%s", ctx.Username, ctx.Reponame, branch, ctx.Token)

integrations/api_packages_test.go

+38
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,44 @@ func TestPackageAPI(t *testing.T) {
7171
assert.Equal(t, packageVersion, p.Version)
7272
assert.NotNil(t, p.Creator)
7373
assert.Equal(t, user.Name, p.Creator.UserName)
74+
75+
t.Run("RepositoryLink", func(t *testing.T) {
76+
defer PrintCurrentTest(t)()
77+
78+
p, err := packages_model.GetPackageByName(db.DefaultContext, user.ID, packages_model.TypeGeneric, packageName)
79+
assert.NoError(t, err)
80+
81+
// no repository link
82+
req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s?token=%s", user.Name, packageName, packageVersion, token))
83+
resp := MakeRequest(t, req, http.StatusOK)
84+
85+
var ap1 *api.Package
86+
DecodeJSON(t, resp, &ap1)
87+
assert.Nil(t, ap1.Repository)
88+
89+
// link to public repository
90+
assert.NoError(t, packages_model.SetRepositoryLink(db.DefaultContext, p.ID, 1))
91+
92+
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s?token=%s", user.Name, packageName, packageVersion, token))
93+
resp = MakeRequest(t, req, http.StatusOK)
94+
95+
var ap2 *api.Package
96+
DecodeJSON(t, resp, &ap2)
97+
assert.NotNil(t, ap2.Repository)
98+
assert.EqualValues(t, 1, ap2.Repository.ID)
99+
100+
// link to private repository
101+
assert.NoError(t, packages_model.SetRepositoryLink(db.DefaultContext, p.ID, 2))
102+
103+
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s?token=%s", user.Name, packageName, packageVersion, token))
104+
resp = MakeRequest(t, req, http.StatusOK)
105+
106+
var ap3 *api.Package
107+
DecodeJSON(t, resp, &ap3)
108+
assert.Nil(t, ap3.Repository)
109+
110+
assert.NoError(t, packages_model.UnlinkRepositoryFromAllPackages(db.DefaultContext, 2))
111+
})
74112
})
75113

76114
t.Run("ListPackageFiles", func(t *testing.T) {

integrations/git_test.go

+83
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ func testGit(t *testing.T, u *url.URL) {
8282

8383
t.Run("CreateAgitFlowPull", doCreateAgitFlowPull(dstPath, &httpContext, "master", "test/head"))
8484
t.Run("BranchProtectMerge", doBranchProtectPRMerge(&httpContext, dstPath))
85+
t.Run("AutoMerge", doAutoPRMerge(&httpContext, dstPath))
8586
t.Run("CreatePRAndSetManuallyMerged", doCreatePRAndSetManuallyMerged(httpContext, httpContext, dstPath, "master", "test-manually-merge"))
8687
t.Run("MergeFork", func(t *testing.T) {
8788
defer PrintCurrentTest(t)()
@@ -615,6 +616,88 @@ func doBranchDelete(ctx APITestContext, owner, repo, branch string) func(*testin
615616
}
616617
}
617618

619+
func doAutoPRMerge(baseCtx *APITestContext, dstPath string) func(t *testing.T) {
620+
return func(t *testing.T) {
621+
defer PrintCurrentTest(t)()
622+
623+
ctx := NewAPITestContext(t, baseCtx.Username, baseCtx.Reponame)
624+
625+
t.Run("CheckoutProtected", doGitCheckoutBranch(dstPath, "protected"))
626+
t.Run("PullProtected", doGitPull(dstPath, "origin", "protected"))
627+
t.Run("GenerateCommit", func(t *testing.T) {
628+
_, err := generateCommitWithNewData(littleSize, dstPath, "[email protected]", "User Two", "branch-data-file-")
629+
assert.NoError(t, err)
630+
})
631+
t.Run("PushToUnprotectedBranch", doGitPushTestRepository(dstPath, "origin", "protected:unprotected3"))
632+
var pr api.PullRequest
633+
var err error
634+
t.Run("CreatePullRequest", func(t *testing.T) {
635+
pr, err = doAPICreatePullRequest(ctx, baseCtx.Username, baseCtx.Reponame, "protected", "unprotected3")(t)
636+
assert.NoError(t, err)
637+
})
638+
639+
// Request repository commits page
640+
req := NewRequest(t, "GET", fmt.Sprintf("/%s/%s/pulls/%d/commits", baseCtx.Username, baseCtx.Reponame, pr.Index))
641+
resp := ctx.Session.MakeRequest(t, req, http.StatusOK)
642+
doc := NewHTMLParser(t, resp.Body)
643+
644+
// Get first commit URL
645+
commitURL, exists := doc.doc.Find("#commits-table tbody tr td.sha a").Last().Attr("href")
646+
assert.True(t, exists)
647+
assert.NotEmpty(t, commitURL)
648+
649+
commitID := path.Base(commitURL)
650+
651+
// Call API to add Pending status for commit
652+
t.Run("CreateStatus", doAPICreateCommitStatus(ctx, commitID, api.CommitStatusPending))
653+
654+
// Cancel not existing auto merge
655+
ctx.ExpectedCode = http.StatusNotFound
656+
t.Run("CancelAutoMergePR", doAPICancelAutoMergePullRequest(ctx, baseCtx.Username, baseCtx.Reponame, pr.Index))
657+
658+
// Add auto merge request
659+
ctx.ExpectedCode = http.StatusCreated
660+
t.Run("AutoMergePR", doAPIAutoMergePullRequest(ctx, baseCtx.Username, baseCtx.Reponame, pr.Index))
661+
662+
// Can not create schedule twice
663+
ctx.ExpectedCode = http.StatusConflict
664+
t.Run("AutoMergePRTwice", doAPIAutoMergePullRequest(ctx, baseCtx.Username, baseCtx.Reponame, pr.Index))
665+
666+
// Cancel auto merge request
667+
ctx.ExpectedCode = http.StatusNoContent
668+
t.Run("CancelAutoMergePR", doAPICancelAutoMergePullRequest(ctx, baseCtx.Username, baseCtx.Reponame, pr.Index))
669+
670+
// Add auto merge request
671+
ctx.ExpectedCode = http.StatusCreated
672+
t.Run("AutoMergePR", doAPIAutoMergePullRequest(ctx, baseCtx.Username, baseCtx.Reponame, pr.Index))
673+
674+
// Check pr status
675+
ctx.ExpectedCode = 0
676+
pr, err = doAPIGetPullRequest(ctx, baseCtx.Username, baseCtx.Reponame, pr.Index)(t)
677+
assert.NoError(t, err)
678+
assert.False(t, pr.HasMerged)
679+
680+
// Call API to add Failure status for commit
681+
t.Run("CreateStatus", doAPICreateCommitStatus(ctx, commitID, api.CommitStatusFailure))
682+
683+
// Check pr status
684+
pr, err = doAPIGetPullRequest(ctx, baseCtx.Username, baseCtx.Reponame, pr.Index)(t)
685+
assert.NoError(t, err)
686+
assert.False(t, pr.HasMerged)
687+
688+
// Call API to add Success status for commit
689+
t.Run("CreateStatus", doAPICreateCommitStatus(ctx, commitID, api.CommitStatusSuccess))
690+
691+
// wait to let gitea merge stuff
692+
time.Sleep(time.Second)
693+
694+
// test pr status
695+
pr, err = doAPIGetPullRequest(ctx, baseCtx.Username, baseCtx.Reponame, pr.Index)(t)
696+
assert.NoError(t, err)
697+
assert.True(t, pr.HasMerged)
698+
}
699+
}
700+
618701
func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, baseBranch, headBranch string) func(t *testing.T) {
619702
return func(t *testing.T) {
620703
defer PrintCurrentTest(t)()

integrations/pull_status_test.go

+21-10
Original file line numberDiff line numberDiff line change
@@ -63,20 +63,13 @@ func TestPullCreate_CommitStatus(t *testing.T) {
6363
api.CommitStatusWarning: "warning sign icon yellow",
6464
}
6565

66+
testCtx := NewAPITestContext(t, "user1", "repo1")
67+
6668
// Update commit status, and check if icon is updated as well
6769
for _, status := range statusList {
6870

6971
// Call API to add status for commit
70-
token := getTokenForLoggedInUser(t, session)
71-
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/user1/repo1/statuses/%s?token=%s", commitID, token),
72-
api.CreateStatusOption{
73-
State: status,
74-
TargetURL: "http://test.ci/",
75-
Description: "",
76-
Context: "testci",
77-
},
78-
)
79-
session.MakeRequest(t, req, http.StatusCreated)
72+
t.Run("CreateStatus", doAPICreateCommitStatus(testCtx, commitID, status))
8073

8174
req = NewRequestf(t, "GET", "/user1/repo1/pulls/1/commits")
8275
resp = session.MakeRequest(t, req, http.StatusOK)
@@ -94,6 +87,24 @@ func TestPullCreate_CommitStatus(t *testing.T) {
9487
})
9588
}
9689

90+
func doAPICreateCommitStatus(ctx APITestContext, commitID string, status api.CommitStatusState) func(*testing.T) {
91+
return func(t *testing.T) {
92+
req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/statuses/%s?token=%s", ctx.Username, ctx.Reponame, commitID, ctx.Token),
93+
api.CreateStatusOption{
94+
State: status,
95+
TargetURL: "http://test.ci/",
96+
Description: "",
97+
Context: "testci",
98+
},
99+
)
100+
if ctx.ExpectedCode != 0 {
101+
ctx.Session.MakeRequest(t, req, ctx.ExpectedCode)
102+
return
103+
}
104+
ctx.Session.MakeRequest(t, req, http.StatusCreated)
105+
}
106+
}
107+
97108
func TestPullCreate_EmptyChangesWithCommits(t *testing.T) {
98109
onGiteaRun(t, func(t *testing.T, u *url.URL) {
99110
session := loginUser(t, "user1")

integrations/repo_commits_test.go

+1-11
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ func doTestRepoCommitWithStatus(t *testing.T, state string, classes ...string) {
3636
defer prepareTestEnv(t)()
3737

3838
session := loginUser(t, "user2")
39-
token := getTokenForLoggedInUser(t, session)
4039

4140
// Request repository commits page
4241
req := NewRequest(t, "GET", "/user2/repo1/commits/branch/master")
@@ -49,16 +48,7 @@ func doTestRepoCommitWithStatus(t *testing.T, state string, classes ...string) {
4948
assert.NotEmpty(t, commitURL)
5049

5150
// Call API to add status for commit
52-
req = NewRequestWithJSON(t, "POST", "/api/v1/repos/user2/repo1/statuses/"+path.Base(commitURL)+"?token="+token,
53-
api.CreateStatusOption{
54-
State: api.CommitStatusState(state),
55-
TargetURL: "http://test.ci/",
56-
Description: "",
57-
Context: "testci",
58-
},
59-
)
60-
61-
resp = session.MakeRequest(t, req, http.StatusCreated)
51+
t.Run("CreateStatus", doAPICreateCommitStatus(NewAPITestContext(t, "user2", "repo1"), path.Base(commitURL), api.CommitStatusState(state)))
6252

6353
req = NewRequest(t, "GET", "/user2/repo1/commits/branch/master")
6454
resp = session.MakeRequest(t, req, http.StatusOK)

models/issue_comment.go

+6
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ const (
110110
CommentTypeDismissReview
111111
// 33 Change issue ref
112112
CommentTypeChangeIssueRef
113+
// 34 pr was scheduled to auto merge when checks succeed
114+
CommentTypePRScheduledToAutoMerge
115+
// 35 pr was un scheduled to auto merge when checks succeed
116+
CommentTypePRUnScheduledToAutoMerge
113117
)
114118

115119
var commentStrings = []string{
@@ -147,6 +151,8 @@ var commentStrings = []string{
147151
"project_board",
148152
"dismiss_review",
149153
"change_issue_ref",
154+
"pull_scheduled_merge",
155+
"pull_cancel_scheduled_merge",
150156
}
151157

152158
func (t CommentType) String() string {

models/migrations/migrations.go

+2
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,8 @@ var migrations = []Migration{
384384
// v213 -> v214
385385
NewMigration("Add allow edits from maintainers to PullRequest table", addAllowMaintainerEdit),
386386
// v214 -> v215
387+
NewMigration("Add auto merge table", addAutoMergeTable),
388+
// v215 -> v216
387389
NewMigration("allow to view files in PRs", addReviewViewedFiles),
388390
}
389391

models/migrations/v214.go

+10-12
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,19 @@
55
package migrations
66

77
import (
8-
"code.gitea.io/gitea/models/pull"
9-
"code.gitea.io/gitea/modules/timeutil"
10-
118
"xorm.io/xorm"
129
)
1310

14-
func addReviewViewedFiles(x *xorm.Engine) error {
15-
type ReviewState struct {
16-
ID int64 `xorm:"pk autoincr"`
17-
UserID int64 `xorm:"NOT NULL UNIQUE(pull_commit_user)"`
18-
PullID int64 `xorm:"NOT NULL UNIQUE(pull_commit_user) DEFAULT 0"`
19-
CommitSHA string `xorm:"NOT NULL VARCHAR(40) UNIQUE(pull_commit_user)"`
20-
UpdatedFiles map[string]pull.ViewedState `xorm:"NOT NULL TEXT JSON"`
21-
UpdatedUnix timeutil.TimeStamp `xorm:"updated"`
11+
func addAutoMergeTable(x *xorm.Engine) error {
12+
type MergeStyle string
13+
type PullAutoMerge struct {
14+
ID int64 `xorm:"pk autoincr"`
15+
PullID int64 `xorm:"UNIQUE"`
16+
DoerID int64 `xorm:"NOT NULL"`
17+
MergeStyle MergeStyle `xorm:"varchar(30)"`
18+
Message string `xorm:"LONGTEXT"`
19+
CreatedUnix int64 `xorm:"created"`
2220
}
2321

24-
return x.Sync2(new(ReviewState))
22+
return x.Sync2(&PullAutoMerge{})
2523
}

models/migrations/v215.go

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2022 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package migrations
6+
7+
import (
8+
"code.gitea.io/gitea/models/pull"
9+
"code.gitea.io/gitea/modules/timeutil"
10+
11+
"xorm.io/xorm"
12+
)
13+
14+
func addReviewViewedFiles(x *xorm.Engine) error {
15+
type ReviewState struct {
16+
ID int64 `xorm:"pk autoincr"`
17+
UserID int64 `xorm:"NOT NULL UNIQUE(pull_commit_user)"`
18+
PullID int64 `xorm:"NOT NULL UNIQUE(pull_commit_user) DEFAULT 0"`
19+
CommitSHA string `xorm:"NOT NULL VARCHAR(40) UNIQUE(pull_commit_user)"`
20+
UpdatedFiles map[string]pull.ViewedState `xorm:"NOT NULL TEXT JSON"`
21+
UpdatedUnix timeutil.TimeStamp `xorm:"updated"`
22+
}
23+
24+
return x.Sync2(new(ReviewState))
25+
}

models/pull.go

+14
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import (
2020
"code.gitea.io/gitea/modules/setting"
2121
"code.gitea.io/gitea/modules/timeutil"
2222
"code.gitea.io/gitea/modules/util"
23+
24+
"xorm.io/builder"
2325
)
2426

2527
// PullRequestType defines pull request type
@@ -675,6 +677,18 @@ func (pr *PullRequest) IsSameRepo() bool {
675677
return pr.BaseRepoID == pr.HeadRepoID
676678
}
677679

680+
// GetPullRequestsByHeadBranch returns all prs by head branch
681+
// Since there could be multiple prs with the same head branch, this function returns a slice of prs
682+
func GetPullRequestsByHeadBranch(ctx context.Context, headBranch string, headRepoID int64) ([]*PullRequest, error) {
683+
log.Trace("GetPullRequestsByHeadBranch: headBranch: '%s', headRepoID: '%d'", headBranch, headRepoID)
684+
prs := make([]*PullRequest, 0, 2)
685+
if err := db.GetEngine(ctx).Where(builder.Eq{"head_branch": headBranch, "head_repo_id": headRepoID}).
686+
Find(&prs); err != nil {
687+
return nil, err
688+
}
689+
return prs, nil
690+
}
691+
678692
// GetBaseBranchHTMLURL returns the HTML URL of the base branch
679693
func (pr *PullRequest) GetBaseBranchHTMLURL() string {
680694
if err := pr.LoadBaseRepo(); err != nil {

0 commit comments

Comments
 (0)