* Add API endpoint for displaying effective branch protection. * Add status checks.tags/v1.21.12.1
| @@ -242,6 +242,11 @@ func (repo *Repository) GetProtectedBranches() ([]*ProtectedBranch, error) { | |||||
| return protectedBranches, x.Find(&protectedBranches, &ProtectedBranch{RepoID: repo.ID}) | return protectedBranches, x.Find(&protectedBranches, &ProtectedBranch{RepoID: repo.ID}) | ||||
| } | } | ||||
| // GetBranchProtection get the branch protection of a branch | |||||
| func (repo *Repository) GetBranchProtection(branchName string) (*ProtectedBranch, error) { | |||||
| return GetProtectedBranchBy(repo.ID, branchName) | |||||
| } | |||||
| // IsProtectedBranch checks if branch is protected | // IsProtectedBranch checks if branch is protected | ||||
| func (repo *Repository) IsProtectedBranch(branchName string, doer *User) (bool, error) { | func (repo *Repository) IsProtectedBranch(branchName string, doer *User) (bool, error) { | ||||
| if doer == nil { | if doer == nil { | ||||
| @@ -30,10 +30,28 @@ func ToEmail(email *models.EmailAddress) *api.Email { | |||||
| } | } | ||||
| // ToBranch convert a git.Commit and git.Branch to an api.Branch | // ToBranch convert a git.Commit and git.Branch to an api.Branch | ||||
| func ToBranch(repo *models.Repository, b *git.Branch, c *git.Commit) *api.Branch { | |||||
| func ToBranch(repo *models.Repository, b *git.Branch, c *git.Commit, bp *models.ProtectedBranch, user *models.User) *api.Branch { | |||||
| if bp == nil { | |||||
| return &api.Branch{ | |||||
| Name: b.Name, | |||||
| Commit: ToCommit(repo, c), | |||||
| Protected: false, | |||||
| RequiredApprovals: 0, | |||||
| EnableStatusCheck: false, | |||||
| StatusCheckContexts: []string{}, | |||||
| UserCanPush: true, | |||||
| UserCanMerge: true, | |||||
| } | |||||
| } | |||||
| return &api.Branch{ | return &api.Branch{ | ||||
| Name: b.Name, | |||||
| Commit: ToCommit(repo, c), | |||||
| Name: b.Name, | |||||
| Commit: ToCommit(repo, c), | |||||
| Protected: true, | |||||
| RequiredApprovals: bp.RequiredApprovals, | |||||
| EnableStatusCheck: bp.EnableStatusCheck, | |||||
| StatusCheckContexts: bp.StatusCheckContexts, | |||||
| UserCanPush: bp.CanUserPush(user.ID), | |||||
| UserCanMerge: bp.CanUserMerge(user.ID), | |||||
| } | } | ||||
| } | } | ||||
| @@ -6,6 +6,12 @@ package structs | |||||
| // Branch represents a repository branch | // Branch represents a repository branch | ||||
| type Branch struct { | type Branch struct { | ||||
| Name string `json:"name"` | |||||
| Commit *PayloadCommit `json:"commit"` | |||||
| Name string `json:"name"` | |||||
| Commit *PayloadCommit `json:"commit"` | |||||
| Protected bool `json:"protected"` | |||||
| RequiredApprovals int64 `json:"required_approvals"` | |||||
| EnableStatusCheck bool `json:"enable_status_check"` | |||||
| StatusCheckContexts []string `json:"status_check_contexts"` | |||||
| UserCanPush bool `json:"user_can_push"` | |||||
| UserCanMerge bool `json:"user_can_merge"` | |||||
| } | } | ||||
| @@ -16,7 +16,7 @@ import ( | |||||
| func GetBranch(ctx *context.APIContext) { | func GetBranch(ctx *context.APIContext) { | ||||
| // swagger:operation GET /repos/{owner}/{repo}/branches/{branch} repository repoGetBranch | // swagger:operation GET /repos/{owner}/{repo}/branches/{branch} repository repoGetBranch | ||||
| // --- | // --- | ||||
| // summary: Retrieve a specific branch from a repository | |||||
| // summary: Retrieve a specific branch from a repository, including its effective branch protection | |||||
| // produces: | // produces: | ||||
| // - application/json | // - application/json | ||||
| // parameters: | // parameters: | ||||
| @@ -61,7 +61,13 @@ func GetBranch(ctx *context.APIContext) { | |||||
| return | return | ||||
| } | } | ||||
| ctx.JSON(200, convert.ToBranch(ctx.Repo.Repository, branch, c)) | |||||
| branchProtection, err := ctx.Repo.Repository.GetBranchProtection(ctx.Repo.BranchName) | |||||
| if err != nil { | |||||
| ctx.Error(500, "GetBranchProtection", err) | |||||
| return | |||||
| } | |||||
| ctx.JSON(200, convert.ToBranch(ctx.Repo.Repository, branch, c, branchProtection, ctx.User)) | |||||
| } | } | ||||
| // ListBranches list all the branches of a repository | // ListBranches list all the branches of a repository | ||||
| @@ -98,7 +104,12 @@ func ListBranches(ctx *context.APIContext) { | |||||
| ctx.Error(500, "GetCommit", err) | ctx.Error(500, "GetCommit", err) | ||||
| return | return | ||||
| } | } | ||||
| apiBranches[i] = convert.ToBranch(ctx.Repo.Repository, branches[i], c) | |||||
| branchProtection, err := ctx.Repo.Repository.GetBranchProtection(branches[i].Name) | |||||
| if err != nil { | |||||
| ctx.Error(500, "GetBranchProtection", err) | |||||
| return | |||||
| } | |||||
| apiBranches[i] = convert.ToBranch(ctx.Repo.Repository, branches[i], c, branchProtection, ctx.User) | |||||
| } | } | ||||
| ctx.JSON(200, &apiBranches) | ctx.JSON(200, &apiBranches) | ||||
| @@ -1492,7 +1492,7 @@ | |||||
| "tags": [ | "tags": [ | ||||
| "repository" | "repository" | ||||
| ], | ], | ||||
| "summary": "Retrieve a specific branch from a repository", | |||||
| "summary": "Retrieve a specific branch from a repository, including its effective branch protection", | |||||
| "operationId": "repoGetBranch", | "operationId": "repoGetBranch", | ||||
| "parameters": [ | "parameters": [ | ||||
| { | { | ||||
| @@ -7583,9 +7583,37 @@ | |||||
| "commit": { | "commit": { | ||||
| "$ref": "#/definitions/PayloadCommit" | "$ref": "#/definitions/PayloadCommit" | ||||
| }, | }, | ||||
| "enable_status_check": { | |||||
| "type": "boolean", | |||||
| "x-go-name": "EnableStatusCheck" | |||||
| }, | |||||
| "name": { | "name": { | ||||
| "type": "string", | "type": "string", | ||||
| "x-go-name": "Name" | "x-go-name": "Name" | ||||
| }, | |||||
| "protected": { | |||||
| "type": "boolean", | |||||
| "x-go-name": "Protected" | |||||
| }, | |||||
| "required_approvals": { | |||||
| "type": "integer", | |||||
| "format": "int64", | |||||
| "x-go-name": "RequiredApprovals" | |||||
| }, | |||||
| "status_check_contexts": { | |||||
| "type": "array", | |||||
| "items": { | |||||
| "type": "string" | |||||
| }, | |||||
| "x-go-name": "StatusCheckContexts" | |||||
| }, | |||||
| "user_can_merge": { | |||||
| "type": "boolean", | |||||
| "x-go-name": "UserCanMerge" | |||||
| }, | |||||
| "user_can_push": { | |||||
| "type": "boolean", | |||||
| "x-go-name": "UserCanPush" | |||||
| } | } | ||||
| }, | }, | ||||
| "x-go-package": "code.gitea.io/gitea/modules/structs" | "x-go-package": "code.gitea.io/gitea/modules/structs" | ||||