Skip to content

Commit 86cff86

Browse files
davidsvantessonzeripath
authored andcommitted
Update branch API endpoint to show effective branch protection. (#9031)
* Add API endpoint for displaying effective branch protection. * Add status checks.
1 parent 3dfe919 commit 86cff86

File tree

5 files changed

+77
-9
lines changed

5 files changed

+77
-9
lines changed

models/branches.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,11 @@ func (repo *Repository) GetProtectedBranches() ([]*ProtectedBranch, error) {
242242
return protectedBranches, x.Find(&protectedBranches, &ProtectedBranch{RepoID: repo.ID})
243243
}
244244

245+
// GetBranchProtection get the branch protection of a branch
246+
func (repo *Repository) GetBranchProtection(branchName string) (*ProtectedBranch, error) {
247+
return GetProtectedBranchBy(repo.ID, branchName)
248+
}
249+
245250
// IsProtectedBranch checks if branch is protected
246251
func (repo *Repository) IsProtectedBranch(branchName string, doer *User) (bool, error) {
247252
if doer == nil {

modules/convert/convert.go

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,28 @@ func ToEmail(email *models.EmailAddress) *api.Email {
3030
}
3131

3232
// ToBranch convert a git.Commit and git.Branch to an api.Branch
33-
func ToBranch(repo *models.Repository, b *git.Branch, c *git.Commit) *api.Branch {
33+
func ToBranch(repo *models.Repository, b *git.Branch, c *git.Commit, bp *models.ProtectedBranch, user *models.User) *api.Branch {
34+
if bp == nil {
35+
return &api.Branch{
36+
Name: b.Name,
37+
Commit: ToCommit(repo, c),
38+
Protected: false,
39+
RequiredApprovals: 0,
40+
EnableStatusCheck: false,
41+
StatusCheckContexts: []string{},
42+
UserCanPush: true,
43+
UserCanMerge: true,
44+
}
45+
}
3446
return &api.Branch{
35-
Name: b.Name,
36-
Commit: ToCommit(repo, c),
47+
Name: b.Name,
48+
Commit: ToCommit(repo, c),
49+
Protected: true,
50+
RequiredApprovals: bp.RequiredApprovals,
51+
EnableStatusCheck: bp.EnableStatusCheck,
52+
StatusCheckContexts: bp.StatusCheckContexts,
53+
UserCanPush: bp.CanUserPush(user.ID),
54+
UserCanMerge: bp.CanUserMerge(user.ID),
3755
}
3856
}
3957

modules/structs/repo_branch.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ package structs
66

77
// Branch represents a repository branch
88
type Branch struct {
9-
Name string `json:"name"`
10-
Commit *PayloadCommit `json:"commit"`
9+
Name string `json:"name"`
10+
Commit *PayloadCommit `json:"commit"`
11+
Protected bool `json:"protected"`
12+
RequiredApprovals int64 `json:"required_approvals"`
13+
EnableStatusCheck bool `json:"enable_status_check"`
14+
StatusCheckContexts []string `json:"status_check_contexts"`
15+
UserCanPush bool `json:"user_can_push"`
16+
UserCanMerge bool `json:"user_can_merge"`
1117
}

routers/api/v1/repo/branch.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import (
1616
func GetBranch(ctx *context.APIContext) {
1717
// swagger:operation GET /repos/{owner}/{repo}/branches/{branch} repository repoGetBranch
1818
// ---
19-
// summary: Retrieve a specific branch from a repository
19+
// summary: Retrieve a specific branch from a repository, including its effective branch protection
2020
// produces:
2121
// - application/json
2222
// parameters:
@@ -61,7 +61,13 @@ func GetBranch(ctx *context.APIContext) {
6161
return
6262
}
6363

64-
ctx.JSON(200, convert.ToBranch(ctx.Repo.Repository, branch, c))
64+
branchProtection, err := ctx.Repo.Repository.GetBranchProtection(ctx.Repo.BranchName)
65+
if err != nil {
66+
ctx.Error(500, "GetBranchProtection", err)
67+
return
68+
}
69+
70+
ctx.JSON(200, convert.ToBranch(ctx.Repo.Repository, branch, c, branchProtection, ctx.User))
6571
}
6672

6773
// ListBranches list all the branches of a repository
@@ -98,7 +104,12 @@ func ListBranches(ctx *context.APIContext) {
98104
ctx.Error(500, "GetCommit", err)
99105
return
100106
}
101-
apiBranches[i] = convert.ToBranch(ctx.Repo.Repository, branches[i], c)
107+
branchProtection, err := ctx.Repo.Repository.GetBranchProtection(branches[i].Name)
108+
if err != nil {
109+
ctx.Error(500, "GetBranchProtection", err)
110+
return
111+
}
112+
apiBranches[i] = convert.ToBranch(ctx.Repo.Repository, branches[i], c, branchProtection, ctx.User)
102113
}
103114

104115
ctx.JSON(200, &apiBranches)

templates/swagger/v1_json.tmpl

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1492,7 +1492,7 @@
14921492
"tags": [
14931493
"repository"
14941494
],
1495-
"summary": "Retrieve a specific branch from a repository",
1495+
"summary": "Retrieve a specific branch from a repository, including its effective branch protection",
14961496
"operationId": "repoGetBranch",
14971497
"parameters": [
14981498
{
@@ -7583,9 +7583,37 @@
75837583
"commit": {
75847584
"$ref": "#/definitions/PayloadCommit"
75857585
},
7586+
"enable_status_check": {
7587+
"type": "boolean",
7588+
"x-go-name": "EnableStatusCheck"
7589+
},
75867590
"name": {
75877591
"type": "string",
75887592
"x-go-name": "Name"
7593+
},
7594+
"protected": {
7595+
"type": "boolean",
7596+
"x-go-name": "Protected"
7597+
},
7598+
"required_approvals": {
7599+
"type": "integer",
7600+
"format": "int64",
7601+
"x-go-name": "RequiredApprovals"
7602+
},
7603+
"status_check_contexts": {
7604+
"type": "array",
7605+
"items": {
7606+
"type": "string"
7607+
},
7608+
"x-go-name": "StatusCheckContexts"
7609+
},
7610+
"user_can_merge": {
7611+
"type": "boolean",
7612+
"x-go-name": "UserCanMerge"
7613+
},
7614+
"user_can_push": {
7615+
"type": "boolean",
7616+
"x-go-name": "UserCanPush"
75897617
}
75907618
},
75917619
"x-go-package": "code.gitea.io/gitea/modules/structs"

0 commit comments

Comments
 (0)