2020-09-14 12:05:12 +02:00
package cmd
import (
"context"
"fmt"
"strings"
"github.com/SAP/jenkins-library/pkg/log"
"github.com/SAP/jenkins-library/pkg/telemetry"
"github.com/google/go-github/v32/github"
"github.com/pkg/errors"
piperGithub "github.com/SAP/jenkins-library/pkg/github"
)
2020-09-14 18:08:24 +02:00
type gitHubBranchProtectionRepositoriesService interface {
2020-09-14 12:05:12 +02:00
GetBranchProtection ( ctx context . Context , owner , repo , branch string ) ( * github . Protection , * github . Response , error )
}
func githubCheckBranchProtection ( config githubCheckBranchProtectionOptions , telemetryData * telemetry . CustomData ) {
2022-02-23 10:30:19 +02:00
//TODO provide parameter for trusted certs
ctx , client , err := piperGithub . NewClient ( config . Token , config . APIURL , "" , [ ] string { } )
2020-09-14 12:05:12 +02:00
if err != nil {
log . Entry ( ) . WithError ( err ) . Fatal ( "Failed to get GitHub client" )
}
err = runGithubCheckBranchProtection ( ctx , & config , telemetryData , client . Repositories )
if err != nil {
log . Entry ( ) . WithError ( err ) . Fatal ( "GitHub branch protection check failed" )
}
}
2020-09-14 18:08:24 +02:00
func runGithubCheckBranchProtection ( ctx context . Context , config * githubCheckBranchProtectionOptions , telemetryData * telemetry . CustomData , ghRepositoriesService gitHubBranchProtectionRepositoriesService ) error {
2020-09-14 12:05:12 +02:00
ghProtection , _ , err := ghRepositoriesService . GetBranchProtection ( ctx , config . Owner , config . Repository , config . Branch )
if err != nil {
return errors . Wrap ( err , "failed to read branch protection information" )
}
// validate required status checks
for _ , check := range config . RequiredChecks {
var found bool
2020-09-15 17:50:55 +02:00
foundContexts := [ ] string { }
if requiredStatusChecks := ghProtection . GetRequiredStatusChecks ( ) ; requiredStatusChecks != nil {
foundContexts = requiredStatusChecks . Contexts
}
2020-09-14 12:05:12 +02:00
for _ , context := range foundContexts {
if check == context {
found = true
}
}
if ! found {
return fmt . Errorf ( "required status check '%v' not found among '%v' in branch protection configuration" , check , strings . Join ( foundContexts , "," ) )
}
}
// validate that admins are enforced in checks
if config . RequireEnforceAdmins && ! ghProtection . GetEnforceAdmins ( ) . Enabled {
return fmt . Errorf ( "admins are not enforced in branch protection configuration" )
}
// validate number of mandatory reviewers
if config . RequiredApprovingReviewCount > 0 && ghProtection . GetRequiredPullRequestReviews ( ) . RequiredApprovingReviewCount < config . RequiredApprovingReviewCount {
return fmt . Errorf ( "not enough mandatory reviewers in branch protection configuration, expected at least %v, got %v" , config . RequiredApprovingReviewCount , ghProtection . GetRequiredPullRequestReviews ( ) . RequiredApprovingReviewCount )
}
return nil
}