aboutsummaryrefslogtreecommitdiff
path: root/routers
diff options
context:
space:
mode:
authorAnthony Wang2023-03-04 00:03:38 +0000
committerAnthony Wang2023-03-04 00:03:38 +0000
commitb4640101f3c8938ed689743606a79601201141ca (patch)
tree8469fc5ef817560db646837b41417d50e2f8ebfc /routers
parentdc20c2832871f6462990751ea802e14b02bf41b0 (diff)
parent8540fc45b11eff9a73753ca139f8ea5c38509bf5 (diff)
Merge remote-tracking branch 'origin/main' into forgejo-federation
Diffstat (limited to 'routers')
-rw-r--r--routers/api/packages/chef/auth.go3
-rw-r--r--routers/api/packages/maven/maven.go3
-rw-r--r--routers/api/v1/repo/issue.go7
-rw-r--r--routers/api/v1/repo/pull.go21
-rw-r--r--routers/api/v1/user/app.go13
-rw-r--r--routers/init.go2
-rw-r--r--routers/web/admin/config.go2
-rw-r--r--routers/web/admin/repos.go7
-rw-r--r--routers/web/explore/repo.go37
-rw-r--r--routers/web/feed/profile.go2
-rw-r--r--routers/web/feed/repo.go2
-rw-r--r--routers/web/repo/actions/view.go49
-rw-r--r--routers/web/repo/issue.go10
-rw-r--r--routers/web/repo/patch.go11
-rw-r--r--routers/web/repo/pull.go16
-rw-r--r--routers/web/repo/setting_protected_branch.go34
-rw-r--r--routers/web/user/home.go29
-rw-r--r--routers/web/user/profile.go34
-rw-r--r--routers/web/web.go1
19 files changed, 217 insertions, 66 deletions
diff --git a/routers/api/packages/chef/auth.go b/routers/api/packages/chef/auth.go
index 69f7b763a..1ea453f1f 100644
--- a/routers/api/packages/chef/auth.go
+++ b/routers/api/packages/chef/auth.go
@@ -7,7 +7,6 @@ import (
"crypto"
"crypto/rsa"
"crypto/sha1"
- "crypto/sha256"
"crypto/x509"
"encoding/base64"
"encoding/pem"
@@ -25,6 +24,8 @@ import (
chef_module "code.gitea.io/gitea/modules/packages/chef"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/services/auth"
+
+ "github.com/minio/sha256-simd"
)
const (
diff --git a/routers/api/packages/maven/maven.go b/routers/api/packages/maven/maven.go
index d0c9983cb..a3a23ecfa 100644
--- a/routers/api/packages/maven/maven.go
+++ b/routers/api/packages/maven/maven.go
@@ -6,7 +6,6 @@ package maven
import (
"crypto/md5"
"crypto/sha1"
- "crypto/sha256"
"crypto/sha512"
"encoding/hex"
"encoding/xml"
@@ -27,6 +26,8 @@ import (
maven_module "code.gitea.io/gitea/modules/packages/maven"
"code.gitea.io/gitea/routers/api/packages/helper"
packages_service "code.gitea.io/gitea/services/packages"
+
+ "github.com/minio/sha256-simd"
)
const (
diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go
index 699ca3161..9ac1022b4 100644
--- a/routers/api/v1/repo/issue.go
+++ b/routers/api/v1/repo/issue.go
@@ -92,6 +92,10 @@ func SearchIssues(ctx *context.APIContext) {
// in: query
// description: filter pulls requesting your review, default is false
// type: boolean
+ // - name: reviewed
+ // in: query
+ // description: filter pulls reviewed by you, default is false
+ // type: boolean
// - name: owner
// in: query
// description: filter by owner
@@ -266,6 +270,9 @@ func SearchIssues(ctx *context.APIContext) {
if ctx.FormBool("review_requested") {
issuesOpt.ReviewRequestedID = ctxUserID
}
+ if ctx.FormBool("reviewed") {
+ issuesOpt.ReviewedID = ctxUserID
+ }
if issues, err = issues_model.Issues(ctx, issuesOpt); err != nil {
ctx.Error(http.StatusInternalServerError, "Issues", err)
diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go
index 7005725cf..84eebeb94 100644
--- a/routers/api/v1/repo/pull.go
+++ b/routers/api/v1/repo/pull.go
@@ -767,11 +767,18 @@ func MergePullRequest(ctx *context.APIContext) {
}
}
- manuallMerge := repo_model.MergeStyle(form.Do) == repo_model.MergeStyleManuallyMerged
- force := form.ForceMerge != nil && *form.ForceMerge
+ manuallyMerged := repo_model.MergeStyle(form.Do) == repo_model.MergeStyleManuallyMerged
+
+ mergeCheckType := pull_service.MergeCheckTypeGeneral
+ if form.MergeWhenChecksSucceed {
+ mergeCheckType = pull_service.MergeCheckTypeAuto
+ }
+ if manuallyMerged {
+ mergeCheckType = pull_service.MergeCheckTypeManually
+ }
// start with merging by checking
- if err := pull_service.CheckPullMergable(ctx, ctx.Doer, &ctx.Repo.Permission, pr, manuallMerge, force); err != nil {
+ if err := pull_service.CheckPullMergable(ctx, ctx.Doer, &ctx.Repo.Permission, pr, mergeCheckType, form.ForceMerge); err != nil {
if errors.Is(err, pull_service.ErrIsClosed) {
ctx.NotFound()
} else if errors.Is(err, pull_service.ErrUserNotAllowedToMerge) {
@@ -793,7 +800,7 @@ func MergePullRequest(ctx *context.APIContext) {
}
// handle manually-merged mark
- if manuallMerge {
+ if manuallyMerged {
if err := pull_service.MergedManually(pr, ctx.Doer, ctx.Repo.GitRepo, form.MergeCommitID); err != nil {
if models.IsErrInvalidMergeStyle(err) {
ctx.Error(http.StatusMethodNotAllowed, "Invalid merge style", fmt.Errorf("%s is not allowed an allowed merge style for this repository", repo_model.MergeStyle(form.Do)))
@@ -1420,8 +1427,9 @@ func GetPullRequestFiles(ctx *context.APIContext) {
startCommitID := prInfo.MergeBase
endCommitID := headCommitID
- maxLines, maxFiles := setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffFiles
+ maxLines := setting.Git.MaxGitDiffLines
+ // FIXME: If there are too many files in the repo, may cause some unpredictable issues.
diff, err := gitdiff.GetDiff(baseGitRepo,
&gitdiff.DiffOptions{
BeforeCommitID: startCommitID,
@@ -1429,7 +1437,7 @@ func GetPullRequestFiles(ctx *context.APIContext) {
SkipTo: ctx.FormString("skip-to"),
MaxLines: maxLines,
MaxLineCharacters: setting.Git.MaxGitDiffLineCharacters,
- MaxFiles: maxFiles,
+ MaxFiles: -1, // GetDiff() will return all files
WhitespaceBehavior: gitdiff.GetWhitespaceFlag(ctx.FormString("whitespace")),
})
if err != nil {
@@ -1452,6 +1460,7 @@ func GetPullRequestFiles(ctx *context.APIContext) {
if lenFiles < 0 {
lenFiles = 0
}
+
apiFiles := make([]*api.ChangedFile, 0, lenFiles)
for i := start; i < end; i++ {
apiFiles = append(apiFiles, convert.ToChangedFile(diff.Files[i], pr.HeadRepo, endCommitID))
diff --git a/routers/api/v1/user/app.go b/routers/api/v1/user/app.go
index 7b2f0d8c3..f89d53945 100644
--- a/routers/api/v1/user/app.go
+++ b/routers/api/v1/user/app.go
@@ -9,6 +9,7 @@ import (
"fmt"
"net/http"
"strconv"
+ "strings"
auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/modules/context"
@@ -62,6 +63,7 @@ func ListAccessTokens(ctx *context.APIContext) {
ID: tokens[i].ID,
Name: tokens[i].Name,
TokenLastEight: tokens[i].TokenLastEight,
+ Scopes: tokens[i].Scope.StringSlice(),
}
}
@@ -82,9 +84,9 @@ func CreateAccessToken(ctx *context.APIContext) {
// - name: username
// in: path
// description: username of user
- // type: string
// required: true
- // - name: userCreateToken
+ // type: string
+ // - name: body
// in: body
// schema:
// "$ref": "#/definitions/CreateAccessTokenOption"
@@ -111,6 +113,13 @@ func CreateAccessToken(ctx *context.APIContext) {
return
}
+ scope, err := auth_model.AccessTokenScope(strings.Join(form.Scopes, ",")).Normalize()
+ if err != nil {
+ ctx.Error(http.StatusBadRequest, "AccessTokenScope.Normalize", fmt.Errorf("invalid access token scope provided: %w", err))
+ return
+ }
+ t.Scope = scope
+
if err := auth_model.NewAccessToken(t); err != nil {
ctx.Error(http.StatusInternalServerError, "NewAccessToken", err)
return
diff --git a/routers/init.go b/routers/init.go
index 6a51de669..d3f822dc8 100644
--- a/routers/init.go
+++ b/routers/init.go
@@ -150,7 +150,7 @@ func GlobalInitInstalled(ctx context.Context) {
mustInit(system.Init)
mustInit(oauth2.Init)
- mustInit(models.Init)
+ mustInitCtx(ctx, models.Init)
mustInit(repo_service.Init)
// Booting long running goroutines.
diff --git a/routers/web/admin/config.go b/routers/web/admin/config.go
index 2566cbe42..075fb423d 100644
--- a/routers/web/admin/config.go
+++ b/routers/web/admin/config.go
@@ -103,7 +103,7 @@ func Config(ctx *context.Context) {
ctx.Data["PageIsAdmin"] = true
ctx.Data["PageIsAdminConfig"] = true
- systemSettings, err := system_model.GetAllSettings()
+ systemSettings, err := system_model.GetAllSettings(ctx)
if err != nil {
ctx.ServerError("system_model.GetAllSettings", err)
return
diff --git a/routers/web/admin/repos.go b/routers/web/admin/repos.go
index dc5432c54..1c4754f6d 100644
--- a/routers/web/admin/repos.go
+++ b/routers/web/admin/repos.go
@@ -33,9 +33,10 @@ func Repos(ctx *context.Context) {
ctx.Data["PageIsAdminRepositories"] = true
explore.RenderRepoSearch(ctx, &explore.RepoSearchOptions{
- Private: true,
- PageSize: setting.UI.Admin.RepoPagingNum,
- TplName: tplRepos,
+ Private: true,
+ PageSize: setting.UI.Admin.RepoPagingNum,
+ TplName: tplRepos,
+ OnlyShowRelevant: false,
})
}
diff --git a/routers/web/explore/repo.go b/routers/web/explore/repo.go
index e9684dd28..058971b9b 100644
--- a/routers/web/explore/repo.go
+++ b/routers/web/explore/repo.go
@@ -23,14 +23,17 @@ const (
// RepoSearchOptions when calling search repositories
type RepoSearchOptions struct {
- OwnerID int64
- Private bool
- Restricted bool
- PageSize int
- TplName base.TplName
+ OwnerID int64
+ Private bool
+ Restricted bool
+ PageSize int
+ OnlyShowRelevant bool
+ TplName base.TplName
}
// RenderRepoSearch render repositories search page
+// This function is also used to render the Admin Repository Management page.
+// The isAdmin param should be set to true when rendering the Admin page.
func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) {
// Sitemap index for sitemap paths
page := int(ctx.ParamsInt64("idx"))
@@ -48,11 +51,10 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) {
}
var (
- repos []*repo_model.Repository
- count int64
- err error
- orderBy db.SearchOrderBy
- onlyShowRelevant bool
+ repos []*repo_model.Repository
+ count int64
+ err error
+ orderBy db.SearchOrderBy
)
ctx.Data["SortType"] = ctx.FormString("sort")
@@ -84,11 +86,9 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) {
orderBy = db.SearchOrderByRecentUpdated
}
- onlyShowRelevant = !ctx.FormBool(relevantReposOnlyParam)
-
keyword := ctx.FormTrim("q")
- ctx.Data["OnlyShowRelevant"] = onlyShowRelevant
+ ctx.Data["OnlyShowRelevant"] = opts.OnlyShowRelevant
topicOnly := ctx.FormBool("topic")
ctx.Data["TopicOnly"] = topicOnly
@@ -111,7 +111,7 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) {
TopicOnly: topicOnly,
Language: language,
IncludeDescription: setting.UI.SearchRepoDescription,
- OnlyShowRelevant: onlyShowRelevant,
+ OnlyShowRelevant: opts.OnlyShowRelevant,
})
if err != nil {
ctx.ServerError("SearchRepository", err)
@@ -158,9 +158,10 @@ func Repos(ctx *context.Context) {
}
RenderRepoSearch(ctx, &RepoSearchOptions{
- PageSize: setting.UI.ExplorePagingNum,
- OwnerID: ownerID,
- Private: ctx.Doer != nil,
- TplName: tplExploreRepos,
+ PageSize: setting.UI.ExplorePagingNum,
+ OwnerID: ownerID,
+ Private: ctx.Doer != nil,
+ TplName: tplExploreRepos,
+ OnlyShowRelevant: !ctx.FormBool(relevantReposOnlyParam),
})
}
diff --git a/routers/web/feed/profile.go b/routers/web/feed/profile.go
index 764176919..b9dda2fc1 100644
--- a/routers/web/feed/profile.go
+++ b/routers/web/feed/profile.go
@@ -26,7 +26,7 @@ func ShowUserFeedAtom(ctx *context.Context) {
func showUserFeed(ctx *context.Context, formatType string) {
includePrivate := ctx.IsSigned && (ctx.Doer.IsAdmin || ctx.Doer.ID == ctx.ContextUser.ID)
- actions, err := activities_model.GetFeeds(ctx, activities_model.GetFeedsOptions{
+ actions, _, err := activities_model.GetFeeds(ctx, activities_model.GetFeedsOptions{
RequestedUser: ctx.ContextUser,
Actor: ctx.Doer,
IncludePrivate: includePrivate,
diff --git a/routers/web/feed/repo.go b/routers/web/feed/repo.go
index 1d24b5880..5fcad2677 100644
--- a/routers/web/feed/repo.go
+++ b/routers/web/feed/repo.go
@@ -15,7 +15,7 @@ import (
// ShowRepoFeed shows user activity on the repo as RSS / Atom feed
func ShowRepoFeed(ctx *context.Context, repo *repo_model.Repository, formatType string) {
- actions, err := activities_model.GetFeeds(ctx, activities_model.GetFeedsOptions{
+ actions, _, err := activities_model.GetFeeds(ctx, activities_model.GetFeedsOptions{
RequestedRepo: repo,
Actor: ctx.Doer,
IncludePrivate: true,
diff --git a/routers/web/repo/actions/view.go b/routers/web/repo/actions/view.go
index 5370310e8..dd2750f90 100644
--- a/routers/web/repo/actions/view.go
+++ b/routers/web/repo/actions/view.go
@@ -49,11 +49,12 @@ type ViewRequest struct {
type ViewResponse struct {
State struct {
Run struct {
- Link string `json:"link"`
- Title string `json:"title"`
- CanCancel bool `json:"canCancel"`
- Done bool `json:"done"`
- Jobs []*ViewJob `json:"jobs"`
+ Link string `json:"link"`
+ Title string `json:"title"`
+ CanCancel bool `json:"canCancel"`
+ CanApprove bool `json:"canApprove"` // the run needs an approval and the doer has permission to approve
+ Done bool `json:"done"`
+ Jobs []*ViewJob `json:"jobs"`
} `json:"run"`
CurrentJob struct {
Title string `json:"title"`
@@ -107,6 +108,7 @@ func ViewPost(ctx *context_module.Context) {
resp.State.Run.Title = run.Title
resp.State.Run.Link = run.Link()
resp.State.Run.CanCancel = !run.Status.IsDone() && ctx.Repo.CanWrite(unit.TypeActions)
+ resp.State.Run.CanApprove = run.NeedApproval && ctx.Repo.CanWrite(unit.TypeActions)
resp.State.Run.Done = run.Status.IsDone()
resp.State.Run.Jobs = make([]*ViewJob, 0, len(jobs)) // marshal to '[]' instead fo 'null' in json
for _, v := range jobs {
@@ -135,6 +137,9 @@ func ViewPost(ctx *context_module.Context) {
resp.State.CurrentJob.Title = current.Name
resp.State.CurrentJob.Detail = current.Status.LocaleString(ctx.Locale)
+ if run.NeedApproval {
+ resp.State.CurrentJob.Detail = ctx.Locale.Tr("actions.need_approval_desc")
+ }
resp.State.CurrentJob.Steps = make([]*ViewJobStep, 0) // marshal to '[]' instead fo 'null' in json
resp.Logs.StepsLog = make([]*ViewStepLog, 0) // marshal to '[]' instead fo 'null' in json
if task != nil {
@@ -261,6 +266,40 @@ func Cancel(ctx *context_module.Context) {
ctx.JSON(http.StatusOK, struct{}{})
}
+func Approve(ctx *context_module.Context) {
+ runIndex := ctx.ParamsInt64("run")
+
+ current, jobs := getRunJobs(ctx, runIndex, -1)
+ if ctx.Written() {
+ return
+ }
+ run := current.Run
+ doer := ctx.Doer
+
+ if err := db.WithTx(ctx, func(ctx context.Context) error {
+ run.NeedApproval = false
+ run.ApprovedBy = doer.ID
+ if err := actions_model.UpdateRun(ctx, run, "need_approval", "approved_by"); err != nil {
+ return err
+ }
+ for _, job := range jobs {
+ if len(job.Needs) == 0 && job.Status.IsBlocked() {
+ job.Status = actions_model.StatusWaiting
+ _, err := actions_model.UpdateRunJob(ctx, job, nil, "status")
+ if err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+ }); err != nil {
+ ctx.Error(http.StatusInternalServerError, err.Error())
+ return
+ }
+
+ ctx.JSON(http.StatusOK, struct{}{})
+}
+
// getRunJobs gets the jobs of runIndex, and returns jobs[jobIndex], jobs.
// Any error will be written to the ctx.
// It never returns a nil job of an empty jobs, if the jobIndex is out of range, it will be treated as 0.
diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go
index d740b9344..f8cc4daeb 100644
--- a/routers/web/repo/issue.go
+++ b/routers/web/repo/issue.go
@@ -138,7 +138,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti
var err error
viewType := ctx.FormString("type")
sortType := ctx.FormString("sort")
- types := []string{"all", "your_repositories", "assigned", "created_by", "mentioned", "review_requested"}
+ types := []string{"all", "your_repositories", "assigned", "created_by", "mentioned", "review_requested", "reviewed_by"}
if !util.SliceContainsString(types, viewType, true) {
viewType = "all"
}
@@ -148,6 +148,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti
posterID = ctx.FormInt64("poster")
mentionedID int64
reviewRequestedID int64
+ reviewedID int64
forceEmpty bool
)
@@ -161,6 +162,8 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti
assigneeID = ctx.Doer.ID
case "review_requested":
reviewRequestedID = ctx.Doer.ID
+ case "reviewed_by":
+ reviewedID = ctx.Doer.ID
}
}
@@ -208,6 +211,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti
MentionedID: mentionedID,
PosterID: posterID,
ReviewRequestedID: reviewRequestedID,
+ ReviewedID: reviewedID,
IsPull: isPullOption,
IssueIDs: issueIDs,
})
@@ -255,6 +259,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti
PosterID: posterID,
MentionedID: mentionedID,
ReviewRequestedID: reviewRequestedID,
+ ReviewedID: reviewedID,
MilestoneIDs: mileIDs,
ProjectID: projectID,
IsClosed: util.OptionalBoolOf(isShowClosed),
@@ -2425,6 +2430,9 @@ func SearchIssues(ctx *context.Context) {
if ctx.FormBool("review_requested") {
issuesOpt.ReviewRequestedID = ctxUserID
}
+ if ctx.FormBool("reviewed") {
+ issuesOpt.ReviewedID = ctxUserID
+ }
if issues, err = issues_model.Issues(ctx, issuesOpt); err != nil {
ctx.Error(http.StatusInternalServerError, "Issues", err.Error())
diff --git a/routers/web/repo/patch.go b/routers/web/repo/patch.go
index 12b26f38e..efb466249 100644
--- a/routers/web/repo/patch.go
+++ b/routers/web/repo/patch.go
@@ -25,7 +25,7 @@ const (
func NewDiffPatch(ctx *context.Context) {
canCommit := renderCommitRights(ctx)
- ctx.Data["TreePath"] = ""
+ ctx.Data["PageIsPatch"] = true
ctx.Data["commit_summary"] = ""
ctx.Data["commit_message"] = ""
@@ -51,7 +51,7 @@ func NewDiffPatchPost(ctx *context.Context) {
if form.CommitChoice == frmCommitChoiceNewBranch {
branchName = form.NewBranchName
}
- ctx.Data["TreePath"] = ""
+ ctx.Data["PageIsPatch"] = true
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL()
ctx.Data["FileContent"] = form.Content
ctx.Data["commit_summary"] = form.CommitSummary
@@ -86,13 +86,14 @@ func NewDiffPatchPost(ctx *context.Context) {
message += "\n\n" + form.CommitMessage
}
- if _, err := files.ApplyDiffPatch(ctx, ctx.Repo.Repository, ctx.Doer, &files.ApplyDiffPatchOptions{
+ fileResponse, err := files.ApplyDiffPatch(ctx, ctx.Repo.Repository, ctx.Doer, &files.ApplyDiffPatchOptions{
LastCommitID: form.LastCommit,
OldBranch: ctx.Repo.BranchName,
NewBranch: branchName,
Message: message,
Content: strings.ReplaceAll(form.Content, "\r", ""),
- }); err != nil {
+ })
+ if err != nil {
if models.IsErrBranchAlreadyExists(err) {
// User has specified a branch that already exists
branchErr := err.(models.ErrBranchAlreadyExists)
@@ -111,6 +112,6 @@ func NewDiffPatchPost(ctx *context.Context) {
if form.CommitChoice == frmCommitChoiceNewBranch && ctx.Repo.Repository.UnitEnabled(ctx, unit.TypePullRequests) {
ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + util.PathEscapeSegments(ctx.Repo.BranchName) + "..." + util.PathEscapeSegments(form.NewBranchName))
} else {
- ctx.Redirect(ctx.Repo.RepoLink + "/src/branch/" + util.PathEscapeSegments(branchName) + "/" + util.PathEscapeSegments(form.TreePath))
+ ctx.Redirect(ctx.Repo.RepoLink + "/commit/" + fileResponse.Commit.SHA)
}
}
diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go
index c7a59da8a..38b9f22cb 100644
--- a/routers/web/repo/pull.go
+++ b/routers/web/repo/pull.go
@@ -926,11 +926,19 @@ func MergePullRequest(ctx *context.Context) {
pr := issue.PullRequest
pr.Issue = issue
pr.Issue.Repo = ctx.Repo.Repository
- manualMerge := repo_model.MergeStyle(form.Do) == repo_model.MergeStyleManuallyMerged
- forceMerge := form.ForceMerge != nil && *form.ForceMerge
+
+ manuallyMerged := repo_model.MergeStyle(form.Do) == repo_model.MergeStyleManuallyMerged
+
+ mergeCheckType := pull_service.MergeCheckTypeGeneral
+ if form.MergeWhenChecksSucceed {
+ mergeCheckType = pull_service.MergeCheckTypeAuto
+ }
+ if manuallyMerged {
+ mergeCheckType = pull_service.MergeCheckTypeManually
+ }
// start with merging by checking
- if err := pull_service.CheckPullMergable(ctx, ctx.Doer, &ctx.Repo.Permission, pr, manualMerge, forceMerge); err != nil {
+ if err := pull_service.CheckPullMergable(ctx, ctx.Doer, &ctx.Repo.Permission, pr, mergeCheckType, form.ForceMerge); err != nil {
switch {
case errors.Is(err, pull_service.ErrIsClosed):
if issue.IsPull {
@@ -962,7 +970,7 @@ func MergePullRequest(ctx *context.Context) {
}
// handle manually-merged mark
- if manualMerge {
+ if manuallyMerged {
if err := pull_service.MergedManually(pr, ctx.Doer, ctx.Repo.GitRepo, form.MergeCommitID); err != nil {
switch {
diff --git a/routers/web/repo/setting_protected_branch.go b/routers/web/repo/setting_protected_branch.go
index a54565c1f..0a8c39fef 100644
--- a/routers/web/repo/setting_protected_branch.go
+++ b/routers/web/repo/setting_protected_branch.go
@@ -166,10 +166,36 @@ func SettingsProtectedBranchPost(ctx *context.Context) {
}
var err error
- protectBranch, err = git_model.GetProtectedBranchRuleByName(ctx, ctx.Repo.Repository.ID, f.RuleName)
- if err != nil {
- ctx.ServerError("GetProtectBranchOfRepoByName", err)
- return
+ if f.RuleID > 0 {
+ // If the RuleID isn't 0, it must be an edit operation. So we get rule by id.
+ protectBranch, err = git_model.GetProtectedBranchRuleByID(ctx, ctx.Repo.Repository.ID, f.RuleID)
+ if err != nil {
+ ctx.ServerError("GetProtectBranchOfRepoByID", err)
+ return
+ }
+ if protectBranch != nil && protectBranch.RuleName != f.RuleName {
+ // RuleName changed. We need to check if there is a rule with the same name.
+ // If a rule with the same name exists, an error should be returned.
+ sameNameProtectBranch, err := git_model.GetProtectedBranchRuleByName(ctx, ctx.Repo.Repository.ID, f.RuleName)
+ if err != nil {
+ ctx.ServerError("GetProtectBranchOfRepoByName", err)
+ return
+ }
+ if sameNameProtectBranch != nil {
+ ctx.Flash.Error(ctx.Tr("repo.settings.protected_branch_duplicate_rule_name"))
+ ctx.Redirect(fmt.Sprintf("%s/settings/branches/edit?rule_name=%s", ctx.Repo.RepoLink, protectBranch.RuleName))
+ return
+ }
+ }
+ } else {
+ // FIXME: If a new ProtectBranch has a duplicate RuleName, an error should be returned.
+ // Currently, if a new ProtectBranch with a duplicate RuleName is created, the existing ProtectBranch will be updated.
+ // But we cannot modify this logic now because many unit tests rely on it.
+ protectBranch, err = git_model.GetProtectedBranchRuleByName(ctx, ctx.Repo.Repository.ID, f.RuleName)
+ if err != nil {
+ ctx.ServerError("GetProtectBranchOfRepoByName", err)
+ return
+ }
}
if protectBranch == nil {
// No options found, create defaults.
diff --git a/routers/web/user/home.go b/routers/web/user/home.go
index 4f45c1d5c..a0a5dc3c4 100644
--- a/routers/web/user/home.go
+++ b/routers/web/user/home.go
@@ -72,12 +72,23 @@ func Dashboard(ctx *context.Context) {
return
}
+ var (
+ date = ctx.FormString("date")
+ page = ctx.FormInt("page")
+ )
+
+ // Make sure page number is at least 1. Will be posted to ctx.Data.
+ if page <= 1 {
+ page = 1
+ }
+
ctx.Data["Title"] = ctxUser.DisplayName() + " - " + ctx.Tr("dashboard")
ctx.Data["PageIsDashboard"] = true
ctx.Data["PageIsNews"] = true
cnt, _ := organization.GetOrganizationCount(ctx, ctxUser)
ctx.Data["UserOrgsCount"] = cnt
ctx.Data["MirrorsEnabled"] = setting.Mirror.Enabled
+ ctx.Data["Date"] = date
var uid int64
if ctxUser != nil {
@@ -98,8 +109,7 @@ func Dashboard(ctx *context.Context) {
ctx.Data["HeatmapData"] = data
}
- var err error
- ctx.Data["Feeds"], err = activities_model.GetFeeds(ctx, activities_model.GetFeedsOptions{
+ feeds, count, err := activities_model.GetFeeds(ctx, activities_model.GetFeedsOptions{
RequestedUser: ctxUser,
RequestedTeam: ctx.Org.Team,
Actor: ctx.Doer,
@@ -107,13 +117,22 @@ func Dashboard(ctx *context.Context) {
OnlyPerformedBy: false,
IncludeDeleted: false,
Date: ctx.FormString("date"),
- ListOptions: db.ListOptions{PageSize: setting.UI.FeedPagingNum},
+ ListOptions: db.ListOptions{
+ Page: page,
+ PageSize: setting.UI.FeedPagingNum,
+ },
})
if err != nil {
ctx.ServerError("GetFeeds", err)
return
}
+ ctx.Data["Feeds"] = feeds
+
+ pager := context.NewPagination(int(count), setting.UI.FeedPagingNum, page, 5)
+ pager.AddParam(ctx, "date", "Date")
+ ctx.Data["Page"] = pager
+
ctx.HTML(http.StatusOK, tplDashboard)
}
@@ -366,6 +385,8 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
filterMode = issues_model.FilterModeMention
case "review_requested":
filterMode = issues_model.FilterModeReviewRequested
+ case "reviewed_by":
+ filterMode = issues_model.FilterModeReviewed
case "your_repositories":
fallthrough
default:
@@ -434,6 +455,8 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
opts.MentionedID = ctx.Doer.ID
case issues_model.FilterModeReviewRequested:
opts.ReviewRequestedID = ctx.Doer.ID
+ case issues_model.FilterModeReviewed:
+ opts.ReviewedID = ctx.Doer.ID
}
// keyword holds the search term entered into the search field.
diff --git a/routers/web/user/profile.go b/routers/web/user/profile.go
index 503562220..5d34df79b 100644
--- a/routers/web/user/profile.go
+++ b/routers/web/user/profile.go
@@ -120,6 +120,11 @@ func Profile(ctx *context.Context) {
page = 1
}
+ pagingNum := setting.UI.User.RepoPagingNum
+ if tab == "activity" {
+ pagingNum = setting.UI.FeedPagingNum
+ }
+
topicOnly := ctx.FormBool("topic")
var (
@@ -165,7 +170,7 @@ func Profile(ctx *context.Context) {
switch tab {
case "followers":
items, count, err := user_model.GetUserFollowers(ctx, ctx.ContextUser, ctx.Doer, db.ListOptions{
- PageSize: setting.UI.User.RepoPagingNum,
+ PageSize: pagingNum,
Page: page,
})
if err != nil {
@@ -177,7 +182,7 @@ func Profile(ctx *context.Context) {
total = int(count)
case "following":
items, count, err := user_model.GetUserFollowing(ctx, ctx.ContextUser, ctx.Doer, db.ListOptions{
- PageSize: setting.UI.User.RepoPagingNum,
+ PageSize: pagingNum,
Page: page,
})
if err != nil {
@@ -188,24 +193,32 @@ func Profile(ctx *context.Context) {
total = int(count)
case "activity":
- ctx.Data["Feeds"], err = activities_model.GetFeeds(ctx, activities_model.GetFeedsOptions{
+ date := ctx.FormString("date")
+ items, count, err := activities_model.GetFeeds(ctx, activities_model.GetFeedsOptions{
RequestedUser: ctx.ContextUser,
Actor: ctx.Doer,
IncludePrivate: showPrivate,
OnlyPerformedBy: true,
IncludeDeleted: false,
- Date: ctx.FormString("date"),
- ListOptions: db.ListOptions{PageSize: setting.UI.FeedPagingNum},
+ Date: date,
+ ListOptions: db.ListOptions{
+ PageSize: pagingNum,
+ Page: page,
+ },
})
if err != nil {
ctx.ServerError("GetFeeds", err)
return
}
+ ctx.Data["Feeds"] = items
+ ctx.Data["Date"] = date
+
+ total = int(count)
case "stars":
ctx.Data["PageIsProfileStarList"] = true
repos, count, err = repo_model.SearchRepository(ctx, &repo_model.SearchRepoOptions{
ListOptions: db.ListOptions{
- PageSize: setting.UI.User.RepoPagingNum,
+ PageSize: pagingNum,
Page: page,
},
Actor: ctx.Doer,
@@ -237,7 +250,7 @@ func Profile(ctx *context.Context) {
case "watching":
repos, count, err = repo_model.SearchRepository(ctx, &repo_model.SearchRepoOptions{
ListOptions: db.ListOptions{
- PageSize: setting.UI.User.RepoPagingNum,
+ PageSize: pagingNum,
Page: page,
},
Actor: ctx.Doer,
@@ -259,7 +272,7 @@ func Profile(ctx *context.Context) {
default:
repos, count, err = repo_model.SearchRepository(ctx, &repo_model.SearchRepoOptions{
ListOptions: db.ListOptions{
- PageSize: setting.UI.User.RepoPagingNum,
+ PageSize: pagingNum,
Page: page,
},
Actor: ctx.Doer,
@@ -282,12 +295,15 @@ func Profile(ctx *context.Context) {
ctx.Data["Repos"] = repos
ctx.Data["Total"] = total
- pager := context.NewPagination(total, setting.UI.User.RepoPagingNum, page, 5)
+ pager := context.NewPagination(total, pagingNum, page, 5)
pager.SetDefaultParams(ctx)
pager.AddParam(ctx, "tab", "TabName")
if tab != "followers" && tab != "following" && tab != "activity" && tab != "projects" {
pager.AddParam(ctx, "language", "Language")
}
+ if tab == "activity" {
+ pager.AddParam(ctx, "date", "Date")
+ }
ctx.Data["Page"] = pager
ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
diff --git a/routers/web/web.go b/routers/web/web.go
index 88e27ad67..ff312992d 100644
--- a/routers/web/web.go
+++ b/routers/web/web.go
@@ -1286,6 +1286,7 @@ func RegisterRoutes(m *web.Route) {
m.Post("/rerun", reqRepoActionsWriter, actions.Rerun)
})
m.Post("/cancel", reqRepoActionsWriter, actions.Cancel)
+ m.Post("/approve", reqRepoActionsWriter, actions.Approve)
})
}, reqRepoActionsReader, actions.MustEnableActions)