Merge branch 'master' into remove_user_as_assignee_after_collaboration_removal

This commit is contained in:
Lanre Adelowo 2020-01-11 17:20:07 +01:00 committed by GitHub
commit 5905ed9f9f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 498 additions and 180 deletions

130
cmd/doctor.go Normal file
View File

@ -0,0 +1,130 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package cmd
import (
"bufio"
"errors"
"fmt"
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
"code.gitea.io/gitea/modules/setting"
"github.com/urfave/cli"
)
// CmdDoctor represents the available doctor sub-command.
var CmdDoctor = cli.Command{
Name: "doctor",
Usage: "Diagnose the problems",
Description: "A command to diagnose the problems of current gitea instance according the given configuration.",
Action: runDoctor,
}
type check struct {
title string
f func(ctx *cli.Context) ([]string, error)
}
// checklist represents list for all checks
var checklist = []check{
{
title: "Check if OpenSSH authorized_keys file id correct",
f: runDoctorLocationMoved,
},
// more checks please append here
}
func runDoctor(ctx *cli.Context) error {
err := initDB()
fmt.Println("Using app.ini at", setting.CustomConf)
if err != nil {
fmt.Println(err)
fmt.Println("Check if you are using the right config file. You can use a --config directive to specify one.")
return nil
}
for i, check := range checklist {
fmt.Println("[", i+1, "]", check.title)
if messages, err := check.f(ctx); err != nil {
fmt.Println("Error:", err)
} else if len(messages) > 0 {
for _, message := range messages {
fmt.Println("-", message)
}
} else {
fmt.Println("OK.")
}
fmt.Println()
}
return nil
}
func exePath() (string, error) {
file, err := exec.LookPath(os.Args[0])
if err != nil {
return "", err
}
return filepath.Abs(file)
}
func runDoctorLocationMoved(ctx *cli.Context) ([]string, error) {
if setting.SSH.StartBuiltinServer || !setting.SSH.CreateAuthorizedKeysFile {
return nil, nil
}
fPath := filepath.Join(setting.SSH.RootPath, "authorized_keys")
f, err := os.Open(fPath)
if err != nil {
return nil, err
}
defer f.Close()
var firstline string
scanner := bufio.NewScanner(f)
for scanner.Scan() {
firstline = strings.TrimSpace(scanner.Text())
if len(firstline) == 0 || firstline[0] == '#' {
continue
}
break
}
// command="/Volumes/data/Projects/gitea/gitea/gitea --config
if len(firstline) > 0 {
exp := regexp.MustCompile(`^[ \t]*(?:command=")([^ ]+) --config='([^']+)' serv key-([^"]+)",(?:[^ ]+) ssh-rsa ([^ ]+) ([^ ]+)[ \t]*$`)
// command="/home/user/gitea --config='/home/user/etc/app.ini' serv key-999",option-1,option-2,option-n ssh-rsa public-key-value key-name
res := exp.FindStringSubmatch(firstline)
if res == nil {
return nil, errors.New("Unknow authorized_keys format")
}
giteaPath := res[1] // => /home/user/gitea
iniPath := res[2] // => /home/user/etc/app.ini
p, err := exePath()
if err != nil {
return nil, err
}
p, err = filepath.Abs(p)
if err != nil {
return nil, err
}
if len(giteaPath) > 0 && giteaPath != p {
return []string{fmt.Sprintf("Gitea exe path wants %s but %s on %s", p, giteaPath, fPath)}, nil
}
if len(iniPath) > 0 && iniPath != setting.CustomConf {
return []string{fmt.Sprintf("Gitea config path wants %s but %s on %s", setting.CustomConf, iniPath, fPath)}, nil
}
}
return nil, nil
}

View File

@ -289,3 +289,28 @@ This command is idempotent.
#### convert
Converts an existing MySQL database from utf8 to utf8mb4.
#### doctor
Diagnose the problems of current gitea instance according the given configuration.
Currently there are a check list below:
- Check if OpenSSH authorized_keys file id correct
When your gitea instance support OpenSSH, your gitea instance binary path will be written to `authorized_keys`
when there is any public key added or changed on your gitea instance.
Sometimes if you moved or renamed your gitea binary when upgrade and you haven't run `Update the '.ssh/authorized_keys' file with Gitea SSH keys. (Not needed for the built-in SSH server.)` on your Admin Panel. Then all pull/push via SSH will not be work.
This check will help you to check if it works well.
For contributors, if you want to add more checks, you can wrie ad new function like `func(ctx *cli.Context) ([]string, error)` and
append it to `doctor.go`.
```go
var checklist = []check{
{
title: "Check if OpenSSH authorized_keys file id correct",
f: runDoctorLocationMoved,
},
// more checks please append here
}
```
This function will receive a command line context and return a list of details about the problems or error.

View File

