Skip to content

Commit ff32715

Browse files
committed
Add block on pending codeowner reviews branch protection
1 parent 52c3a7d commit ff32715

File tree

15 files changed

+208
-23
lines changed

15 files changed

+208
-23
lines changed

models/git/protected_branch.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ type ProtectedBranch struct {
5656
RequiredApprovals int64 `xorm:"NOT NULL DEFAULT 0"`
5757
BlockOnRejectedReviews bool `xorm:"NOT NULL DEFAULT false"`
5858
BlockOnOfficialReviewRequests bool `xorm:"NOT NULL DEFAULT false"`
59+
BlockOnCodeownerReviews bool `xorm:"NOT NULL DEFAULT false"`
5960
BlockOnOutdatedBranch bool `xorm:"NOT NULL DEFAULT false"`
6061
DismissStaleApprovals bool `xorm:"NOT NULL DEFAULT false"`
6162
IgnoreStaleApprovals bool `xorm:"NOT NULL DEFAULT false"`

models/migrations/migrations.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,7 @@ func prepareMigrationTasks() []*migration {
400400
newMigration(323, "Add support for actions concurrency", v1_26.AddActionsConcurrency),
401401
newMigration(324, "Fix closed milestone completeness for milestones with no issues", v1_26.FixClosedMilestoneCompleteness),
402402
newMigration(325, "Fix missed repo_id when migrate attachments", v1_26.FixMissedRepoIDWhenMigrateAttachments),
403+
newMigration(326, "Add block on codeowner reviews branch protection", v1_26.AddBlockOnCodeownerReviews),
403404
}
404405
return preparedMigrations
405406
}

models/migrations/v1_26/v326.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2025 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package v1_26
5+
6+
import (
7+
"xorm.io/xorm"
8+
)
9+
10+
func AddBlockOnCodeownerReviews(x *xorm.Engine) error {
11+
type ProtectedBranch struct {
12+
BlockOnCodeownerReviews bool `xorm:"NOT NULL DEFAULT false"`
13+
}
14+
15+
return x.Sync(new(ProtectedBranch))
16+
}

