Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Move "EnforcesAdmins" to tier 5 Branch-Protection #3502

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions checks/branch_protection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ func TestReleaseAndDevBranchProtected(t *testing.T) {
name: "Only development branch",
expected: scut.TestReturn{
Error: nil,
Score: 2,
Score: 3,
NumberOfWarn: 7,
NumberOfInfo: 2,
NumberOfDebug: 0,
Expand Down Expand Up @@ -173,7 +173,7 @@ func TestReleaseAndDevBranchProtected(t *testing.T) {
name: "Take worst of release and development",
expected: scut.TestReturn{
Error: nil,
Score: 2,
Score: 4,
NumberOfWarn: 9,
NumberOfInfo: 10,
NumberOfDebug: 0,
Expand Down Expand Up @@ -285,7 +285,7 @@ func TestReleaseAndDevBranchProtected(t *testing.T) {
name: "Ignore a non-branch targetcommitish",
expected: scut.TestReturn{
Error: nil,
Score: 2,
Score: 3,
NumberOfWarn: 7,
NumberOfInfo: 2,
NumberOfDebug: 0,
Expand Down
60 changes: 19 additions & 41 deletions checks/evaluation/branch_protection.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (
const (
minReviews = 2
// Points incremented at each level.
adminNonAdminBasicLevel = 3 // Level 1.
basicLevel = 3 // Level 1.
adminNonAdminReviewLevel = 3 // Level 2.
nonAdminContextLevel = 2 // Level 3.
nonAdminThoroughReviewLevel = 1 // Level 4.
Expand All @@ -35,7 +35,6 @@ const (

type scoresInfo struct {
basic int
adminBasic int
review int
adminReview int
context int
Expand Down Expand Up @@ -71,7 +70,6 @@ func BranchProtection(name string, dl checker.DetailLogger,
})
}
score.scores.basic, score.maxes.basic = basicNonAdminProtection(&b, dl)
score.scores.adminBasic, score.maxes.adminBasic = basicAdminProtection(&b, dl)
score.scores.review, score.maxes.review = nonAdminReviewProtection(&b)
score.scores.adminReview, score.maxes.adminReview = adminReviewProtection(&b, dl)
score.scores.context, score.maxes.context = nonAdminContextProtection(&b, dl)
Expand Down Expand Up @@ -114,15 +112,6 @@ func computeNonAdminBasicScore(scores []levelScore) int {
return score
}

func computeAdminBasicScore(scores []levelScore) int {
score := 0
for i := range scores {
s := scores[i]
score += s.scores.adminBasic
}
return score
}

func computeNonAdminReviewScore(scores []levelScore) int {
score := 0
for i := range scores {
Expand Down Expand Up @@ -194,12 +183,9 @@ func computeScore(scores []levelScore) (int, error) {

// First, check if they all pass the basic (admin and non-admin) checks.
maxBasicScore := maxScore.basic * len(scores)
maxAdminBasicScore := maxScore.adminBasic * len(scores)
basicScore := computeNonAdminBasicScore(scores)
adminBasicScore := computeAdminBasicScore(scores)
score += noarmalizeScore(basicScore+adminBasicScore, maxBasicScore+maxAdminBasicScore, adminNonAdminBasicLevel)
if basicScore != maxBasicScore ||
adminBasicScore != maxAdminBasicScore {
score += noarmalizeScore(basicScore, maxBasicScore, basicLevel)
if basicScore != maxBasicScore {
return int(score), nil
}

Expand Down Expand Up @@ -308,30 +294,6 @@ func basicNonAdminProtection(branch *clients.BranchRef, dl checker.DetailLogger)
return score, max
}

func basicAdminProtection(branch *clients.BranchRef, dl checker.DetailLogger) (int, int) {
score := 0
max := 0
// Only log information if the branch is protected.
log := branch.Protected != nil && *branch.Protected

// nil typically means we do not have access to the value.
if branch.BranchProtectionRule.EnforceAdmins != nil {
// Note: we don't inrecase max possible score for non-admin viewers.
max++
switch *branch.BranchProtectionRule.EnforceAdmins {
case true:
info(dl, log, "settings apply to administrators on branch '%s'", *branch.Name)
score++
case false:
warn(dl, log, "settings do not apply to administrators on branch '%s'", *branch.Name)
}
} else {
debug(dl, log, "unable to retrieve whether or not settings apply to administrators on branch '%s'", *branch.Name)
}

return score, max
}

func nonAdminContextProtection(branch *clients.BranchRef, dl checker.DetailLogger) (int, int) {
score := 0
max := 0
Expand Down Expand Up @@ -422,6 +384,22 @@ func adminThoroughReviewProtection(branch *clients.BranchRef, dl checker.DetailL
} else {
debug(dl, log, "unable to retrieve review dismissal on branch '%s'", *branch.Name)
}

// nil typically means we do not have access to the value.
if branch.BranchProtectionRule.EnforceAdmins != nil {
// Note: we don't inrecase max possible score for non-admin viewers.
max++
switch *branch.BranchProtectionRule.EnforceAdmins {
case true:
info(dl, log, "settings apply to administrators on branch '%s'", *branch.Name)
score++
case false:
warn(dl, log, "settings do not apply to administrators on branch '%s'", *branch.Name)
}
} else {
debug(dl, log, "unable to retrieve whether or not settings apply to administrators on branch '%s'", *branch.Name)
}

return score, max
}

Expand Down
11 changes: 5 additions & 6 deletions checks/evaluation/branch_protection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import (
func testScore(branch *clients.BranchRef, codeownersFiles []string, dl checker.DetailLogger) (int, error) {
var score levelScore
score.scores.basic, score.maxes.basic = basicNonAdminProtection(branch, dl)
score.scores.adminBasic, score.maxes.adminBasic = basicAdminProtection(branch, dl)
score.scores.review, score.maxes.review = nonAdminReviewProtection(branch)
score.scores.adminReview, score.maxes.adminReview = adminReviewProtection(branch, dl)
score.scores.context, score.maxes.context = nonAdminContextProtection(branch, dl)
Expand Down Expand Up @@ -53,7 +52,7 @@ func TestIsBranchProtected(t *testing.T) {
name: "Nothing is enabled",
expected: scut.TestReturn{
Error: nil,
Score: 2,
Score: 3,
NumberOfWarn: 7,
NumberOfInfo: 2,
NumberOfDebug: 0,
Expand Down Expand Up @@ -98,7 +97,7 @@ func TestIsBranchProtected(t *testing.T) {
name: "Required status check enabled",
expected: scut.TestReturn{
Error: nil,
Score: 2,
Score: 4,
NumberOfWarn: 5,
NumberOfInfo: 4,
NumberOfDebug: 0,
Expand Down Expand Up @@ -129,7 +128,7 @@ func TestIsBranchProtected(t *testing.T) {
name: "Required status check enabled without checking for status string",
expected: scut.TestReturn{
Error: nil,
Score: 2,
Score: 4,
NumberOfWarn: 6,
NumberOfInfo: 3,
NumberOfDebug: 0,
Expand Down Expand Up @@ -160,7 +159,7 @@ func TestIsBranchProtected(t *testing.T) {
name: "Required pull request enabled",
expected: scut.TestReturn{
Error: nil,
Score: 2,
Score: 4,
NumberOfWarn: 6,
NumberOfInfo: 3,
NumberOfDebug: 0,
Expand Down Expand Up @@ -222,7 +221,7 @@ func TestIsBranchProtected(t *testing.T) {
name: "Required linear history enabled",
expected: scut.TestReturn{
Error: nil,
Score: 2,
Score: 3,
NumberOfWarn: 6,
NumberOfInfo: 3,
NumberOfDebug: 0,
Expand Down
2 changes: 1 addition & 1 deletion docs/checks.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ Note: If Scorecard is run without an administrative access token, the requiremen
Tier 1 Requirements (3/10 points):
- Prevent force push
- Prevent branch deletion
- For administrators: Include administrator for review

Tier 2 Requirements (6/10 points):
- Require at least 1 reviewer for approval before merging
Expand All @@ -125,6 +124,7 @@ Tier 4 Requirements (9/10 points):

Tier 5 Requirements (10/10 points):
- For administrators: Dismiss stale reviews and approvals when new commits are pushed
- For administrators: Include administrator for review

GitLab Integration Status:
- GitLab associates releases with commits and not with the branch. Releases are ignored in this portion of the scoring.
Expand Down
2 changes: 1 addition & 1 deletion docs/checks/internal/checks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,6 @@ checks:
Tier 1 Requirements (3/10 points):
- Prevent force push
- Prevent branch deletion
- For administrators: Include administrator for review

Tier 2 Requirements (6/10 points):
- Require at least 1 reviewer for approval before merging
Expand All @@ -214,6 +213,7 @@ checks:

Tier 5 Requirements (10/10 points):
- For administrators: Dismiss stale reviews and approvals when new commits are pushed
- For administrators: Include administrator for review

GitLab Integration Status:
- GitLab associates releases with commits and not with the branch. Releases are ignored in this portion of the scoring.
Expand Down
Loading