@ -68,6 +68,7 @@ arguments - which can alternatively be run by running the subcommand web.`
cmd.CmdMigrate,
cmd.CmdKeys,
cmd.CmdConvert,
cmd.CmdDoctor,
}
// Now adjust these commands to add our global configuration options

View File

@ -93,8 +93,8 @@ func (protectBranch *ProtectedBranch) CanUserPush(userID int64) bool {
return in
}
// CanUserMerge returns if some user could merge a pull request to this protected branch
func (protectBranch *ProtectedBranch) CanUserMerge(userID int64) bool {
// IsUserMergeWhitelisted checks if some user is whitelisted to merge to this branch
func (protectBranch *ProtectedBranch) IsUserMergeWhitelisted(userID int64) bool {
if !protectBranch.EnableMergeWhitelist {
return true
}
@ -348,27 +348,6 @@ func (repo *Repository) IsProtectedBranchForPush(branchName string, doer *User)
return false, nil
}
// IsProtectedBranchForMerging checks if branch is protected for merging
func (repo *Repository) IsProtectedBranchForMerging(pr *PullRequest, branchName string, doer *User) (bool, error) {
if doer == nil {
return true, nil
}
protectedBranch := &ProtectedBranch{
RepoID: repo.ID,
BranchName: branchName,
}
has, err := x.Get(protectedBranch)
if err != nil {
return true, err
} else if has {
return !protectedBranch.CanUserMerge(doer.ID) || !protectedBranch.HasEnoughApprovals(pr) || protectedBranch.MergeBlockedByRejectedReview(pr), nil
}
return false, nil
}
// updateApprovalWhitelist checks whether the user whitelist changed and returns a whitelist with
// the users from newWhitelist which have explicit read or write access to the repo.
func updateApprovalWhitelist(repo *Repository, currentWhitelist, newWhitelist []int64) (whitelist []int64, err error) {

View File

@ -403,11 +403,12 @@ func (issue *Issue) apiFormat(e Engine) *api.Issue {
apiIssue.Closed = issue.ClosedUnix.AsTimePtr()
}
issue.loadMilestone(e)
if issue.Milestone != nil {
apiIssue.Milestone = issue.Milestone.APIFormat()
}
issue.loadAssignees(e)
issue.loadAssignees(e)
if len(issue.Assignees) > 0 {
for _, assignee := range issue.Assignees {
apiIssue.Assignees = append(apiIssue.Assignees, assignee.APIFormat())

View File

@ -8,7 +8,6 @@ import (
"time"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"xorm.io/builder"
"xorm.io/xorm"
@ -60,25 +59,6 @@ func (t *TrackedTime) loadAttributes(e Engine) (err error) {
return
}
// APIFormat converts TrackedTime to API format
func (t *TrackedTime) APIFormat() (apiT *api.TrackedTime) {
apiT = &api.TrackedTime{
ID: t.ID,
IssueID: t.IssueID,
UserID: t.UserID,
UserName: t.User.Name,
Time: t.Time,
Created: t.Created,
}
if t.Issue != nil {
apiT.Issue = t.Issue.APIFormat()
}
if t.User != nil {
apiT.UserName = t.User.Name
}
return
}
// LoadAttributes load Issue, User
func (tl TrackedTimeList) LoadAttributes() (err error) {
for _, t := range tl {
@ -89,15 +69,6 @@ func (tl TrackedTimeList) LoadAttributes() (err error) {
return
}
// APIFormat converts TrackedTimeList to API format
func (tl TrackedTimeList) APIFormat() api.TrackedTimeList {
result := make([]*api.TrackedTime, 0, len(tl))
for _, t := range tl {
result = append(result, t.APIFormat())
}
return result
}
// FindTrackedTimesOptions represent the filters for tracked times. If an ID is 0 it will be ignored.
type FindTrackedTimesOptions struct {
IssueID int64

View File

@ -479,31 +479,6 @@ const (
MergeStyleSquash MergeStyle = "squash"
)
// CheckUserAllowedToMerge checks whether the user is allowed to merge
func (pr *PullRequest) CheckUserAllowedToMerge(doer *User) (err error) {
if doer == nil {
return ErrNotAllowedToMerge{
"Not signed in",
}
}
if pr.BaseRepo == nil {
if err = pr.GetBaseRepo(); err != nil {
return fmt.Errorf("GetBaseRepo: %v", err)
}
}
if protected, err := pr.BaseRepo.IsProtectedBranchForMerging(pr, pr.BaseBranch, doer); err != nil {
return fmt.Errorf("IsProtectedBranch: %v", err)
} else if protected {
return ErrNotAllowedToMerge{
"The branch is protected",
}
}
return nil
}
// SetMerged sets a pull request to merged and closes the corresponding issue
func (pr *PullRequest) SetMerged() (err error) {
if pr.HasMerged {

View File

@ -271,7 +271,7 @@ func getUserRepoPermission(e Engine, repo *Repository, user *User) (perm Permiss
return
}
// IsUserRepoAdmin return ture if user has admin right of a repo
// IsUserRepoAdmin return true if user has admin right of a repo
func IsUserRepoAdmin(repo *Repository, user *User) (bool, error) {
return isUserRepoAdmin(x, repo, user)
}

View File

@ -503,7 +503,7 @@ func (u *User) ValidatePassword(passwd string) bool {
// IsPasswordSet checks if the password is set or left empty
func (u *User) IsPasswordSet() bool {
return len(u.Passwd) > 0
return !u.ValidatePassword("")
}
// UploadAvatar saves custom avatar for user.

View File

@ -448,6 +448,7 @@ type MergePullRequestForm struct {
Do string `binding:"Required;In(merge,rebase,rebase-merge,squash)"`
MergeTitleField string
MergeMessageField string
ForceMerge *bool `json:"force_merge,omitempty"`
}
// Validate validates the fields

View File

@ -51,7 +51,7 @@ func ToBranch(repo *models.Repository, b *git.Branch, c *git.Commit, bp *models.
EnableStatusCheck: bp.EnableStatusCheck,
StatusCheckContexts: bp.StatusCheckContexts,
UserCanPush: bp.CanUserPush(user.ID),
UserCanMerge: bp.CanUserMerge(user.ID),
UserCanMerge: bp.IsUserMergeWhitelisted(user.ID),
}
}

38
modules/convert/issue.go Normal file
View File

@ -0,0 +1,38 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package convert
import (
"code.gitea.io/gitea/models"
api "code.gitea.io/gitea/modules/structs"
)
// ToTrackedTime converts TrackedTime to API format
func ToTrackedTime(t *models.TrackedTime) (apiT *api.TrackedTime) {
apiT = &api.TrackedTime{
ID: t.ID,
IssueID: t.IssueID,
UserID: t.UserID,
UserName: t.User.Name,
Time: t.Time,
Created: t.Created,
}
if t.Issue != nil {
apiT.Issue = t.Issue.APIFormat()
}
if t.User != nil {
apiT.UserName = t.User.Name
}
return
}
// ToTrackedTimeList converts TrackedTimeList to API format
func ToTrackedTimeList(tl models.TrackedTimeList) api.TrackedTimeList {
result := make([]*api.TrackedTime, 0, len(tl))
for _, t := range tl {
result = append(result, ToTrackedTime(t))
}
return result
}

View File

@ -138,9 +138,11 @@ func UpdateIssuesCommit(doer *models.User, repo *models.Repository, commits []*r
continue
}
}
if err := changeIssueStatus(refRepo, refIssue, doer, ref.Action == references.XRefActionCloses); err != nil {
return err
close := (ref.Action == references.XRefActionCloses)
if close != refIssue.IsClosed {
if err := changeIssueStatus(refRepo, refIssue, doer, close); err != nil {
return err
}
}
}
}

View File

@ -1036,7 +1036,6 @@ pulls.cannot_auto_merge_helper=Pro vyřešení konfliktů proveďte ruční slou
pulls.no_merge_desc=Tento požadavek na natažení nemůže být sloučen, protože všechny možnosti repozitáře na sloučení jsou zakázány.
pulls.no_merge_helper=Povolte možnosti sloučení v nastavení repozitáře nebo proveďte sloučení požadavku na natažení ručně.
pulls.no_merge_wip=Požadavek na natažení nemůže být sloučen protože je označen jako nedokončený.
pulls.no_merge_status_check=Tento požadavek na natažení nemůže být sloučen, protože ne všechny požadované kontroly stavu byly úspěšné.
pulls.merge_pull_request=Sloučit požadavek na natažení
pulls.rebase_merge_pull_request=Rebase a sloučit
pulls.rebase_merge_commit_pull_request=Rebase a sloučit (--no-ff)

View File

@ -1061,7 +1061,6 @@ pulls.cannot_auto_merge_helper=Bitte manuell zusammenführen, um die Konflikte z
pulls.no_merge_desc=Dieser Pull-Request kann nicht gemerged werden, da keine Mergeoptionen aktiviert sind.
pulls.no_merge_helper=Aktiviere Mergeoptionen in den Repositoryeinstellungen oder merge den Pull-Request manuell.
pulls.no_merge_wip=Dieser Pull Request kann nicht zusammengeführt werden, da er als Work In Progress gekennzeichnet ist.
pulls.no_merge_status_check=Dieser Pull-Request kann nicht zusammengeführt werden, da nicht alle erforderlichen Statusprüfungen erfolgreich waren.
pulls.merge_pull_request=Pull-Request zusammenführen
pulls.rebase_merge_pull_request=Rebase und Mergen
pulls.rebase_merge_commit_pull_request=Rebasen und Mergen (--no-ff)

View File

@ -1062,7 +1062,8 @@ pulls.cannot_auto_merge_helper = Merge manually to resolve the conflicts.
pulls.no_merge_desc = This pull request cannot be merged because all repository merge options are disabled.
pulls.no_merge_helper = Enable merge options in the repository settings or merge the pull request manually.
pulls.no_merge_wip = This pull request can not be merged because it is marked as being a work in progress.
pulls.no_merge_status_check = This pull request cannot be merged because not all required status checkes are successful.
pulls.no_merge_not_ready = This pull request is not ready to be merged, check review status and status checks.
pulls.no_merge_access = You are not authorized to merge this pull request.
pulls.merge_pull_request = Merge Pull Request
pulls.rebase_merge_pull_request = Rebase and Merge
pulls.rebase_merge_commit_pull_request = Rebase and Merge (--no-ff)

View File

@ -1057,7 +1057,6 @@ pulls.cannot_auto_merge_helper=Combinar manualmente para resolver los conflictos
pulls.no_merge_desc=Este pull request no se puede combinar porque todas las opciones de combinación del repositorio están deshabilitadas.
pulls.no_merge_helper=Habilite las opciones de combinación en la configuración del repositorio o fusione el pull request manualmente.
pulls.no_merge_wip=Este pull request no se puede combinar porque está marcada como un trabajo en progreso.
pulls.no_merge_status_check=No se puede fusionar este pull request porque no todas las comprobaciones de estado requeridas resultaron exitosas.
pulls.merge_pull_request=Fusionar Pull Request
pulls.rebase_merge_pull_request=Hacer Rebase y Fusionar
pulls.rebase_merge_commit_pull_request=Hacer Rebase y Fusionar (--no-ff)

View File

@ -1062,7 +1062,6 @@ pulls.cannot_auto_merge_helper=به صورتی دستی ادغام کنید تا
pulls.no_merge_desc=این تقاضای واکشی قابل ادغام نیست لذا تمامی گزینه های ادغام مخزن غیر فعال هستند.
pulls.no_merge_helper=گزینه های ادغام را در تنظیمات مخزن فعال کنید یا از تقاضای واکشی به صورت دستی ادغام نمایید.
pulls.no_merge_wip=این تقاضای واکشی قابل ادغام نیست لذا اکنون به این مخزن درحال پردازش علامت گذاری شده است.
pulls.no_merge_status_check=این تقاضای واکشی نمی‌تواند ادغام شود لذا تمامی حالت های ضروری با موفقیت بررسی نشدند.
pulls.merge_pull_request=ادغام تقاضای واکشی
pulls.rebase_merge_pull_request=بازگردانی و ادغام
pulls.rebase_merge_commit_pull_request=بازگردانی و ادغام (--no-ff)

View File

@ -1054,7 +1054,6 @@ pulls.cannot_auto_merge_helper=Fusionner manuellement pour résoudre les conflit
pulls.no_merge_desc=Cette demande de fusion ne peut être appliquée directement car toutes les options de fusion du dépôt sont désactivées.
pulls.no_merge_helper=Activez des options de fusion dans les paramètres du dépôt ou fusionnez la demande manuellement.
pulls.no_merge_wip=Cette demande d'ajout ne peut pas être fusionnée car elle est marquée comme en cours de chantier.
pulls.no_merge_status_check=Cette demande de pull ne peut pas être fusionnée car tous les contrôles de statut requis ne sont pas réussis.
pulls.merge_pull_request=Fusionner la demande d'ajout
pulls.rebase_merge_pull_request=Rebase et fusionner
pulls.rebase_merge_commit_pull_request=Rebase et Fusion (--no-ff)

View File

@ -1061,7 +1061,8 @@ pulls.cannot_auto_merge_helper=コンフリクトを解消するため手動で
pulls.no_merge_desc=リポジトリのマージオプションがすべて無効になっているため、このプルリクエストをマージすることはできせん。
pulls.no_merge_helper=リポジトリ設定でマージを有効にするか、手動でマージしてください。
pulls.no_merge_wip=このプルリクエストはWork in Progressとマークされているため、マージすることはできません。
pulls.no_merge_status_check=すべての必要なステータスチェックが成功していないため、このプルリクエストはマージできません。
pulls.no_merge_not_ready=このプルリクエストはマージする準備ができていません。 レビュー状況とステータスチェックを確認してください。
pulls.no_merge_access=このプルリクエストをマージする権限がありません。
pulls.merge_pull_request=プルリクエストをマージ
pulls.rebase_merge_pull_request=リベースしてマージ
pulls.rebase_merge_commit_pull_request=リベースしてマージ(--no-ff)
@ -1412,6 +1413,8 @@ settings.protect_approvals_whitelist_enabled=ホワイトリストに登録し
settings.protect_approvals_whitelist_enabled_desc=ホワイトリストに登録したユーザーやチームによるレビューのみを、必要な承認とみなします。 承認のホワイトリストが無い場合は、書き込み権限がある人によるレビューを必要な承認とみなします。
settings.protect_approvals_whitelist_users=ホワイトリストに含めるレビューア:
settings.protect_approvals_whitelist_teams=ホワイトリストに含めるレビューチーム:
settings.dismiss_stale_approvals=古くなった承認を取り消す
settings.dismiss_stale_approvals_desc=プルリクエストの内容を変える新たなコミットがブランチにプッシュされた場合、以前の承認を取り消します。
settings.add_protected_branch=保護を有効にする
settings.delete_protected_branch=保護を無効にする
settings.update_protect_branch_success=ブランチ '%s' の保護を更新しました。
@ -2025,8 +2028,54 @@ monitor.execute_time=実行時間
monitor.process.cancel=処理をキャンセル
monitor.process.cancel_desc=処理をキャンセルするとデータが失われる可能性があります
monitor.process.cancel_notices=キャンセル: <strong>%s</strong>?
monitor.queues=キュー
monitor.queue=キュー: %s
monitor.queue.name=キュー名
monitor.queue.type=種類
monitor.queue.exemplar=要素の型
monitor.queue.numberworkers=ワーカー数
monitor.queue.maxnumberworkers=ワーカー数上限
monitor.queue.review=設定確認
monitor.queue.review_add=確認/ワーカー追加
monitor.queue.configuration=初期設定
monitor.queue.nopool.title=ワーカープールはありません
monitor.queue.nopool.desc=このキューは他のキューをラップし、これ自体にはワーカープールがありません。
monitor.queue.wrapped.desc=wrappedキューは、すぐに開始されないキューをラップし、入ってきたリクエストをチャンネルにバッファリングします。 これ自体にはワーカープールがありません。
monitor.queue.persistable-channel.desc=persistable-channelキューは二つのキューをラップします。 一つはchannelキューで、自分のワーカープールを持ちます。もう一つはlevelキューで、前回のシャットダウンからリクエストを引き継ぐためのものです。 これ自体にはワーカープールがありません。
monitor.queue.pool.timeout=タイムアウト
monitor.queue.pool.addworkers.title=ワーカーの追加
monitor.queue.pool.addworkers.submit=ワーカーを追加
monitor.queue.pool.addworkers.desc=このプールに、タイムアウト付きまたはタイムアウト無しでワーカーを追加します。 タイムアウトを指定した場合は、タイムアウト後にそれらのワーカーがこのプールから取り除かれます。
monitor.queue.pool.addworkers.numberworkers.placeholder=ワーカー数
monitor.queue.pool.addworkers.timeout.placeholder=0でタイムアウト無し
monitor.queue.pool.addworkers.mustnumbergreaterzero=追加するワーカー数は1以上にしてください
monitor.queue.pool.addworkers.musttimeoutduration=タイムアウトは 、Go言語の時間差表記(例 5m)、または0にしてください
monitor.queue.settings.title=プール設定
monitor.queue.settings.desc=ワーカーへのキューのブロックが発生すると、それに応じてプール数がブースト分ずつ動的に増えます。 これらの変更は現在のワーカーグループには影響しません。
monitor.queue.settings.timeout=ブースト分のタイムアウト
monitor.queue.settings.timeout.placeholder=現在の設定 %[1]v
monitor.queue.settings.timeout.error=タイムアウトは 、Go言語の時間差表記(例 5m)、または0にしてください
monitor.queue.settings.numberworkers=ブースト分のワーカー数
monitor.queue.settings.numberworkers.placeholder=現在の設定 %[1]d
monitor.queue.settings.numberworkers.error=追加するワーカー数はゼロ以上にしてください
monitor.queue.settings.maxnumberworkers=ワーカー数上限
monitor.queue.settings.maxnumberworkers.placeholder=現在の設定 %[1]d
monitor.queue.settings.maxnumberworkers.error=ワーカー数上限は数値にしてください
monitor.queue.settings.submit=設定を更新
monitor.queue.settings.changed=設定を更新しました
monitor.queue.settings.blocktimeout=現在のブロックタイムアウト
monitor.queue.settings.blocktimeout.value=%[1]v
monitor.queue.pool.none=このキューにはプールがありません
monitor.queue.pool.added=ワーカーグループを追加しました
monitor.queue.pool.max_changed=ワーカー数の上限を変更しました
monitor.queue.pool.workers.title=アクティブなワーカーグループ
monitor.queue.pool.workers.none=ワーカーグループはありません。
monitor.queue.pool.cancel=ワーカーグループのシャットダウン
monitor.queue.pool.cancelling=ワーカーグループをシャットダウンしています
monitor.queue.pool.cancel_notices=このワーカー数 %s のグループをシャットダウンしますか?
monitor.queue.pool.cancel_desc=キューをワーカーグループ無しのままにすると、リクエストがブロックし続ける原因となります。
notices.system_notice_list=システム通知
notices.view_detail_header=通知の詳細を表示

View File

@ -1061,7 +1061,6 @@ pulls.cannot_auto_merge_helper=Sapludiniet manuāli, lai atrisinātu konfliktus.
pulls.no_merge_desc=Šo izmaiņu pieprasījumu nav iespējams sapludināt, jo nav atļauts neviens sapludināšanas veids.
pulls.no_merge_helper=Lai sapludinātu šo izmaiņu pieprasījumu, iespējojiet vismaz vienu sapludināšanas veidu repozitorija iestatījumos vai sapludiniet to manuāli.
pulls.no_merge_wip=Šo izmaiņu pieprasījumu nav iespējams sapludināt, jo tas ir atzīmēts, ka darbs pie tā vēl nav pabeigts.
pulls.no_merge_status_check=Šo izmaiņu pieprasījumu nevar saplusināt, jo nav veiksmīgi izildītas visas obligātas statusa pārbaudes.
pulls.merge_pull_request=Izmaiņu pieprasījuma sapludināšana
pulls.rebase_merge_pull_request=Pārbāzēt un sapludināt
pulls.rebase_merge_commit_pull_request=Pārbāzēt un sapludināt (--no-ff)

View File

@ -1055,7 +1055,6 @@ pulls.cannot_auto_merge_helper=Scal ręcznie, aby rozwiązać konflikty.
pulls.no_merge_desc=Ten Pull Request nie może zostać scalony, ponieważ wszystkie opcje scalania dla tego repozytorium są wyłączone.
pulls.no_merge_helper=Włącz opcje scalania w ustawieniach repozytorium, lub scal ten Pull Request ręcznie.
pulls.no_merge_wip=Ten pull request nie może być automatycznie scalony, ponieważ jest oznaczony jako praca w toku.
pulls.no_merge_status_check=Ten Pull Request nie może być scalony, bo nie wszystkie kontrole stanów były pomyślne.
pulls.merge_pull_request=Scal Pull Request
pulls.rebase_merge_pull_request=Zmień bazę i scal
pulls.rebase_merge_commit_pull_request=Zmień bazę i scal (--no-ff)

View File

@ -1061,7 +1061,6 @@ pulls.cannot_auto_merge_helper=Faça o merge manualmente para resolver os confli
pulls.no_merge_desc=O merge deste pull request não pode ser aplicado porque todas as opções de mesclagem do repositório estão desabilitadas.
pulls.no_merge_helper=Habilite as opções de merge nas configurações do repositório ou faça o merge do pull request manualmente.
pulls.no_merge_wip=O merge deste pull request não pode ser aplicado porque está marcado como um trabalho em andamento.
pulls.no_merge_status_check=Este pull request não pode ter seu merge aplicado porque nem todas as verificações de status necessárias foram bem sucedidas.
pulls.merge_pull_request=Aplicar merge do pull request
pulls.rebase_merge_pull_request=Aplicar Rebase e Merge
pulls.rebase_merge_commit_pull_request=Aplicar Rebase e Merge (--no-ff)

View File

@ -1054,7 +1054,6 @@ pulls.cannot_auto_merge_helper=Çakışmaları çözmek için el ile birleştiri
pulls.no_merge_desc=Tüm depo birleştirme seçenekleri devre dışı bırakıldığından, bu değişiklik isteği birleştirilemez.
pulls.no_merge_helper=Depo ayarlarındaki birleştirme seçeneklerini etkinleştirin veya değişiklik isteğini el ile birleştirin.
pulls.no_merge_wip=Bu değişiklik isteği birleştirilemez çünkü devam eden bir çalışma olarak işaretlendi.
pulls.no_merge_status_check=Gerekli olan tüm durum denetimleri başarılı olmadığından bu değişiklik isteği birleştirilemez.
pulls.merge_pull_request=Değişiklik İsteğini Birleştir
pulls.rebase_merge_pull_request=Rebase ve Merge
pulls.rebase_merge_commit_pull_request=Rebase ve Merge (--no-ff)

View File

@ -1058,7 +1058,6 @@ pulls.cannot_auto_merge_helper=Злийте вручну для вирішенн
pulls.no_merge_desc=Цей запити на злиття неможливо злити, оскільки всі параметри об'єднання репозиторія вимкнено.
pulls.no_merge_helper=Увімкніть параметри злиття в налаштуваннях репозиторія або злийте запити на злиття вручну.
pulls.no_merge_wip=Цей пулл-реквест не можливо об'єднати, тому-що він вже виконується.
pulls.no_merge_status_check=Не вдалося об'єднати цей запит на злиття, оскільки не всі обов'язкові перевірки були успішними.
pulls.merge_pull_request=Об'єднати запит на злиття
pulls.rebase_merge_pull_request=Зробити Rebase і злити
pulls.rebase_merge_commit_pull_request=Rebase та злитя (--no-ff)

View File

@ -1061,7 +1061,6 @@ pulls.cannot_auto_merge_helper=手动合并解决此冲突
pulls.no_merge_desc=由于未启用合并选项,此合并请求无法被合并。
pulls.no_merge_helper=在仓库设置中启用合并选项或者手工合并请求。
pulls.no_merge_wip=这个合并请求无法合并,因为被标记为尚未完成的工作。
pulls.no_merge_status_check=此合并请求不能合并,因为不是所有的状态检查都是成功的。
pulls.merge_pull_request=合并请求
pulls.rebase_merge_pull_request=变基并合并
pulls.rebase_merge_commit_pull_request=变基合并 (--no-ff)

View File

@ -12,6 +12,7 @@ import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/convert"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/routers/api/v1/utils"
)
@ -93,7 +94,7 @@ func ListTrackedTimes(ctx *context.APIContext) {
ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
return
}
ctx.JSON(http.StatusOK, trackedTimes.APIFormat())
ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(trackedTimes))
}
// AddTime add time manual to the given issue
@ -178,7 +179,7 @@ func AddTime(ctx *context.APIContext, form api.AddTimeOption) {
ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
return
}
ctx.JSON(http.StatusOK, trackedTime.APIFormat())
ctx.JSON(http.StatusOK, convert.ToTrackedTime(trackedTime))
}
// ResetIssueTime reset time manual to the given issue
@ -399,7 +400,7 @@ func ListTrackedTimesByUser(ctx *context.APIContext) {
ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
return
}
ctx.JSON(http.StatusOK, trackedTimes.APIFormat())
ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(trackedTimes))
}
// ListTrackedTimesByRepository lists all tracked times of the repository
@ -486,7 +487,7 @@ func ListTrackedTimesByRepository(ctx *context.APIContext) {
ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
return
}
ctx.JSON(http.StatusOK, trackedTimes.APIFormat())
ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(trackedTimes))
}
// ListMyTrackedTimes lists all tracked times of the current user
@ -530,5 +531,5 @@ func ListMyTrackedTimes(ctx *context.APIContext) {
return
}
ctx.JSON(http.StatusOK, trackedTimes.APIFormat())
ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(trackedTimes))
}

View File

@ -600,20 +600,43 @@ func MergePullRequest(ctx *context.APIContext, form auth.MergePullRequestForm) {
return
}
perm, err := models.GetUserRepoPermission(ctx.Repo.Repository, ctx.User)
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err)
return
}
allowedMerge, err := pull_service.IsUserAllowedToMerge(pr, perm, ctx.User)
if err != nil {
ctx.Error(http.StatusInternalServerError, "IsUSerAllowedToMerge", err)
return
}
if !allowedMerge {
ctx.Error(http.StatusMethodNotAllowed, "Merge", "User not allowed to merge PR")
return
}
if !pr.CanAutoMerge() || pr.HasMerged || pr.IsWorkInProgress() {
ctx.Status(http.StatusMethodNotAllowed)
return
}
isPass, err := pull_service.IsPullCommitStatusPass(pr)
if err != nil {
ctx.Error(http.StatusInternalServerError, "IsPullCommitStatusPass", err)
return
}
if !isPass && !ctx.IsUserRepoAdmin() {
ctx.Status(http.StatusMethodNotAllowed)
return
if err := pull_service.CheckPRReadyToMerge(pr); err != nil {
if !models.IsErrNotAllowedToMerge(err) {
ctx.Error(http.StatusInternalServerError, "CheckPRReadyToMerge", err)
return
}
if form.ForceMerge != nil && *form.ForceMerge {
if isRepoAdmin, err := models.IsUserRepoAdmin(pr.BaseRepo, ctx.User); err != nil {
ctx.Error(http.StatusInternalServerError, "IsUserRepoAdmin", err)
return
} else if !isRepoAdmin {
ctx.Error(http.StatusMethodNotAllowed, "Merge", "Only repository admin can merge if not all checks are ok (force merge)")
}
} else {
ctx.Error(http.StatusMethodNotAllowed, "PR is not ready to be merged", err)
return
}
}
if len(form.Do) == 0 {

View File

@ -319,7 +319,6 @@ func CreateOrgRepo(ctx *context.APIContext, opt api.CreateRepoOption) {
// swagger:operation POST /orgs/{org}/repos organization createOrgRepo
// ---
// summary: Create a repository in an organization
// deprecated: true
// consumes:
// - application/json
// produces:

View File

@ -17,6 +17,7 @@ import (
"code.gitea.io/gitea/modules/private"
"code.gitea.io/gitea/modules/repofiles"
"code.gitea.io/gitea/modules/util"
pull_service "code.gitea.io/gitea/services/pull"
"gitea.com/macaron/macaron"
)
@ -98,6 +99,7 @@ func HookPreReceive(ctx *macaron.Context, opts private.HookOptions) {
canPush = protectBranch.CanUserPush(opts.UserID)
}
if !canPush && opts.ProtectedBranchID > 0 {
// Manual merge
pr, err := models.GetPullRequestByID(opts.ProtectedBranchID)
if err != nil {
log.Error("Unable to get PullRequest %d Error: %v", opts.ProtectedBranchID, err)
@ -106,24 +108,55 @@ func HookPreReceive(ctx *macaron.Context, opts private.HookOptions) {
})
return
}
if !protectBranch.HasEnoughApprovals(pr) {
log.Warn("Forbidden: User %d cannot push to protected branch: %s in %-v and pr #%d does not have enough approvals", opts.UserID, branchName, repo, pr.Index)
ctx.JSON(http.StatusForbidden, map[string]interface{}{
"err": fmt.Sprintf("protected branch %s can not be pushed to and pr #%d does not have enough approvals", branchName, opts.ProtectedBranchID),
user, err := models.GetUserByID(opts.UserID)
if err != nil {
log.Error("Unable to get User id %d Error: %v", opts.UserID, err)
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"err": fmt.Sprintf("Unable to get User id %d Error: %v", opts.UserID, err),
})
return
}
if protectBranch.MergeBlockedByRejectedReview(pr) {
log.Warn("Forbidden: User %d cannot push to protected branch: %s in %-v and pr #%d has requested changes", opts.UserID, branchName, repo, pr.Index)
ctx.JSON(http.StatusForbidden, map[string]interface{}{
"err": fmt.Sprintf("protected branch %s can not be pushed to and pr #%d has requested changes", branchName, opts.ProtectedBranchID),
perm, err := models.GetUserRepoPermission(repo, user)
if err != nil {
log.Error("Unable to get Repo permission of repo %s/%s of User %s", repo.OwnerName, repo.Name, user.Name, err)
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"err": fmt.Sprintf("Unable to get Repo permission of repo %s/%s of User %s: %v", repo.OwnerName, repo.Name, user.Name, err),
})
return
}
allowedMerge, err := pull_service.IsUserAllowedToMerge(pr, perm, user)
if err != nil {
log.Error("Error calculating if allowed to merge: %v", err)
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"err": fmt.Sprintf("Error calculating if allowed to merge: %v", err),
})
return
}
if !allowedMerge {
log.Warn("Forbidden: User %d is not allowed to push to protected branch: %s in %-v and is not allowed to merge pr #%d", opts.UserID, branchName, repo, pr.Index)
ctx.JSON(http.StatusForbidden, map[string]interface{}{
"err": fmt.Sprintf("Not allowed to push to protected branch %s", branchName),
})
return
}
// Manual merge only allowed if PR is ready (even if admin)
if err := pull_service.CheckPRReadyToMerge(pr); err != nil {
if models.IsErrNotAllowedToMerge(err) {
log.Warn("Forbidden: User %d is not allowed push to protected branch %s in %-v and pr #%d is not ready to be merged: %s", opts.UserID, branchName, repo, pr.Index, err.Error())
ctx.JSON(http.StatusForbidden, map[string]interface{}{
"err": fmt.Sprintf("Not allowed to push to protected branch %s and pr #%d is not ready to be merged: %s", branchName, opts.ProtectedBranchID, err.Error()),
})
return
}
log.Error("Unable to check if mergable: protected branch %s in %-v and pr #%d. Error: %v", opts.UserID, branchName, repo, pr.Index, err)
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"err": fmt.Sprintf("Unable to get status of pull request %d. Error: %v", opts.ProtectedBranchID, err),
})
}
} else if !canPush {
log.Warn("Forbidden: User %d cannot push to protected branch: %s in %-v", opts.UserID, branchName, repo)
log.Warn("Forbidden: User %d is not allowed to push to protected branch: %s in %-v", opts.UserID, branchName, repo)
ctx.JSON(http.StatusForbidden, map[string]interface{}{
"err": fmt.Sprintf("protected branch %s can not be pushed to", branchName),
"err": fmt.Sprintf("Not allowed to push to protected branch %s", branchName),
})
return
}

View File

@ -903,6 +903,7 @@ func ViewIssue(ctx *context.Context) {
pull := issue.PullRequest
pull.Issue = issue
canDelete := false
ctx.Data["AllowMerge"] = false
if ctx.IsSigned {
if err := pull.GetHeadRepo(); err != nil {
@ -923,6 +924,20 @@ func ViewIssue(ctx *context.Context) {
}
}
}
if err := pull.GetBaseRepo(); err != nil {
log.Error("GetBaseRepo: %v", err)
}
perm, err := models.GetUserRepoPermission(pull.BaseRepo, ctx.User)
if err != nil {
ctx.ServerError("GetUserRepoPermission", err)
return
}
ctx.Data["AllowMerge"], err = pull_service.IsUserAllowedToMerge(pull, perm, ctx.User)
if err != nil {
ctx.ServerError("IsUserAllowedToMerge", err)
return
}
}
prUnit, err := repo.GetUnit(models.UnitTypePullRequests)
@ -932,15 +947,6 @@ func ViewIssue(ctx *context.Context) {
}
prConfig := prUnit.PullRequestsConfig()
ctx.Data["AllowMerge"] = ctx.Repo.CanWrite(models.UnitTypeCode)
if err := pull.CheckUserAllowedToMerge(ctx.User); err != nil {
if !models.IsErrNotAllowedToMerge(err) {
ctx.ServerError("CheckUserAllowedToMerge", err)
return
}
ctx.Data["AllowMerge"] = false
}
// Check correct values and select default
if ms, ok := ctx.Data["MergeStyle"].(models.MergeStyle); !ok ||
!prConfig.IsMergeStyleAllowed(ms) {

View File

@ -600,6 +600,16 @@ func MergePullRequest(ctx *context.Context, form auth.MergePullRequestForm) {
pr := issue.PullRequest
allowedMerge, err := pull_service.IsUserAllowedToMerge(pr, ctx.Repo.Permission, ctx.User)
if err != nil {
ctx.ServerError("IsUserAllowedToMerge", err)
return
}
if !allowedMerge {
ctx.NotFound("MergePullRequest", nil)
return
}
if !pr.CanAutoMerge() || pr.HasMerged {
ctx.NotFound("MergePullRequest", nil)
return
@ -611,15 +621,19 @@ func MergePullRequest(ctx *context.Context, form auth.MergePullRequestForm) {
return
}
isPass, err := pull_service.IsPullCommitStatusPass(pr)
if err != nil {
ctx.ServerError("IsPullCommitStatusPass", err)
return
}
if !isPass && !ctx.IsUserRepoAdmin() {
ctx.Flash.Error(ctx.Tr("repo.pulls.no_merge_status_check"))
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + com.ToStr(pr.Index))
return
if err := pull_service.CheckPRReadyToMerge(pr); err != nil {
if !models.IsErrNotAllowedToMerge(err) {
ctx.ServerError("Merge PR status", err)
return
}
if isRepoAdmin, err := models.IsUserRepoAdmin(pr.BaseRepo, ctx.User); err != nil {
ctx.ServerError("IsUserRepoAdmin", err)
return
} else if !isRepoAdmin {
ctx.Flash.Error(ctx.Tr("repo.pulls.no_merge_not_ready"))
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + com.ToStr(pr.Index))
return
}
}
if ctx.HasError() {

View File

@ -30,6 +30,7 @@ import (
)
// Merge merges pull request to base repository.
// Caller should check PR is ready to be merged (review and status checks)
// FIXME: add repoWorkingPull make sure two merges does not happen at same time.
func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repository, mergeStyle models.MergeStyle, message string) (err error) {
binVersion, err := git.BinVersion()
@ -53,11 +54,6 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor
}
prConfig := prUnit.PullRequestsConfig()
if err := pr.CheckUserAllowedToMerge(doer); err != nil {
log.Error("CheckUserAllowedToMerge(%v): %v", doer, err)
return fmt.Errorf("CheckUserAllowedToMerge: %v", err)
}
// Check if merge style is correct and allowed
if !prConfig.IsMergeStyleAllowed(mergeStyle) {
return models.ErrInvalidMergeStyle{ID: pr.BaseRepo.ID, Style: mergeStyle}
@ -374,8 +370,10 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor
return err
}
close := (ref.RefAction == references.XRefActionCloses)
if err = issue_service.ChangeStatus(ref.Issue, doer, close); err != nil {
return err
if close != ref.Issue.IsClosed {
if err = issue_service.ChangeStatus(ref.Issue, doer, close); err != nil {
return err
}
}
}
@ -471,3 +469,64 @@ func getDiffTree(repoPath, baseBranch, headBranch string) (string, error) {
return out.String(), nil
}
// IsUserAllowedToMerge check if user is allowed to merge PR with given permissions and branch protections
func IsUserAllowedToMerge(pr *models.PullRequest, p models.Permission, user *models.User) (bool, error) {
if p.IsAdmin() {
return true, nil
}
if !p.CanWrite(models.UnitTypeCode) {
return false, nil
}
err := pr.LoadProtectedBranch()
if err != nil {
return false, err
}
if pr.ProtectedBranch == nil || pr.ProtectedBranch.IsUserMergeWhitelisted(user.ID) {
return true, nil
}
return false, nil
}
// CheckPRReadyToMerge checks whether the PR is ready to be merged (reviews and status checks)
func CheckPRReadyToMerge(pr *models.PullRequest) (err error) {
if pr.BaseRepo == nil {
if err = pr.GetBaseRepo(); err != nil {
return fmt.Errorf("GetBaseRepo: %v", err)
}
}
if pr.ProtectedBranch == nil {
if err = pr.LoadProtectedBranch(); err != nil {
return fmt.Errorf("LoadProtectedBranch: %v", err)
}
if pr.ProtectedBranch == nil {
return nil
}
}
isPass, err := IsPullCommitStatusPass(pr)
if err != nil {
return err
}
if !isPass {
return models.ErrNotAllowedToMerge{
Reason: "Not all required status checks successful",
}
}
if enoughApprovals := pr.ProtectedBranch.HasEnoughApprovals(pr); !enoughApprovals {
return models.ErrNotAllowedToMerge{
Reason: "Does not have enough approvals",
}
}
if rejected := pr.ProtectedBranch.MergeBlockedByRejectedReview(pr); rejected {
return models.ErrNotAllowedToMerge{
Reason: "There are requested changes",
}
}
return nil
}

View File

@ -101,35 +101,31 @@
<span class="octicon octicon-x"></span>
{{$.i18n.Tr "repo.pulls.cannot_merge_work_in_progress" .WorkInProgressPrefix | Str2html}}
</div>
{{else if .IsBlockedByApprovals}}
<div class="item text red">
<span class="octicon octicon-x"></span>
{{$.i18n.Tr "repo.pulls.blocked_by_approvals" .GrantedApprovals .Issue.PullRequest.ProtectedBranch.RequiredApprovals}}
</div>
{{else if .IsBlockedByRejection}}
<div class="item text red">
<span class="octicon octicon-x"></span>
{{$.i18n.Tr "repo.pulls.blocked_by_rejection"}}
</div>
{{else if .Issue.PullRequest.IsChecking}}
<div class="item text yellow">
<span class="octicon octicon-sync"></span>
{{$.i18n.Tr "repo.pulls.is_checking"}}
</div>
{{else if and (not .Issue.PullRequest.CanAutoMerge) .EnableStatusCheck (not .IsRequiredStatusCheckSuccess)}}
<div class="item text red">
<span class="octicon octicon-x"></span>
{{$.i18n.Tr "repo.pulls.required_status_check_failed"}}
</div>
{{else if .Issue.PullRequest.CanAutoMerge}}
{{if and .EnableStatusCheck (not .IsRequiredStatusCheckSuccess)}}
<div class="item text red">
<span class="octicon octicon-x"></span>
{{$.i18n.Tr "repo.pulls.required_status_check_failed"}}
</div>
{{if .IsBlockedByApprovals}}
<div class="item text red">
<span class="octicon octicon-x"></span>
{{$.i18n.Tr "repo.pulls.blocked_by_approvals" .GrantedApprovals .Issue.PullRequest.ProtectedBranch.RequiredApprovals}}
</div>
{{else if .IsBlockedByRejection}}
<div class="item text red">
<span class="octicon octicon-x"></span>
{{$.i18n.Tr "repo.pulls.blocked_by_rejection"}}
</div>
{{else if and .EnableStatusCheck (not .IsRequiredStatusCheckSuccess)}}
<div class="item text red">
<span class="octicon octicon-x"></span>
{{$.i18n.Tr "repo.pulls.required_status_check_failed"}}
</div>
{{end}}
{{if or $.IsRepoAdmin (not .EnableStatusCheck) .IsRequiredStatusCheckSuccess}}
{{if and $.IsRepoAdmin .EnableStatusCheck (not .IsRequiredStatusCheckSuccess)}}
{{$notAllOk := or .IsBlockedByApprovals .IsBlockedByRejection (and .EnableStatusCheck (not .IsRequiredStatusCheckSuccess))}}
{{if or $.IsRepoAdmin (not $notAllOk)}}
{{if $notAllOk}}
<div class="item text yellow">
<span class="octicon octicon-primitive-dot"></span>
{{$.i18n.Tr "repo.pulls.required_status_check_administrator"}}
@ -216,7 +212,7 @@
</form>
</div>
{{end}}
<div class="ui green buttons merge-button">
<div class="ui {{if $notAllOk}}red{{else}}green{{end}} buttons merge-button">
<button class="ui button" data-do="{{.MergeStyle}}">
<span class="octicon octicon-git-merge"></span>
<span class="button-text">
@ -262,17 +258,40 @@
{{$.i18n.Tr "repo.pulls.no_merge_helper"}}
</div>
{{end}}
{{else}}
<div class="item text grey">
<span class="octicon octicon-info"></span>
{{$.i18n.Tr "repo.pulls.no_merge_access"}}
</div>
{{end}}
{{end}}
{{else}}
<div class="item text red">
<span class="octicon octicon-x"></span>
{{$.i18n.Tr "repo.pulls.cannot_auto_merge_desc"}}
</div>
<div class="item text grey">
<span class="octicon octicon-info"></span>
{{$.i18n.Tr "repo.pulls.cannot_auto_merge_helper"}}
</div>
{{/* Merge conflict without specific file. Suggest manual merge, only if all reviews and status checks OK. */}}
{{if .IsBlockedByApprovals}}
<div class="item text red">
<span class="octicon octicon-x"></span>
{{$.i18n.Tr "repo.pulls.blocked_by_approvals" .GrantedApprovals .Issue.PullRequest.ProtectedBranch.RequiredApprovals}}
</div>
{{else if .IsBlockedByRejection}}
<div class="item text red">
<span class="octicon octicon-x"></span>
{{$.i18n.Tr "repo.pulls.blocked_by_rejection"}}
</div>
{{else if and .EnableStatusCheck (not .IsRequiredStatusCheckSuccess)}}
<div class="item text red">
<span class="octicon octicon-x"></span>
{{$.i18n.Tr "repo.pulls.required_status_check_failed"}}
</div>
{{else}}
<div class="item text red">
<span class="octicon octicon-x"></span>
{{$.i18n.Tr "repo.pulls.cannot_auto_merge_desc"}}
</div>
<div class="item text grey">
<span class="octicon octicon-info"></span>
{{$.i18n.Tr "repo.pulls.cannot_auto_merge_helper"}}
</div>
{{end}}
{{end}}
</div>
</div>

View File

@ -66,7 +66,6 @@
<div id="swagger-ui"></div>
<script src="{{StaticUrlPrefix}}/vendor/assets/swagger-ui/swagger-ui-bundle.js"> </script>
<script src="{{StaticUrlPrefix}}/vendor/assets/swagger-ui/swagger-ui-standalone-preset.js"> </script>
<script>
window.onload = function() {

View File

@ -1154,7 +1154,6 @@
],
"summary": "Create a repository in an organization",
"operationId": "createOrgRepo",
"deprecated": true,
"parameters": [
{
"type": "string",
@ -10746,6 +10745,10 @@
},
"MergeTitleField": {
"type": "string"
},
"force_merge": {
"type": "boolean",
"x-go-name": "ForceMerge"
}
},
"x-go-name": "MergePullRequestForm",