modules/structs/repo_branch.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ type BranchProtection struct {
5858
ApprovalsWhitelistTeams []string `json:"approvals_whitelist_teams"`
5959
BlockOnRejectedReviews bool `json:"block_on_rejected_reviews"`
6060
BlockOnOfficialReviewRequests bool `json:"block_on_official_review_requests"`
61+
BlockOnCodeownerReviews bool `json:"block_on_codeowner_reviews"`
6162
BlockOnOutdatedBranch bool `json:"block_on_outdated_branch"`
6263
DismissStaleApprovals bool `json:"dismiss_stale_approvals"`
6364
IgnoreStaleApprovals bool `json:"ignore_stale_approvals"`
@@ -98,6 +99,7 @@ type CreateBranchProtectionOption struct {
9899
ApprovalsWhitelistTeams []string `json:"approvals_whitelist_teams"`
99100
BlockOnRejectedReviews bool `json:"block_on_rejected_reviews"`
100101
BlockOnOfficialReviewRequests bool `json:"block_on_official_review_requests"`
102+
BlockOnCodeownerReviews bool `json:"block_on_codeowner_reviews"`
101103
BlockOnOutdatedBranch bool `json:"block_on_outdated_branch"`
102104
DismissStaleApprovals bool `json:"dismiss_stale_approvals"`
103105
IgnoreStaleApprovals bool `json:"ignore_stale_approvals"`
@@ -131,6 +133,7 @@ type EditBranchProtectionOption struct {
131133
ApprovalsWhitelistTeams []string `json:"approvals_whitelist_teams"`
132134
BlockOnRejectedReviews *bool `json:"block_on_rejected_reviews"`
133135
BlockOnOfficialReviewRequests *bool `json:"block_on_official_review_requests"`
136+
BlockOnCodeownerReviews *bool `json:"block_on_codeowner_reviews"`
134137
BlockOnOutdatedBranch *bool `json:"block_on_outdated_branch"`
135138
DismissStaleApprovals *bool `json:"dismiss_stale_approvals"`
136139
IgnoreStaleApprovals *bool `json:"ignore_stale_approvals"`

options/locale/locale_en-US.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1808,6 +1808,7 @@
18081808
"repo.pulls.blocked_by_outdated_branch": "This pull request is blocked because it's outdated.",
18091809
"repo.pulls.blocked_by_changed_protected_files_1": "This pull request is blocked because it changes a protected file:",
18101810
"repo.pulls.blocked_by_changed_protected_files_n": "This pull request is blocked because it changes protected files:",
1811+
"repo.pulls.blocked_by_codeowners": "This pull request is missing approval from one or more code owners.",
18111812
"repo.pulls.can_auto_merge_desc": "This pull request can be merged automatically.",
18121813
"repo.pulls.cannot_auto_merge_desc": "This pull request cannot be merged automatically due to conflicts.",
18131814
"repo.pulls.cannot_auto_merge_helper": "Merge manually to resolve the conflicts.",
@@ -2430,6 +2431,8 @@
24302431
"repo.settings.block_on_official_review_requests_desc": "Merging will not be possible when it has official review requests, even if there are enough approvals.",
24312432
"repo.settings.block_outdated_branch": "Block merge if pull request is outdated",
24322433
"repo.settings.block_outdated_branch_desc": "Merging will not be possible when head branch is behind base branch.",
2434+
"repo.settings.block_on_codeowner_reviews" : "Require approval from code owners",
2435+
"repo.settings.block_on_codeowner_reviews_desc" : "Merging will only be possible if at least one code owner per code owner rule has given an approving review.",
24332436
"repo.settings.block_admin_merge_override": "Administrators must follow branch protection rules",
24342437
"repo.settings.block_admin_merge_override_desc": "Administrators must follow branch protection rules and cannot circumvent it.",
24352438
"repo.settings.default_branch_desc": "Select a default repository branch for pull requests and code commits:",

routers/api/v1/repo/branch.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,10 @@ func EditBranchProtection(ctx *context.APIContext) {
930930
protectBranch.BlockOnOfficialReviewRequests = *form.BlockOnOfficialReviewRequests
931931
}
932932

933+
if form.BlockOnCodeownerReviews != nil {
934+
protectBranch.BlockOnCodeownerReviews = *form.BlockOnCodeownerReviews
935+
}
936+
933937
if form.DismissStaleApprovals != nil {
934938
protectBranch.DismissStaleApprovals = *form.DismissStaleApprovals
935939
}

routers/web/repo/issue_view.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -952,6 +952,7 @@ func preparePullViewReviewAndMerge(ctx *context.Context, issue *issues_model.Iss
952952
ctx.Data["ProtectedBranch"] = pb
953953
ctx.Data["IsBlockedByApprovals"] = !issues_model.HasEnoughApprovals(ctx, pb, pull)
954954
ctx.Data["IsBlockedByRejection"] = issues_model.MergeBlockedByRejectedReview(ctx, pb, pull)
955+
ctx.Data["IsBlockedByCodeowners"] = !issue_service.HasAllRequiredCodeownerReviews(ctx, pb, pull)
955956
ctx.Data["IsBlockedByOfficialReviewRequests"] = issues_model.MergeBlockedByOfficialReviewRequests(ctx, pb, pull)
956957
ctx.Data["IsBlockedByOutdatedBranch"] = issues_model.MergeBlockedByOutdatedBranch(pb, pull)
957958
ctx.Data["GrantedApprovals"] = issues_model.GetGrantedApprovalsCount(ctx, pb, pull)

routers/web/repo/setting/protected_branch.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ func SettingsProtectedBranchPost(ctx *context.Context) {
253253
}
254254
protectBranch.BlockOnRejectedReviews = f.BlockOnRejectedReviews
255255
protectBranch.BlockOnOfficialReviewRequests = f.BlockOnOfficialReviewRequests
256+
protectBranch.BlockOnCodeownerReviews = f.BlockOnCodeownerReviews
256257
protectBranch.DismissStaleApprovals = f.DismissStaleApprovals
257258
protectBranch.IgnoreStaleApprovals = f.IgnoreStaleApprovals
258259
protectBranch.RequireSignedCommits = f.RequireSignedCommits

services/convert/convert.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ func ToBranchProtection(ctx context.Context, bp *git_model.ProtectedBranch, repo
189189
ApprovalsWhitelistTeams: approvalsWhitelistTeams,
190190
BlockOnRejectedReviews: bp.BlockOnRejectedReviews,
191191
BlockOnOfficialReviewRequests: bp.BlockOnOfficialReviewRequests,
192+
BlockOnCodeownerReviews: bp.BlockOnCodeownerReviews,
192193
BlockOnOutdatedBranch: bp.BlockOnOutdatedBranch,
193194
DismissStaleApprovals: bp.DismissStaleApprovals,
194195
IgnoreStaleApprovals: bp.IgnoreStaleApprovals,

services/forms/repo_form.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ type ProtectBranchForm struct {
184184
ApprovalsWhitelistTeams string
185185
BlockOnRejectedReviews bool
186186
BlockOnOfficialReviewRequests bool
187+
BlockOnCodeownerReviews bool
187188
BlockOnOutdatedBranch bool
188189
DismissStaleApprovals bool
189190
IgnoreStaleApprovals bool

0 commit comments

Comments
 (0)