mirror of
https://github.com/go-gitea/gitea.git
synced 2026-01-27 04:05:09 +01:00
Merge branch 'lunny/some_refactors' of github.com:lunny/gitea into lunny/some_refactors
This commit is contained in:
commit
b34b0e5add
@ -10,9 +10,12 @@ import (
|
||||
|
||||
// ReleaseAsset represents a release asset
|
||||
type ReleaseAsset struct {
|
||||
ID int64
|
||||
Name string
|
||||
ContentType *string `yaml:"content_type"`
|
||||
ID int64
|
||||
Name string
|
||||
|
||||
// There was a field "ContentType (content_type)" because Some forges can provide that for assets,
|
||||
// but we don't need it when migrating, so the field is omitted here.
|
||||
|
||||
Size *int
|
||||
DownloadCount *int `yaml:"download_count"`
|
||||
Created time.Time
|
||||
|
||||
@ -140,6 +140,8 @@ type CreatePullRequestOption struct {
|
||||
Reviewers []string `json:"reviewers"`
|
||||
// The list of team reviewer names
|
||||
TeamReviewers []string `json:"team_reviewers"`
|
||||
// Whether maintainers can edit the pull request
|
||||
AllowMaintainerEdit *bool `json:"allow_maintainer_edit"`
|
||||
}
|
||||
|
||||
// EditPullRequestOption options when modify pull request
|
||||
|
||||
@ -25,6 +25,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/gitrepo"
|
||||
"code.gitea.io/gitea/modules/graceful"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/optional"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
@ -496,6 +497,11 @@ func CreatePullRequest(ctx *context.APIContext) {
|
||||
deadlineUnix = timeutil.TimeStamp(form.Deadline.Unix())
|
||||
}
|
||||
|
||||
unitPullRequest, err := ctx.Repo.Repository.GetUnit(ctx, unit.TypePullRequests)
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
}
|
||||
|
||||
prIssue := &issues_model.Issue{
|
||||
RepoID: repo.ID,
|
||||
Title: form.Title,
|
||||
@ -517,6 +523,8 @@ func CreatePullRequest(ctx *context.APIContext) {
|
||||
Type: issues_model.PullRequestGitea,
|
||||
}
|
||||
|
||||
pr.AllowMaintainerEdit = optional.FromPtr(form.AllowMaintainerEdit).ValueOrDefault(unitPullRequest.PullRequestsConfig().DefaultAllowMaintainerEdit)
|
||||
|
||||
// Get all assignee IDs
|
||||
assigneeIDs, err := issues_model.MakeIDsFromAPIAssigneesToAdd(ctx, form.Assignee, form.Assignees)
|
||||
if err != nil {
|
||||
|
||||
@ -1390,6 +1390,7 @@ func CompareAndPullRequestPost(ctx *context.Context) {
|
||||
AssigneeIDs: assigneeIDs,
|
||||
Reviewers: validateRet.Reviewers,
|
||||
TeamReviewers: validateRet.TeamReviewers,
|
||||
ProjectID: projectID,
|
||||
}
|
||||
if err := pull_service.NewPullRequest(ctx, prOpts); err != nil {
|
||||
switch {
|
||||
@ -1441,15 +1442,6 @@ func CompareAndPullRequestPost(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if projectID > 0 && ctx.Repo.CanWrite(unit.TypeProjects) {
|
||||
if err := issues_model.IssueAssignOrRemoveProject(ctx, pullIssue, ctx.Doer, projectID, 0); err != nil {
|
||||
if !errors.Is(err, util.ErrPermissionDenied) {
|
||||
ctx.ServerError("IssueAssignOrRemoveProject", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.Trace("Pull request created: %d/%d", repo.ID, pullIssue.ID)
|
||||
ctx.JSONRedirect(pullIssue.Link())
|
||||
}
|
||||
|
||||
@ -405,13 +405,6 @@ func (f *NewPackagistHookForm) Validate(req *http.Request, errs binding.Errors)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// .___
|
||||
// | | ______ ________ __ ____
|
||||
// | |/ ___// ___/ | \_/ __ \
|
||||
// | |\___ \ \___ \| | /\ ___/
|
||||
// |___/____ >____ >____/ \___ >
|
||||
// \/ \/ \/
|
||||
|
||||
// CreateIssueForm form for creating issue
|
||||
type CreateIssueForm struct {
|
||||
Title string `binding:"Required;MaxSize(255)"`
|
||||
|
||||
@ -329,7 +329,6 @@ func (g *GithubDownloaderV3) convertGithubRelease(ctx context.Context, rel *gith
|
||||
r.Assets = append(r.Assets, &base.ReleaseAsset{
|
||||
ID: asset.GetID(),
|
||||
Name: asset.GetName(),
|
||||
ContentType: asset.ContentType,
|
||||
Size: asset.Size,
|
||||
DownloadCount: asset.DownloadCount,
|
||||
Created: asset.CreatedAt.Time,
|
||||
|
||||
@ -316,12 +316,11 @@ func (g *GitlabDownloader) convertGitlabRelease(ctx context.Context, rel *gitlab
|
||||
|
||||
httpClient := NewMigrationHTTPClient()
|
||||
|
||||
for k, asset := range rel.Assets.Links {
|
||||
for _, asset := range rel.Assets.Links {
|
||||
assetID := asset.ID // Don't optimize this, for closure we need a local variable
|
||||
r.Assets = append(r.Assets, &base.ReleaseAsset{
|
||||
ID: int64(asset.ID),
|
||||
Name: asset.Name,
|
||||
ContentType: &rel.Assets.Sources[k].Format,
|
||||
Size: &zero,
|
||||
DownloadCount: &zero,
|
||||
DownloadFunc: func() (io.ReadCloser, error) {
|
||||
|
||||
@ -171,7 +171,6 @@ func assertReactionsEqual(t *testing.T, expected, actual []*base.Reaction) {
|
||||
func assertReleaseAssetEqual(t *testing.T, expected, actual *base.ReleaseAsset) {
|
||||
assert.Equal(t, expected.ID, actual.ID)
|
||||
assert.Equal(t, expected.Name, actual.Name)
|
||||
assert.Equal(t, expected.ContentType, actual.ContentType)
|
||||
assert.Equal(t, expected.Size, actual.Size)
|
||||
assert.Equal(t, expected.DownloadCount, actual.DownloadCount)
|
||||
assertTimeEqual(t, expected.Created, actual.Created)
|
||||
|
||||
@ -52,6 +52,7 @@ type NewPullRequestOptions struct {
|
||||
AssigneeIDs []int64
|
||||
Reviewers []*user_model.User
|
||||
TeamReviewers []*organization.Team
|
||||
ProjectID int64
|
||||
}
|
||||
|
||||
// NewPullRequest creates new pull request with labels for repository.
|
||||
@ -67,11 +68,13 @@ func NewPullRequest(ctx context.Context, opts *NewPullRequestOptions) error {
|
||||
|
||||
// user should be a collaborator or a member of the organization for base repo
|
||||
canCreate := issue.Poster.IsAdmin || pr.Flow == issues_model.PullRequestFlowAGit
|
||||
canAssignProject := canCreate
|
||||
if !canCreate {
|
||||
canCreate, err := repo_model.IsOwnerMemberCollaborator(ctx, repo, issue.Poster.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
canAssignProject = canCreate
|
||||
|
||||
if !canCreate {
|
||||
// or user should have write permission in the head repo
|
||||
@ -85,6 +88,7 @@ func NewPullRequest(ctx context.Context, opts *NewPullRequestOptions) error {
|
||||
if !perm.CanWrite(unit.TypeCode) {
|
||||
return issues_model.ErrMustCollaborator
|
||||
}
|
||||
canAssignProject = perm.CanWrite(unit.TypeProjects)
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,6 +121,12 @@ func NewPullRequest(ctx context.Context, opts *NewPullRequestOptions) error {
|
||||
assigneeCommentMap[assigneeID] = comment
|
||||
}
|
||||
|
||||
if opts.ProjectID > 0 && canAssignProject {
|
||||
if err := issues_model.IssueAssignOrRemoveProject(ctx, issue, issue.Poster, opts.ProjectID, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
pr.Issue = issue
|
||||
issue.PullRequest = pr
|
||||
|
||||
|
||||
5
templates/swagger/v1_json.tmpl
generated
5
templates/swagger/v1_json.tmpl
generated
@ -23420,6 +23420,11 @@
|
||||
"description": "CreatePullRequestOption options when creating a pull request",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow_maintainer_edit": {
|
||||
"description": "Whether maintainers can edit the pull request",
|
||||
"type": "boolean",
|
||||
"x-go-name": "AllowMaintainerEdit"
|
||||
},
|
||||
"assignee": {
|
||||
"description": "The primary assignee username",
|
||||
"type": "string",
|
||||
|
||||
@ -270,13 +270,20 @@ func TestAPICreatePullSuccess(t *testing.T) {
|
||||
owner11 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo11.OwnerID})
|
||||
|
||||
session := loginUser(t, owner11.Name)
|
||||
prTitle := "test pull request title " + time.Now().String()
|
||||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
|
||||
req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls", owner10.Name, repo10.Name), &api.CreatePullRequestOption{
|
||||
Head: owner11.Name + ":master",
|
||||
Base: "master",
|
||||
Title: "create a failure pr",
|
||||
Title: prTitle,
|
||||
}).AddTokenAuth(token)
|
||||
MakeRequest(t, req, http.StatusCreated)
|
||||
|
||||
// Also test that AllowMaintainerEdit is false by default
|
||||
prIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{Title: prTitle})
|
||||
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{IssueID: prIssue.ID})
|
||||
assert.False(t, pr.AllowMaintainerEdit)
|
||||
|
||||
MakeRequest(t, req, http.StatusUnprocessableEntity) // second request should fail
|
||||
}
|
||||
|
||||
@ -290,11 +297,14 @@ func TestAPICreatePullBasePermission(t *testing.T) {
|
||||
user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
|
||||
|
||||
session := loginUser(t, user4.Name)
|
||||
prTitle := "test pull request title " + time.Now().String()
|
||||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
|
||||
opts := &api.CreatePullRequestOption{
|
||||
Head: repo11.OwnerName + ":master",
|
||||
Base: "master",
|
||||
Title: "create a failure pr",
|
||||
Title: prTitle,
|
||||
|
||||
AllowMaintainerEdit: util.ToPointer(true),
|
||||
}
|
||||
req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls", owner10.Name, repo10.Name), &opts).AddTokenAuth(token)
|
||||
MakeRequest(t, req, http.StatusForbidden)
|
||||
@ -306,6 +316,11 @@ func TestAPICreatePullBasePermission(t *testing.T) {
|
||||
// create again
|
||||
req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls", owner10.Name, repo10.Name), &opts).AddTokenAuth(token)
|
||||
MakeRequest(t, req, http.StatusCreated)
|
||||
|
||||
// Also test that AllowMaintainerEdit is set to true
|
||||
prIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{Title: prTitle})
|
||||
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{IssueID: prIssue.ID})
|
||||
assert.True(t, pr.AllowMaintainerEdit)
|
||||
}
|
||||
|
||||
func TestAPICreatePullHeadPermission(t *testing.T) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user