{{if and .Issue.PullRequest.HasMerged (not .IsPullBranchDeletable)}} {{/* Then the merge box will not be displayed because this page already contains enough information */}} {{else}} <div class="timeline-item comment merge box"> <div class="timeline-avatar text {{if .Issue.PullRequest.HasMerged}}purple {{- else if .Issue.IsClosed}}grey {{- else if .IsPullWorkInProgress}}grey {{- else if .IsFilesConflicted}}grey {{- else if .IsPullRequestBroken}}red {{- else if .IsBlockedByApprovals}}red {{- else if .IsBlockedByRejection}}red {{- else if .IsBlockedByOfficialReviewRequests}}red {{- else if .IsBlockedByOutdatedBranch}}red {{- else if .IsBlockedByChangedProtectedFiles}}red {{- else if and .EnableStatusCheck (or .RequiredStatusCheckState.IsFailure .RequiredStatusCheckState.IsError)}}red {{- else if and .EnableStatusCheck (or (not $.LatestCommitStatus) .RequiredStatusCheckState.IsPending .RequiredStatusCheckState.IsWarning)}}yellow {{- else if and .AllowMerge .RequireSigned (not .WillSign)}}red {{- else if .Issue.PullRequest.IsChecking}}yellow {{- else if .Issue.PullRequest.IsEmpty}}grey {{- else if .Issue.PullRequest.CanAutoMerge}}green {{- else}}red{{end}}">{{svg "octicon-git-merge" 40}}</div> <div class="content"> {{if .LatestCommitStatus}} <div class="ui attached segment fitted"> {{template "repo/pulls/status" (dict "CommitStatus" .LatestCommitStatus "CommitStatuses" .LatestCommitStatuses "MissingRequiredChecks" .MissingRequiredChecks "ShowHideChecks" true "is_context_required" .is_context_required )}} </div> {{end}} {{$showGeneralMergeForm := false}} <div class="ui attached segment merge-section {{if not $.LatestCommitStatus}}no-header{{end}} flex-items-block"> {{if .Issue.PullRequest.HasMerged}} {{if .IsPullBranchDeletable}} <div class="item item-section text tw-flex-1"> <div class="item-section-left"> <h3 class="tw-mb-2"> {{ctx.Locale.Tr "repo.pulls.merged_success"}} </h3> <div class="merge-section-info"> {{ctx.Locale.Tr "repo.pulls.merged_info_text" (HTMLFormat "<code>%s</code>" .HeadTarget)}} </div> </div> <div class="item-section-right"> <button class="delete-button ui button" data-url="{{.DeleteBranchLink}}">{{ctx.Locale.Tr "repo.branch.delete_html"}}</button> </div> </div> {{end}} {{else if .Issue.IsClosed}} <div class="item item-section text tw-flex-1"> <div class="item-section-left"> <h3 class="tw-mb-2">{{ctx.Locale.Tr "repo.pulls.closed"}}</h3> <div class="merge-section-info"> {{if .IsPullRequestBroken}} {{ctx.Locale.Tr "repo.pulls.cant_reopen_deleted_branch"}} {{else}} {{ctx.Locale.Tr "repo.pulls.reopen_to_merge"}} {{end}} </div> </div> {{if and .IsPullBranchDeletable (not .IsPullRequestBroken)}} <div class="item-section-right"> <button class="delete-button ui button" data-url="{{.DeleteBranchLink}}">{{ctx.Locale.Tr "repo.branch.delete_html"}}</button> </div> {{end}} </div> {{else if .IsPullFilesConflicted}} <div class="item"> {{svg "octicon-x"}} {{ctx.Locale.Tr "repo.pulls.files_conflicted"}} </div> <ul> {{range .ConflictedFiles}} <li>{{.}}</li> {{end}} </ul> {{else if .IsPullRequestBroken}} <div class="item"> {{svg "octicon-x"}} {{ctx.Locale.Tr "repo.pulls.data_broken"}} </div> {{else if .IsPullWorkInProgress}} <div class="item toggle-wip" data-title="{{.Issue.Title}}" data-wip-prefix="{{.WorkInProgressPrefix}}" data-update-url="{{.Issue.Link}}/title"> <div class="item-section-left flex-text-inline tw-flex-1"> {{svg "octicon-x"}} {{ctx.Locale.Tr "repo.pulls.cannot_merge_work_in_progress"}} </div> {{if or .HasIssuesOrPullsWritePermission .IsIssuePoster}} <button class="ui compact button"> {{ctx.Locale.Tr "repo.pulls.remove_prefix" .WorkInProgressPrefix}} </button> {{end}} </div> {{template "repo/issue/view_content/update_branch_by_merge" $}} {{else if .Issue.PullRequest.IsChecking}} <div class="item"> {{svg "octicon-sync"}} {{ctx.Locale.Tr "repo.pulls.is_checking"}} </div> {{else if .Issue.PullRequest.IsAncestor}} <div class="item"> {{svg "octicon-alert"}} {{ctx.Locale.Tr "repo.pulls.is_ancestor"}} </div> {{else if or .Issue.PullRequest.CanAutoMerge .Issue.PullRequest.IsEmpty}} {{if .IsBlockedByApprovals}} <div class="item"> {{svg "octicon-x"}} {{ctx.Locale.Tr "repo.pulls.blocked_by_approvals" .GrantedApprovals .ProtectedBranch.RequiredApprovals}} </div> {{else if .IsBlockedByRejection}} <div class="item"> {{svg "octicon-x"}} {{ctx.Locale.Tr "repo.pulls.blocked_by_rejection"}} </div> {{else if .IsBlockedByOfficialReviewRequests}} <div class="item"> {{svg "octicon-x"}} {{ctx.Locale.Tr "repo.pulls.blocked_by_official_review_requests"}} </div> {{else if .IsBlockedByOutdatedBranch}} <div class="item"> {{svg "octicon-x"}} {{ctx.Locale.Tr "repo.pulls.blocked_by_outdated_branch"}} </div> {{else if .IsBlockedByChangedProtectedFiles}} <div class="item"> {{svg "octicon-x"}} {{ctx.Locale.TrN $.ChangedProtectedFilesNum "repo.pulls.blocked_by_changed_protected_files_1" "repo.pulls.blocked_by_changed_protected_files_n"}} </div> <ul> {{range .ChangedProtectedFiles}} <li>{{.}}</li> {{end}} </ul> {{else if and .EnableStatusCheck (or .RequiredStatusCheckState.IsError .RequiredStatusCheckState.IsFailure)}} <div class="item"> {{svg "octicon-x"}} {{ctx.Locale.Tr "repo.pulls.required_status_check_failed"}} </div> {{else if and .EnableStatusCheck (not .RequiredStatusCheckState.IsSuccess)}} <div class="item"> {{svg "octicon-x"}} {{ctx.Locale.Tr "repo.pulls.required_status_check_missing"}} </div> {{else if and .AllowMerge .RequireSigned (not .WillSign)}} <div class="item"> {{svg "octicon-x"}} {{ctx.Locale.Tr "repo.pulls.require_signed_wont_sign"}} </div> <div class="item"> {{svg "octicon-unlock"}} {{ctx.Locale.Tr (printf "repo.signing.wont_sign.%s" .WontSignReason)}} </div> {{end}} {{$notAllOverridableChecksOk := or .IsBlockedByApprovals .IsBlockedByRejection .IsBlockedByOfficialReviewRequests .IsBlockedByOutdatedBranch .IsBlockedByChangedProtectedFiles (and .EnableStatusCheck (not .RequiredStatusCheckState.IsSuccess))}} {{/* admin can merge without checks, writer can merge when checks succeed */}} {{$canMergeNow := and (or $.IsRepoAdmin (not $notAllOverridableChecksOk)) (or (not .AllowMerge) (not .RequireSigned) .WillSign)}} {{/* admin and writer both can make an auto merge schedule */}} {{if $canMergeNow}} {{if $notAllOverridableChecksOk}} <div class="item"> {{svg "octicon-dot-fill"}} {{ctx.Locale.Tr "repo.pulls.required_status_check_administrator"}} </div> {{else}} <div class="item"> {{svg "octicon-check"}} {{ctx.Locale.Tr "repo.pulls.can_auto_merge_desc"}} </div> {{end}} {{if .WillSign}} <div class="item"> {{svg "octicon-lock" 16 "text green"}} {{ctx.Locale.Tr "repo.signing.will_sign" .SigningKey}} </div> {{else if .IsSigned}} <div class="item"> {{svg "octicon-unlock"}} {{ctx.Locale.Tr (printf "repo.signing.wont_sign.%s" .WontSignReason)}} </div> {{end}} {{end}} {{template "repo/issue/view_content/update_branch_by_merge" $}} {{if .Issue.PullRequest.IsEmpty}} <div class="divider"></div> <div class="item"> {{svg "octicon-alert"}} {{ctx.Locale.Tr "repo.pulls.is_empty"}} </div> {{end}} {{if .AllowMerge}} {{/* user is allowed to merge */}} {{$prUnit := .Repository.MustGetUnit $.Context ctx.Consts.RepoUnitTypePullRequests}} {{$approvers := (.Issue.PullRequest.GetApprovers ctx)}} {{if or $prUnit.PullRequestsConfig.AllowMerge $prUnit.PullRequestsConfig.AllowRebase $prUnit.PullRequestsConfig.AllowRebaseMerge $prUnit.PullRequestsConfig.AllowSquash $prUnit.PullRequestsConfig.AllowFastForwardOnly}} {{$hasPendingPullRequestMergeTip := ""}} {{if .HasPendingPullRequestMerge}} {{$createdPRMergeStr := TimeSinceUnix .PendingPullRequestMerge.CreatedUnix ctx.Locale}} {{$hasPendingPullRequestMergeTip = ctx.Locale.Tr "repo.pulls.auto_merge_has_pending_schedule" .PendingPullRequestMerge.Doer.Name $createdPRMergeStr}} {{end}} <div class="divider"></div> <script type="module"> const issueUrl = window.location.origin + {{$.Issue.Link}}; const defaultMergeTitle = {{.DefaultMergeMessage}}; const defaultSquashMergeTitle = {{.DefaultSquashMergeMessage}}; const defaultMergeMessage = {{if .DefaultMergeBody}}{{.DefaultMergeBody}}{{else}}`Reviewed-on: ${issueUrl}\n` + {{$approvers}}{{end}}; const defaultSquashMergeMessage = {{if .DefaultSquashMergeBody}}{{.DefaultSquashMergeBody}}{{else}}`Reviewed-on: ${issueUrl}\n` + {{$approvers}}{{end}}; const mergeForm = { 'baseLink': {{.Link}}, 'textCancel': {{ctx.Locale.Tr "cancel"}}, 'textDeleteBranch': {{ctx.Locale.Tr "repo.branch.delete" .HeadTarget}}, 'textAutoMergeButtonWhenSucceed': {{ctx.Locale.Tr "repo.pulls.auto_merge_button_when_succeed"}}, 'textAutoMergeWhenSucceed': {{ctx.Locale.Tr "repo.pulls.auto_merge_when_succeed"}}, 'textAutoMergeCancelSchedule': {{ctx.Locale.Tr "repo.pulls.auto_merge_cancel_schedule"}}, 'textClearMergeMessage': {{ctx.Locale.Tr "repo.pulls.clear_merge_message"}}, 'textClearMergeMessageHint': {{ctx.Locale.Tr "repo.pulls.clear_merge_message_hint"}}, 'textMergeCommitId': {{ctx.Locale.Tr "repo.pulls.merge_commit_id"}}, 'canMergeNow': {{$canMergeNow}}, 'allOverridableChecksOk': {{not $notAllOverridableChecksOk}}, 'emptyCommit': {{.Issue.PullRequest.IsEmpty}}, 'pullHeadCommitID': {{.PullHeadCommitID}}, 'isPullBranchDeletable': {{.IsPullBranchDeletable}}, 'defaultMergeStyle': {{.MergeStyle}}, 'defaultDeleteBranchAfterMerge': {{$prUnit.PullRequestsConfig.DefaultDeleteBranchAfterMerge}}, 'mergeMessageFieldPlaceHolder': {{ctx.Locale.Tr "repo.editor.commit_message_desc"}}, 'defaultMergeMessage': defaultMergeMessage, 'hasPendingPullRequestMerge': {{.HasPendingPullRequestMerge}}, 'hasPendingPullRequestMergeTip': {{$hasPendingPullRequestMergeTip}}, }; const generalHideAutoMerge = mergeForm.canMergeNow && mergeForm.allOverridableChecksOk; // if this pr can be merged now, then hide the auto merge mergeForm['mergeStyles'] = [ { 'name': 'merge', 'allowed': {{$prUnit.PullRequestsConfig.AllowMerge}}, 'textDoMerge': {{ctx.Locale.Tr "repo.pulls.merge_pull_request"}}, 'mergeTitleFieldText': defaultMergeTitle, 'mergeMessageFieldText': defaultMergeMessage, 'hideAutoMerge': generalHideAutoMerge, }, { 'name': 'rebase', 'allowed': {{$prUnit.PullRequestsConfig.AllowRebase}}, 'textDoMerge': {{ctx.Locale.Tr "repo.pulls.rebase_merge_pull_request"}}, 'hideMergeMessageTexts': true, 'hideAutoMerge': generalHideAutoMerge, }, { 'name': 'rebase-merge', 'allowed': {{$prUnit.PullRequestsConfig.AllowRebaseMerge}}, 'textDoMerge': {{ctx.Locale.Tr "repo.pulls.rebase_merge_commit_pull_request"}}, 'mergeTitleFieldText': defaultMergeTitle, 'mergeMessageFieldText': defaultMergeMessage, 'hideAutoMerge': generalHideAutoMerge, }, { 'name': 'squash', 'allowed': {{$prUnit.PullRequestsConfig.AllowSquash}}, 'textDoMerge': {{ctx.Locale.Tr "repo.pulls.squash_merge_pull_request"}}, 'mergeTitleFieldText': defaultSquashMergeTitle, 'mergeMessageFieldText': {{.GetCommitMessages}} + defaultSquashMergeMessage, 'hideAutoMerge': generalHideAutoMerge, }, { 'name': 'fast-forward-only', 'allowed': {{and $prUnit.PullRequestsConfig.AllowFastForwardOnly (eq .Issue.PullRequest.CommitsBehind 0)}}, 'textDoMerge': {{ctx.Locale.Tr "repo.pulls.fast_forward_only_merge_pull_request"}}, 'hideMergeMessageTexts': true, 'hideAutoMerge': generalHideAutoMerge, }, { 'name': 'manually-merged', 'allowed': {{$prUnit.PullRequestsConfig.AllowManualMerge}}, 'textDoMerge': {{ctx.Locale.Tr "repo.pulls.merge_manually"}}, 'hideMergeMessageTexts': true, 'hideAutoMerge': true, } ]; window.config.pageData.pullRequestMergeForm = mergeForm; </script> {{$showGeneralMergeForm = true}} <div id="pull-request-merge-form"></div> {{else}} {{/* no merge style was set in repo setting: not or ($prUnit.PullRequestsConfig.AllowMerge ...) */}} <div class="divider"></div> <div class="item text red"> {{svg "octicon-x"}} {{ctx.Locale.Tr "repo.pulls.no_merge_desc"}} </div> <div class="item"> {{svg "octicon-info"}} {{ctx.Locale.Tr "repo.pulls.no_merge_helper"}} </div> {{end}} {{/* end if the repo was set to use any merge style */}} {{else}} {{/* user is not allowed to merge */}} <div class="divider"></div> <div class="item"> {{svg "octicon-info"}} {{ctx.Locale.Tr "repo.pulls.no_merge_access"}} </div> {{end}} {{/* end if user is allowed to merge or not */}} {{else}} {{/* Merge conflict without specific file. Suggest manual merge, only if all reviews and status checks OK. */}} {{if .IsBlockedByApprovals}} <div class="item text red"> {{svg "octicon-x"}} {{ctx.Locale.Tr "repo.pulls.blocked_by_approvals" .GrantedApprovals .ProtectedBranch.RequiredApprovals}} </div> {{else if .IsBlockedByRejection}} <div class="item text red"> {{svg "octicon-x"}} {{ctx.Locale.Tr "repo.pulls.blocked_by_rejection"}} </div> {{else if .IsBlockedByOfficialReviewRequests}} <div class="item text red"> {{svg "octicon-x"}} {{ctx.Locale.Tr "repo.pulls.blocked_by_official_review_requests"}} </div> {{else if .IsBlockedByOutdatedBranch}} <div class="item text red"> {{svg "octicon-x"}} {{ctx.Locale.Tr "repo.pulls.blocked_by_outdated_branch"}} </div> {{else if .IsBlockedByChangedProtectedFiles}} <div class="item text red"> {{svg "octicon-x"}} {{ctx.Locale.TrN $.ChangedProtectedFilesNum "repo.pulls.blocked_by_changed_protected_files_1" "repo.pulls.blocked_by_changed_protected_files_n"}} </div> <ul> {{range .ChangedProtectedFiles}} <li>{{.}}</li> {{end}} </ul> {{else if and .EnableStatusCheck (not .RequiredStatusCheckState.IsSuccess)}} <div class="item text red"> {{svg "octicon-x"}} {{ctx.Locale.Tr "repo.pulls.required_status_check_failed"}} </div> {{else if and .RequireSigned (not .WillSign)}} <div class="item text red"> {{svg "octicon-x"}} {{ctx.Locale.Tr "repo.pulls.require_signed_wont_sign"}} </div> {{else}} <div class="item text red"> {{svg "octicon-x"}} {{ctx.Locale.Tr "repo.pulls.cannot_auto_merge_desc"}} </div> <div class="item"> {{svg "octicon-info"}} {{ctx.Locale.Tr "repo.pulls.cannot_auto_merge_helper"}} </div> {{end}} {{end}}{{/* end if: pull request status */}} {{/* Manually Merged is not a well-known feature, it is used to mark a non-mergeable PR (already merged, conflicted) as merged To test it: * Enable "Manually Merged" feature in the Repository Settings * Create a pull request, either: * - Merge the pull request branch locally and push the merged commit to Gitea * - Make some conflicts between the base branch and the pull request branch * Then the Manually Merged form will be shown in the merge form */}} {{if and $.StillCanManualMerge (not $showGeneralMergeForm)}} <div class="divider"></div> <form class="ui form form-fetch-action" action="{{.Link}}/merge" method="post">{{/* another similar form is in PullRequestMergeForm.vue*/}} {{.CsrfTokenHtml}} <div class="field"> <input type="text" name="merge_commit_id" placeholder="{{ctx.Locale.Tr "repo.pulls.merge_commit_id"}}"> </div> <button class="ui red button" type="submit" name="do" value="manually-merged"> {{ctx.Locale.Tr "repo.pulls.merge_manually"}} </button> </form> {{end}} {{if and .Issue.PullRequest.HeadRepo (not .Issue.PullRequest.HasMerged) (not .Issue.IsClosed)}} {{template "repo/issue/view_content/pull_merge_instruction" dict "PullRequest" .Issue.PullRequest "ShowMergeInstructions" .ShowMergeInstructions}} {{end}} </div> </div> </div> {{end}}