Skip to content

Commit 1eb0177

Browse files
committed
Add branch protection mode
1 parent 5ea6d7e commit 1eb0177

File tree

8 files changed

+78
-20
lines changed

8 files changed

+78
-20
lines changed

docs/toml-schema.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,13 +333,18 @@ Admins cannot override these branch protections. If an admin needs to do that, t
333333
# The pattern matching the branches to be protected (required)
334334
pattern = "master"
335335
# Which CI checks to are required for merging (optional)
336+
# Cannot be set if `pr-required` is `false`.
336337
ci-checks = ["CI"]
337338
# Whether new commits after a reviewer's approval of a PR
338339
# merging into this branch require another review.
339340
# (optional - default `false`)
340341
dismiss-stale-review = false
342+
# Is a PR required when making changes to this branch?
343+
# (optional - default `true`)
344+
pr-required = true
341345
# How many approvals are required for a PR to be merged.
342346
# This option is only relevant if bors is not used.
347+
# Cannot be set if `pr-required` is `false`.
343348
# (optional - default `1`)
344349
required-approvals = 1
345350
# Which GitHub teams have access to push/merge to this branch.

rust_team_data/src/v1.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,12 +209,21 @@ pub enum RepoPermission {
209209
Triage,
210210
}
211211

212+
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
213+
#[serde(rename_all = "snake_case")]
214+
pub enum BranchProtectionMode {
215+
PrRequired {
216+
ci_checks: Vec<String>,
217+
required_approvals: u32,
218+
},
219+
PrNotRequired,
220+
}
221+
212222
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
213223
pub struct BranchProtection {
214224
pub pattern: String,
215-
pub ci_checks: Vec<String>,
216225
pub dismiss_stale_review: bool,
217-
pub required_approvals: u32,
226+
pub mode: BranchProtectionMode,
218227
pub allowed_merge_teams: Vec<String>,
219228
}
220229

src/schema.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,8 @@ pub(crate) struct BranchProtection {
797797
pub dismiss_stale_review: bool,
798798
#[serde(default)]
799799
pub required_approvals: Option<u32>,
800+
#[serde(default = "default_true")]
801+
pub pr_required: bool,
800802
#[serde(default)]
801803
pub allowed_merge_teams: Vec<String>,
802804
}

src/static_api.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use anyhow::{ensure, Context as _, Error};
44
use indexmap::IndexMap;
55
use log::info;
66
use rust_team_data::v1;
7+
use rust_team_data::v1::BranchProtectionMode;
78
use std::collections::HashMap;
89
use std::path::Path;
910

@@ -48,9 +49,15 @@ impl<'a> Generator<'a> {
4849
.iter()
4950
.map(|b| v1::BranchProtection {
5051
pattern: b.pattern.clone(),
51-
ci_checks: b.ci_checks.clone(),
5252
dismiss_stale_review: b.dismiss_stale_review,
53-
required_approvals: b.required_approvals.unwrap_or(1),
53+
mode: if b.pr_required {
54+
BranchProtectionMode::PrRequired {
55+
ci_checks: b.ci_checks.clone(),
56+
required_approvals: b.required_approvals.unwrap_or(1),
57+
}
58+
} else {
59+
BranchProtectionMode::PrNotRequired
60+
},
5461
allowed_merge_teams: b.allowed_merge_teams.clone(),
5562
})
5663
.collect();

src/validate.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,25 @@ but that team does not seem to exist"#,
839839
}
840840
}
841841

842+
if !protection.pr_required {
843+
// It does not make sense to use CI checks when a PR is not required, because with a
844+
// CI check, it would not be possible to push into the branch without a PR anyway.
845+
if !protection.ci_checks.is_empty() {
846+
bail!(
847+
r#"repo '{}' uses a branch protection for {} that does not require a PR, but has non-empty `ci-checks`"#,
848+
repo.name,
849+
protection.pattern,
850+
);
851+
}
852+
if protection.required_approvals.is_some() {
853+
bail!(
854+
r#"repo '{}' uses a branch protection for {} that does not require a PR, but sets the `required-approvals` attribute"#,
855+
repo.name,
856+
protection.pattern,
857+
);
858+
}
859+
}
860+
842861
if bors_used {
843862
if protection.required_approvals.is_some() {
844863
bail!(

tests/static-api/_expected/v1/repos.json

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,15 @@
1616
"branch_protections": [
1717
{
1818
"pattern": "master",
19-
"ci_checks": [
20-
"CI"
21-
],
2219
"dismiss_stale_review": false,
23-
"required_approvals": 1,
20+
"mode": {
21+
"pr_required": {
22+
"ci_checks": [
23+
"CI"
24+
],
25+
"required_approvals": 1
26+
}
27+
},
2428
"allowed_merge_teams": []
2529
}
2630
],
@@ -44,11 +48,15 @@
4448
"branch_protections": [
4549
{
4650
"pattern": "master",
47-
"ci_checks": [
48-
"CI"
49-
],
5051
"dismiss_stale_review": false,
51-
"required_approvals": 1,
52+
"mode": {
53+
"pr_required": {
54+
"ci_checks": [
55+
"CI"
56+
],
57+
"required_approvals": 1
58+
}
59+
},
5260
"allowed_merge_teams": [
5361
"foo"
5462
]

tests/static-api/_expected/v1/repos/archived_repo.json

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,15 @@
1414
"branch_protections": [
1515
{
1616
"pattern": "master",
17-
"ci_checks": [
18-
"CI"
19-
],
2017
"dismiss_stale_review": false,
21-
"required_approvals": 1,
18+
"mode": {
19+
"pr_required": {
20+
"ci_checks": [
21+
"CI"
22+
],
23+
"required_approvals": 1
24+
}
25+
},
2226
"allowed_merge_teams": []
2327
}
2428
],

tests/static-api/_expected/v1/repos/some_repo.json

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,15 @@
1414
"branch_protections": [
1515
{
1616
"pattern": "master",
17-
"ci_checks": [
18-
"CI"
19-
],
2017
"dismiss_stale_review": false,
21-
"required_approvals": 1,
18+
"mode": {
19+
"pr_required": {
20+
"ci_checks": [
21+
"CI"
22+
],
23+
"required_approvals": 1
24+
}
25+
},
2226
"allowed_merge_teams": [
2327
"foo"
2428
]

0 commit comments

Comments
 (0)