mirror of
https://github.com/go-gitea/gitea.git
synced 2025-07-27 06:18:52 +00:00
Merge e14fdbdb5e
into 54fe47fbca
This commit is contained in:
commit
cf1ec1cfc5
@ -115,6 +115,7 @@ const (
|
||||
CommentTypeUnpin // 37 unpin Issue/PullRequest
|
||||
|
||||
CommentTypeChangeTimeEstimate // 38 Change time estimate
|
||||
CommentTypeChangePRFlowType // 39 Change pull request's flow type
|
||||
)
|
||||
|
||||
var commentStrings = []string{
|
||||
@ -157,6 +158,7 @@ var commentStrings = []string{
|
||||
"pin",
|
||||
"unpin",
|
||||
"change_time_estimate",
|
||||
"change_flow_type",
|
||||
}
|
||||
|
||||
func (t CommentType) String() string {
|
||||
|
@ -113,6 +113,30 @@ const (
|
||||
PullRequestFlowAGit
|
||||
)
|
||||
|
||||
var PullRequestFlowMap map[PullRequestFlow]string = map[PullRequestFlow]string{
|
||||
PullRequestFlowGithub: "github",
|
||||
PullRequestFlowAGit: "agit",
|
||||
}
|
||||
var PullRequestFlowTypeUnknown error = errors.New("Unknown pull request type")
|
||||
|
||||
func PullRequestFlowFromString(strtype string) (PullRequestFlow, error) {
|
||||
for k, v := range PullRequestFlowMap {
|
||||
if v == strtype {
|
||||
return k, nil
|
||||
}
|
||||
}
|
||||
|
||||
return 0, PullRequestFlowTypeUnknown
|
||||
}
|
||||
|
||||
func PullRequestFlowTypeToString(flow PullRequestFlow) string {
|
||||
v, ok := PullRequestFlowMap[flow]
|
||||
if ok {
|
||||
return v
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// PullRequest represents relation between pull request and repositories.
|
||||
type PullRequest struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
@ -455,6 +479,18 @@ func (pr *PullRequest) IsFromFork() bool {
|
||||
return pr.HeadRepoID != pr.BaseRepoID
|
||||
}
|
||||
|
||||
func (pr *PullRequest) ConvertToAgitPullRequest(ctx context.Context, doer *user_model.User) (err error) {
|
||||
if pr.IsAgitFlow() {
|
||||
return nil
|
||||
}
|
||||
|
||||
pr.Flow = PullRequestFlowAGit
|
||||
pr.HeadRepoID = pr.BaseRepoID
|
||||
pr.HeadBranch = doer.LowerName + "/" + pr.HeadBranch
|
||||
|
||||
return pr.UpdateColsIfNotMerged(ctx, "flow", "head_repo_id", "head_branch")
|
||||
}
|
||||
|
||||
// NewPullRequest creates new pull request with labels for repository.
|
||||
func NewPullRequest(ctx context.Context, repo *repo_model.Repository, issue *Issue, labelIDs []int64, uuids []string, pr *PullRequest) (err error) {
|
||||
return db.WithTx(ctx, func(ctx context.Context) error {
|
||||
|
@ -60,6 +60,9 @@ type PullRequest struct {
|
||||
Closed *time.Time `json:"closed_at"`
|
||||
|
||||
PinOrder int `json:"pin_order"`
|
||||
|
||||
// swagger:enum["agit","github"]
|
||||
Flow string `json:"flow"`
|
||||
}
|
||||
|
||||
// PRBranchInfo information about a branch
|
||||
@ -107,6 +110,7 @@ type EditPullRequestOption struct {
|
||||
Deadline *time.Time `json:"due_date"`
|
||||
RemoveDeadline *bool `json:"unset_due_date"`
|
||||
AllowMaintainerEdit *bool `json:"allow_maintainer_edit"`
|
||||
FlowType string `json:"flow_type"`
|
||||
}
|
||||
|
||||
// ChangedFile store information about files affected by the pull request
|
||||
|
@ -777,6 +777,46 @@ func EditPullRequest(ctx *context.APIContext) {
|
||||
notify_service.PullRequestChangeTargetBranch(ctx, ctx.Doer, pr, form.Base)
|
||||
}
|
||||
|
||||
// change pull request type from branch or from AGit
|
||||
if !pr.HasMerged && len(form.FlowType) != 0 {
|
||||
flow, err := issues_model.PullRequestFlowFromString(form.FlowType)
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
}
|
||||
err = nil
|
||||
if !issue.IsPoster(ctx.Doer.ID) && !ctx.Repo.CanWrite(unit.TypeCode) {
|
||||
// not implemented
|
||||
ctx.Status(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
if flow != pr.Flow {
|
||||
switch flow {
|
||||
case issues_model.PullRequestFlowGithub:
|
||||
// not implemented
|
||||
ctx.Status(http.StatusForbidden)
|
||||
return
|
||||
case issues_model.PullRequestFlowAGit:
|
||||
err = pull_service.ChangePullRequestFlowToAgit(ctx, pr, ctx.Doer)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
if issues_model.IsErrPullRequestAlreadyExists(err) {
|
||||
ctx.APIError(http.StatusConflict, err)
|
||||
return
|
||||
} else if issues_model.IsErrIssueIsClosed(err) {
|
||||
ctx.APIError(http.StatusUnprocessableEntity, err)
|
||||
return
|
||||
} else if pull_service.IsErrPullRequestHasMerged(err) {
|
||||
ctx.APIError(http.StatusConflict, err)
|
||||
return
|
||||
}
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
}
|
||||
notify_service.PullRequestChangeFlowType(ctx, ctx.Doer, pr)
|
||||
}
|
||||
|
||||
// update allow edits
|
||||
if form.AllowMaintainerEdit != nil {
|
||||
if err := pull_service.SetAllowEdits(ctx, ctx.Doer, pr, *form.AllowMaintainerEdit); err != nil {
|
||||
|
@ -688,6 +688,32 @@ func (n *actionsNotifier) PullRequestSynchronized(ctx context.Context, doer *use
|
||||
Notify(ctx)
|
||||
}
|
||||
|
||||
func (n *actionsNotifier) PullRequestChangeFlowType(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
|
||||
ctx = withMethod(ctx, "PullRequestChangeFlowType")
|
||||
|
||||
if err := pr.LoadIssue(ctx); err != nil {
|
||||
log.Error("LoadAttributes: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := pr.Issue.LoadRepo(ctx); err != nil {
|
||||
log.Error("pr.Issue.LoadRepo: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
permission, _ := access_model.GetUserRepoPermission(ctx, pr.Issue.Repo, pr.Issue.Poster)
|
||||
newNotifyInput(pr.Issue.Repo, doer, webhook_module.HookEventPullRequest).
|
||||
WithPayload(&api.PullRequestPayload{
|
||||
Action: api.HookIssueEdited,
|
||||
Index: pr.Issue.Index,
|
||||
PullRequest: convert.ToAPIPullRequest(ctx, pr, nil),
|
||||
Repository: convert.ToRepo(ctx, pr.Issue.Repo, permission),
|
||||
Sender: convert.ToUser(ctx, doer, nil),
|
||||
}).
|
||||
WithPullRequest(pr).
|
||||
Notify(ctx)
|
||||
}
|
||||
|
||||
func (n *actionsNotifier) PullRequestChangeTargetBranch(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, oldBranch string) {
|
||||
ctx = withMethod(ctx, "PullRequestChangeTargetBranch")
|
||||
|
||||
|
@ -97,6 +97,7 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u
|
||||
Created: pr.Issue.CreatedUnix.AsTimePtr(),
|
||||
Updated: pr.Issue.UpdatedUnix.AsTimePtr(),
|
||||
PinOrder: util.Iif(apiIssue.PinOrder == -1, 0, apiIssue.PinOrder),
|
||||
Flow: issues_model.PullRequestFlowTypeToString(pr.Flow),
|
||||
|
||||
// output "[]" rather than null to align to github outputs
|
||||
RequestedReviewers: []*api.User{},
|
||||
|
@ -36,6 +36,7 @@ var hiddenCommentTypeGroups = hiddenCommentTypeGroupsType{
|
||||
"branch": {
|
||||
/*11*/ issues_model.CommentTypeDeleteBranch,
|
||||
/*25*/ issues_model.CommentTypeChangeTargetBranch,
|
||||
/*39*/ issues_model.CommentTypeChangePRFlowType,
|
||||
},
|
||||
"time_tracking": {
|
||||
/*12*/ issues_model.CommentTypeStartTracking,
|
||||
|
@ -49,6 +49,7 @@ type Notifier interface {
|
||||
PullRequestReview(ctx context.Context, pr *issues_model.PullRequest, review *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User)
|
||||
PullRequestCodeComment(ctx context.Context, pr *issues_model.PullRequest, comment *issues_model.Comment, mentions []*user_model.User)
|
||||
PullRequestChangeTargetBranch(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, oldBranch string)
|
||||
PullRequestChangeFlowType(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest)
|
||||
PullRequestPushCommits(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, comment *issues_model.Comment)
|
||||
PullReviewDismiss(ctx context.Context, doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment)
|
||||
|
||||
|
@ -155,6 +155,13 @@ func PullRequestChangeTargetBranch(ctx context.Context, doer *user_model.User, p
|
||||
}
|
||||
}
|
||||
|
||||
// PullRequestChangeFlowType notifies when a pull request's source branch was changed
|
||||
func PullRequestChangeFlowType(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
|
||||
for _, notifier := range notifiers {
|
||||
notifier.PullRequestChangeFlowType(ctx, doer, pr)
|
||||
}
|
||||
}
|
||||
|
||||
// PullRequestPushCommits notifies when push commits to pull request's head branch
|
||||
func PullRequestPushCommits(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, comment *issues_model.Comment) {
|
||||
for _, notifier := range notifiers {
|
||||
|
@ -70,6 +70,10 @@ func (*NullNotifier) PullRequestSynchronized(ctx context.Context, doer *user_mod
|
||||
func (*NullNotifier) PullRequestChangeTargetBranch(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, oldBranch string) {
|
||||
}
|
||||
|
||||
// PullRequestChangeFlowType places a place holder function
|
||||
func (*NullNotifier) PullRequestChangeFlowType(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
|
||||
}
|
||||
|
||||
// PullRequestPushCommits notifies when push commits to pull request's head branch
|
||||
func (*NullNotifier) PullRequestPushCommits(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, comment *issues_model.Comment) {
|
||||
}
|
||||
|
@ -247,6 +247,58 @@ func (err ErrPullRequestHasMerged) Error() string {
|
||||
err.ID, err.IssueID, err.HeadRepoID, err.BaseRepoID, err.HeadBranch, err.BaseBranch)
|
||||
}
|
||||
|
||||
// ChangePullRequestFlowToAgit changes the source branch of this pull request, as the given user
|
||||
func ChangePullRequestFlowToAgit(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.User) (err error) {
|
||||
releaser, err := globallock.Lock(ctx, getPullWorkingLockKey(pr.ID))
|
||||
if err != nil {
|
||||
log.Error("lock.Lock(): %v", err)
|
||||
return fmt.Errorf("lock.Lock: %w", err)
|
||||
}
|
||||
defer releaser()
|
||||
|
||||
// Current target branch is already the same
|
||||
if pr.Flow == issues_model.PullRequestFlowAGit {
|
||||
return nil
|
||||
}
|
||||
|
||||
if pr.Issue.IsClosed {
|
||||
return issues_model.ErrIssueIsClosed{
|
||||
ID: pr.Issue.ID,
|
||||
RepoID: pr.Issue.RepoID,
|
||||
Index: pr.Issue.Index,
|
||||
IsPull: true,
|
||||
}
|
||||
}
|
||||
|
||||
if pr.HasMerged {
|
||||
return ErrPullRequestHasMerged{
|
||||
ID: pr.ID,
|
||||
IssueID: pr.Index,
|
||||
HeadRepoID: pr.HeadRepoID,
|
||||
BaseRepoID: pr.BaseRepoID,
|
||||
HeadBranch: pr.HeadBranch,
|
||||
BaseBranch: pr.BaseBranch,
|
||||
}
|
||||
}
|
||||
|
||||
if err = pr.ConvertToAgitPullRequest(ctx, doer); err != nil {
|
||||
return fmt.Errorf("Failed to convert PR to AGit: %w", err)
|
||||
}
|
||||
|
||||
// Create comment
|
||||
options := &issues_model.CreateCommentOptions{
|
||||
Type: issues_model.CommentTypeChangePRFlowType,
|
||||
Doer: doer,
|
||||
Repo: pr.Issue.Repo,
|
||||
Issue: pr.Issue,
|
||||
}
|
||||
if _, err = issues_model.CreateComment(ctx, options); err != nil {
|
||||
return fmt.Errorf("CreateChangeSourceBranchComment: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ChangeTargetBranch changes the target branch of this pull request, as the given user.
|
||||
func ChangeTargetBranch(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.User, targetBranch string) (err error) {
|
||||
releaser, err := globallock.Lock(ctx, getPullWorkingLockKey(pr.ID))
|
||||
@ -1003,6 +1055,10 @@ func getAllCommitStatus(ctx context.Context, gitRepo *git.Repository, pr *issues
|
||||
return statuses, lastStatus, err
|
||||
}
|
||||
|
||||
func IsBranchEqual(ctx context.Context, gitRepo *git.Repository, branch1, branch2 string) (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// IsHeadEqualWithBranch returns if the commits of branchName are available in pull request head
|
||||
func IsHeadEqualWithBranch(ctx context.Context, pr *issues_model.PullRequest, branchName string) (bool, error) {
|
||||
var err error
|
||||
|
@ -731,6 +731,26 @@ func (m *webhookNotifier) PullRequestChangeTargetBranch(ctx context.Context, doe
|
||||
}
|
||||
}
|
||||
|
||||
func (m *webhookNotifier) PullRequestChangeFlowType(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
|
||||
if err := pr.LoadIssue(ctx); err != nil {
|
||||
log.Error("LoadIssue: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
issue := pr.Issue
|
||||
|
||||
mode, _ := access_model.GetUserRepoPermission(ctx, issue.Repo, issue.Poster)
|
||||
if err := PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventPullRequest, &api.PullRequestPayload{
|
||||
Action: api.HookIssueEdited,
|
||||
Index: issue.Index,
|
||||
PullRequest: convert.ToAPIPullRequest(ctx, pr, doer),
|
||||
Repository: convert.ToRepo(ctx, issue.Repo, mode),
|
||||
Sender: convert.ToUser(ctx, doer, nil),
|
||||
}); err != nil {
|
||||
log.Error("PrepareWebhooks [pr: %d]: %v", pr.ID, err)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *webhookNotifier) PullRequestReview(ctx context.Context, pr *issues_model.PullRequest, review *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) {
|
||||
var reviewHookType webhook_module.HookEventType
|
||||
|
||||
|
8
templates/swagger/v1_json.tmpl
generated
8
templates/swagger/v1_json.tmpl
generated
@ -24173,6 +24173,10 @@
|
||||
"format": "date-time",
|
||||
"x-go-name": "Deadline"
|
||||
},
|
||||
"flow_type": {
|
||||
"type": "string",
|
||||
"x-go-name": "FlowType"
|
||||
},
|
||||
"labels": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
@ -26718,6 +26722,10 @@
|
||||
"format": "date-time",
|
||||
"x-go-name": "Deadline"
|
||||
},
|
||||
"flow": {
|
||||
"type": "string",
|
||||
"x-go-name": "Flow"
|
||||
},
|
||||
"head": {
|
||||
"$ref": "#/definitions/PRBranchInfo"
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user