0
0
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:
Lunny Xiao 2026-01-05 16:08:48 -08:00
commit b34b0e5add
11 changed files with 50 additions and 25 deletions

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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())
}

View File

@ -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)"`

View File

@ -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,

View File

@ -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) {

View File

@ -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)

View File

@ -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

View File

@ -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",

View File

@ -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) {