1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2024-12-12 10:55:20 +02:00

Add step for GitHub branch protection check (#2010)

* add step for GitHub branch protection check

* add command to piper command

* remove unnecessary parameter

* Update resources/metadata/githubbranchprotection.yaml

* add groovy part

* update generation & go mod tidy

* update groovy tests

* fix bug with go-github version

Co-authored-by: Sven Merk <33895725+nevskrem@users.noreply.github.com>
This commit is contained in:
Oliver Nocon 2020-09-11 15:28:43 +02:00 committed by GitHub
parent 37b4af110c
commit f1cfca2e76
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 497 additions and 26 deletions

View File

@ -17,7 +17,7 @@ import (
"github.com/bmatcuk/doublestar"
"github.com/google/go-github/v28/github"
"github.com/google/go-github/v32/github"
"github.com/google/uuid"
"github.com/piper-validation/fortify-client-go/models"

View File

@ -5,8 +5,6 @@ import (
"context"
"errors"
"fmt"
"github.com/SAP/jenkins-library/pkg/fortify"
"github.com/SAP/jenkins-library/pkg/log"
"io"
"io/ioutil"
"os"
@ -15,7 +13,10 @@ import (
"testing"
"time"
"github.com/google/go-github/v28/github"
"github.com/SAP/jenkins-library/pkg/fortify"
"github.com/SAP/jenkins-library/pkg/log"
"github.com/google/go-github/v32/github"
"github.com/stretchr/testify/assert"
"github.com/piper-validation/fortify-client-go/models"

View File

@ -0,0 +1,64 @@
package cmd
import (
"context"
"fmt"
"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"
)
type githubRepositoriesService interface {
GetBranchProtection(ctx context.Context, owner, repo, branch string) (*github.Protection, *github.Response, error)
}
func githubCheckBranchProtection(config githubCheckBranchProtectionOptions, telemetryData *telemetry.CustomData) {
ctx, client, err := piperGithub.NewClient(config.Token, config.APIURL, "")
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")
}
}
func runGithubCheckBranchProtection(ctx context.Context, config *githubCheckBranchProtectionOptions, telemetryData *telemetry.CustomData, ghRepositoriesService githubRepositoriesService) error {
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
for _, context := range ghProtection.GetRequiredStatusChecks().Contexts {
if check == context {
found = true
}
}
if !found {
return fmt.Errorf("required status check '%v' not found in branch protection configuration", check)
}
}
// validate that admins are enforced in checks
if config.RequireEnforceAdmins {
if !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
}

View File

@ -0,0 +1,180 @@
// Code generated by piper's step-generator. DO NOT EDIT.
package cmd
import (
"fmt"
"os"
"time"
"github.com/SAP/jenkins-library/pkg/config"
"github.com/SAP/jenkins-library/pkg/log"
"github.com/SAP/jenkins-library/pkg/telemetry"
"github.com/spf13/cobra"
)
type githubCheckBranchProtectionOptions struct {
APIURL string `json:"apiUrl,omitempty"`
Branch string `json:"branch,omitempty"`
Owner string `json:"owner,omitempty"`
Repository string `json:"repository,omitempty"`
RequiredChecks []string `json:"requiredChecks,omitempty"`
RequireEnforceAdmins bool `json:"requireEnforceAdmins,omitempty"`
RequiredApprovingReviewCount int `json:"requiredApprovingReviewCount,omitempty"`
Token string `json:"token,omitempty"`
}
// GithubCheckBranchProtectionCommand Check branch protection of a GitHub branch
func GithubCheckBranchProtectionCommand() *cobra.Command {
const STEP_NAME = "githubCheckBranchProtection"
metadata := githubCheckBranchProtectionMetadata()
var stepConfig githubCheckBranchProtectionOptions
var startTime time.Time
var createGithubCheckBranchProtectionCmd = &cobra.Command{
Use: STEP_NAME,
Short: "Check branch protection of a GitHub branch",
Long: `This step allows you to check if certain branch protection rules are fulfilled.
It can for example be used to verify if certain status checks are mandatory. This can be helpful to decide if a certain check needs to be performed again after merging a pull request.`,
PreRunE: func(cmd *cobra.Command, _ []string) error {
startTime = time.Now()
log.SetStepName(STEP_NAME)
log.SetVerbose(GeneralConfig.Verbose)
path, _ := os.Getwd()
fatalHook := &log.FatalHook{CorrelationID: GeneralConfig.CorrelationID, Path: path}
log.RegisterHook(fatalHook)
err := PrepareConfig(cmd, &metadata, STEP_NAME, &stepConfig, config.OpenPiperFile)
if err != nil {
log.SetErrorCategory(log.ErrorConfiguration)
return err
}
log.RegisterSecret(stepConfig.Token)
if len(GeneralConfig.HookConfig.SentryConfig.Dsn) > 0 {
sentryHook := log.NewSentryHook(GeneralConfig.HookConfig.SentryConfig.Dsn, GeneralConfig.CorrelationID)
log.RegisterHook(&sentryHook)
}
return nil
},
Run: func(_ *cobra.Command, _ []string) {
telemetryData := telemetry.CustomData{}
telemetryData.ErrorCode = "1"
handler := func() {
telemetryData.Duration = fmt.Sprintf("%v", time.Since(startTime).Milliseconds())
telemetry.Send(&telemetryData)
}
log.DeferExitHandler(handler)
defer handler()
telemetry.Initialize(GeneralConfig.NoTelemetry, STEP_NAME)
githubCheckBranchProtection(stepConfig, &telemetryData)
telemetryData.ErrorCode = "0"
log.Entry().Info("SUCCESS")
},
}
addGithubCheckBranchProtectionFlags(createGithubCheckBranchProtectionCmd, &stepConfig)
return createGithubCheckBranchProtectionCmd
}
func addGithubCheckBranchProtectionFlags(cmd *cobra.Command, stepConfig *githubCheckBranchProtectionOptions) {
cmd.Flags().StringVar(&stepConfig.APIURL, "apiUrl", `https://api.github.com`, "Set the GitHub API url.")
cmd.Flags().StringVar(&stepConfig.Branch, "branch", os.Getenv("PIPER_branch"), "The name of the branch for which the protection settings should be checked.")
cmd.Flags().StringVar(&stepConfig.Owner, "owner", os.Getenv("PIPER_owner"), "Name of the GitHub organization.")
cmd.Flags().StringVar(&stepConfig.Repository, "repository", os.Getenv("PIPER_repository"), "Name of the GitHub repository.")
cmd.Flags().StringSliceVar(&stepConfig.RequiredChecks, "requiredChecks", []string{}, "List of checks which have to be set to required in the GitHub repository configuration.")
cmd.Flags().BoolVar(&stepConfig.RequireEnforceAdmins, "requireEnforceAdmins", false, "Check if 'Include Administrators' option is set in the GitHub repository configuration.")
cmd.Flags().IntVar(&stepConfig.RequiredApprovingReviewCount, "requiredApprovingReviewCount", 0, "Check if 'Require pull request reviews before merging' option is set with at least the defined number of reviewers in the GitHub repository configuration.")
cmd.Flags().StringVar(&stepConfig.Token, "token", os.Getenv("PIPER_token"), "GitHub personal access token as per https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line.")
cmd.MarkFlagRequired("apiUrl")
cmd.MarkFlagRequired("branch")
cmd.MarkFlagRequired("owner")
cmd.MarkFlagRequired("repository")
cmd.MarkFlagRequired("token")
}
// retrieve step metadata
func githubCheckBranchProtectionMetadata() config.StepData {
var theMetaData = config.StepData{
Metadata: config.StepMetadata{
Name: "githubCheckBranchProtection",
Aliases: []config.Alias{},
},
Spec: config.StepSpec{
Inputs: config.StepInputs{
Parameters: []config.StepParameters{
{
Name: "apiUrl",
ResourceRef: []config.ResourceReference{},
Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"},
Type: "string",
Mandatory: true,
Aliases: []config.Alias{{Name: "githubApiUrl"}},
},
{
Name: "branch",
ResourceRef: []config.ResourceReference{},
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
Type: "string",
Mandatory: true,
Aliases: []config.Alias{},
},
{
Name: "owner",
ResourceRef: []config.ResourceReference{},
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
Type: "string",
Mandatory: true,
Aliases: []config.Alias{{Name: "githubOrg"}},
},
{
Name: "repository",
ResourceRef: []config.ResourceReference{},
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
Type: "string",
Mandatory: true,
Aliases: []config.Alias{{Name: "githubRepo"}},
},
{
Name: "requiredChecks",
ResourceRef: []config.ResourceReference{},
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
Type: "[]string",
Mandatory: false,
Aliases: []config.Alias{},
},
{
Name: "requireEnforceAdmins",
ResourceRef: []config.ResourceReference{},
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
Type: "bool",
Mandatory: false,
Aliases: []config.Alias{},
},
{
Name: "requiredApprovingReviewCount",
ResourceRef: []config.ResourceReference{},
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
Type: "int",
Mandatory: false,
Aliases: []config.Alias{},
},
{
Name: "token",
ResourceRef: []config.ResourceReference{{Name: "githubTokenCredentialsId", Param: ""}},
Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"},
Type: "string",
Mandatory: true,
Aliases: []config.Alias{{Name: "githubToken"}},
},
},
},
},
}
return theMetaData
}

View File

@ -0,0 +1,16 @@
package cmd
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestGithubCheckBranchProtectionCommand(t *testing.T) {
testCmd := GithubCheckBranchProtectionCommand()
// only high level testing performed - details are tested in step generation procedure
assert.Equal(t, "githubCheckBranchProtection", testCmd.Use, "command name incorrect")
}

View File

@ -0,0 +1,105 @@
package cmd
import (
"context"
"fmt"
"testing"
"github.com/SAP/jenkins-library/pkg/telemetry"
"github.com/google/go-github/v32/github"
"github.com/stretchr/testify/assert"
)
type ghRepoService struct {
protection github.Protection
serviceError error
owner string
repo string
branch string
}
func (g *ghRepoService) GetBranchProtection(ctx context.Context, owner, repo, branch string) (*github.Protection, *github.Response, error) {
g.owner = owner
g.repo = repo
g.branch = branch
return &g.protection, nil, g.serviceError
}
func TestRunGithubCheckBranchProtection(t *testing.T) {
ctx := context.Background()
telemetryData := telemetry.CustomData{}
t.Run("no checks active", func(t *testing.T) {
config := githubCheckBranchProtectionOptions{Branch: "testBranch", Owner: "testOrg", Repository: "testRepo"}
ghRepo := ghRepoService{}
err := runGithubCheckBranchProtection(ctx, &config, &telemetryData, &ghRepo)
assert.NoError(t, err)
assert.Equal(t, config.Branch, ghRepo.branch)
assert.Equal(t, config.Owner, ghRepo.owner)
assert.Equal(t, config.Repository, ghRepo.repo)
})
t.Run("error calling GitHub", func(t *testing.T) {
config := githubCheckBranchProtectionOptions{Branch: "testBranch", Owner: "testOrg", Repository: "testRepo"}
ghRepo := ghRepoService{serviceError: fmt.Errorf("gh test error")}
err := runGithubCheckBranchProtection(ctx, &config, &telemetryData, &ghRepo)
assert.EqualError(t, err, "failed to read branch protection information: gh test error")
})
t.Run("all checks ok", func(t *testing.T) {
config := githubCheckBranchProtectionOptions{
Branch: "testBranch",
Owner: "testOrg",
Repository: "testRepo",
RequiredChecks: []string{"check1", "check2"},
RequireEnforceAdmins: true,
RequiredApprovingReviewCount: 1,
}
ghRepo := ghRepoService{protection: github.Protection{
RequiredStatusChecks: &github.RequiredStatusChecks{Contexts: []string{"check0", "check1", "check2", "check3"}},
EnforceAdmins: &github.AdminEnforcement{Enabled: true},
RequiredPullRequestReviews: &github.PullRequestReviewsEnforcement{RequiredApprovingReviewCount: 1},
}}
err := runGithubCheckBranchProtection(ctx, &config, &telemetryData, &ghRepo)
assert.NoError(t, err)
assert.Equal(t, config.Branch, ghRepo.branch)
assert.Equal(t, config.Owner, ghRepo.owner)
assert.Equal(t, config.Repository, ghRepo.repo)
})
t.Run("status check missing", func(t *testing.T) {
config := githubCheckBranchProtectionOptions{
RequiredChecks: []string{"check1", "check2"},
}
ghRepo := ghRepoService{protection: github.Protection{
RequiredStatusChecks: &github.RequiredStatusChecks{Contexts: []string{"check0", "check1"}},
}}
err := runGithubCheckBranchProtection(ctx, &config, &telemetryData, &ghRepo)
assert.Contains(t, fmt.Sprint(err), "required status check 'check2' not found")
})
t.Run("admin enforcement inactive", func(t *testing.T) {
config := githubCheckBranchProtectionOptions{
RequireEnforceAdmins: true,
}
ghRepo := ghRepoService{protection: github.Protection{
EnforceAdmins: &github.AdminEnforcement{Enabled: false},
}}
err := runGithubCheckBranchProtection(ctx, &config, &telemetryData, &ghRepo)
assert.Contains(t, fmt.Sprint(err), "admins are not enforced")
})
t.Run("not enough reviewers", func(t *testing.T) {
config := githubCheckBranchProtectionOptions{
RequiredApprovingReviewCount: 2,
}
ghRepo := ghRepoService{protection: github.Protection{
RequiredPullRequestReviews: &github.PullRequestReviewsEnforcement{RequiredApprovingReviewCount: 1},
}}
err := runGithubCheckBranchProtection(ctx, &config, &telemetryData, &ghRepo)
assert.Contains(t, fmt.Sprint(err), "not enough mandatory reviewers")
})
}

View File

@ -5,7 +5,7 @@ import (
"github.com/SAP/jenkins-library/pkg/log"
"github.com/SAP/jenkins-library/pkg/telemetry"
"github.com/google/go-github/v28/github"
"github.com/google/go-github/v32/github"
"github.com/pkg/errors"
piperGithub "github.com/SAP/jenkins-library/pkg/github"

View File

@ -90,8 +90,8 @@ func addGithubCreatePullRequestFlags(cmd *cobra.Command, stepConfig *githubCreat
cmd.Flags().StringVar(&stepConfig.Body, "body", os.Getenv("PIPER_body"), "The description text of the pull request in markdown format.")
cmd.Flags().StringVar(&stepConfig.APIURL, "apiUrl", `https://api.github.com`, "Set the GitHub API url.")
cmd.Flags().StringVar(&stepConfig.Head, "head", os.Getenv("PIPER_head"), "The name of the branch where your changes are implemented.")
cmd.Flags().StringVar(&stepConfig.Owner, "owner", os.Getenv("PIPER_owner"), "Set the GitHub organization.")
cmd.Flags().StringVar(&stepConfig.Repository, "repository", os.Getenv("PIPER_repository"), "Set the GitHub repository.")
cmd.Flags().StringVar(&stepConfig.Owner, "owner", os.Getenv("PIPER_owner"), "Name of the GitHub organization.")
cmd.Flags().StringVar(&stepConfig.Repository, "repository", os.Getenv("PIPER_repository"), "Name of the GitHub repository.")
cmd.Flags().StringVar(&stepConfig.ServerURL, "serverUrl", `https://github.com`, "GitHub server url for end-user access.")
cmd.Flags().StringVar(&stepConfig.Title, "title", os.Getenv("PIPER_title"), "Title of the pull request.")
cmd.Flags().StringVar(&stepConfig.Token, "token", os.Getenv("PIPER_token"), "GitHub personal access token as per https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line")

View File

@ -6,7 +6,7 @@ import (
"net/http"
"testing"
"github.com/google/go-github/v28/github"
"github.com/google/go-github/v32/github"
"github.com/stretchr/testify/assert"
)
@ -46,9 +46,9 @@ func (g *ghIssueMock) Edit(ctx context.Context, owner string, repo string, numbe
g.owner = owner
g.repo = repo
g.number = number
labels := []github.Label{}
labels := []*github.Label{}
for _, l := range *issue.Labels {
labels = append(labels, github.Label{Name: &l})
labels = append(labels, &github.Label{Name: &l})
}
assignees := []*github.User{}

View File

@ -10,7 +10,7 @@ import (
"github.com/SAP/jenkins-library/pkg/log"
"github.com/SAP/jenkins-library/pkg/telemetry"
"github.com/google/go-github/v28/github"
"github.com/google/go-github/v32/github"
"github.com/pkg/errors"
piperGithub "github.com/SAP/jenkins-library/pkg/github"

View File

@ -103,10 +103,10 @@ func addGithubPublishReleaseFlags(cmd *cobra.Command, stepConfig *githubPublishR
cmd.Flags().StringVar(&stepConfig.Commitish, "commitish", `master`, "Target git commitish for the release")
cmd.Flags().StringSliceVar(&stepConfig.ExcludeLabels, "excludeLabels", []string{}, "Allows to exclude issues with dedicated list of labels.")
cmd.Flags().StringSliceVar(&stepConfig.Labels, "labels", []string{}, "Labels to include in issue search.")
cmd.Flags().StringVar(&stepConfig.Owner, "owner", os.Getenv("PIPER_owner"), "Set the GitHub organization.")
cmd.Flags().StringVar(&stepConfig.Owner, "owner", os.Getenv("PIPER_owner"), "Name of the GitHub organization.")
cmd.Flags().BoolVar(&stepConfig.PreRelease, "preRelease", false, "If set to `true` the release will be marked as Pre-release.")
cmd.Flags().StringVar(&stepConfig.ReleaseBodyHeader, "releaseBodyHeader", os.Getenv("PIPER_releaseBodyHeader"), "Content which will appear for the release.")
cmd.Flags().StringVar(&stepConfig.Repository, "repository", os.Getenv("PIPER_repository"), "Set the GitHub repository.")
cmd.Flags().StringVar(&stepConfig.Repository, "repository", os.Getenv("PIPER_repository"), "Name of the GitHub repository.")
cmd.Flags().StringVar(&stepConfig.ServerURL, "serverUrl", `https://github.com`, "GitHub server url for end-user access.")
cmd.Flags().StringVar(&stepConfig.Token, "token", os.Getenv("PIPER_token"), "GitHub personal access token as per https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line")
cmd.Flags().StringVar(&stepConfig.UploadURL, "uploadUrl", `https://uploads.github.com`, "Set the GitHub API url.")

View File

@ -9,7 +9,7 @@ import (
"testing"
"time"
"github.com/google/go-github/v28/github"
"github.com/google/go-github/v32/github"
"github.com/stretchr/testify/assert"
)
@ -393,11 +393,11 @@ func TestIsExcluded(t *testing.T) {
}{
{issue: nil, excludeLabels: nil, expected: false},
{issue: &github.Issue{}, excludeLabels: nil, expected: false},
{issue: &github.Issue{Labels: []github.Label{{Name: &l1}}}, excludeLabels: nil, expected: false},
{issue: &github.Issue{Labels: []github.Label{{Name: &l1}}}, excludeLabels: []string{"label0"}, expected: false},
{issue: &github.Issue{Labels: []github.Label{{Name: &l1}}}, excludeLabels: []string{"label1"}, expected: true},
{issue: &github.Issue{Labels: []github.Label{{Name: &l1}, {Name: &l2}}}, excludeLabels: []string{}, expected: false},
{issue: &github.Issue{Labels: []github.Label{{Name: &l1}, {Name: &l2}}}, excludeLabels: []string{"label1"}, expected: true},
{issue: &github.Issue{Labels: []*github.Label{{Name: &l1}}}, excludeLabels: nil, expected: false},
{issue: &github.Issue{Labels: []*github.Label{{Name: &l1}}}, excludeLabels: []string{"label0"}, expected: false},
{issue: &github.Issue{Labels: []*github.Label{{Name: &l1}}}, excludeLabels: []string{"label1"}, expected: true},
{issue: &github.Issue{Labels: []*github.Label{{Name: &l1}, {Name: &l2}}}, excludeLabels: []string{}, expected: false},
{issue: &github.Issue{Labels: []*github.Label{{Name: &l1}, {Name: &l2}}}, excludeLabels: []string{"label1"}, expected: true},
}
for k, v := range tt {

View File

@ -70,8 +70,9 @@ func Execute() {
rootCmd.AddCommand(SonarExecuteScanCommand())
rootCmd.AddCommand(KubernetesDeployCommand())
rootCmd.AddCommand(XsDeployCommand())
rootCmd.AddCommand(GithubPublishReleaseCommand())
rootCmd.AddCommand(GithubCheckBranchProtectionCommand())
rootCmd.AddCommand(GithubCreatePullRequestCommand())
rootCmd.AddCommand(GithubPublishReleaseCommand())
rootCmd.AddCommand(CloudFoundryDeleteServiceCommand())
rootCmd.AddCommand(AbapEnvironmentPullGitRepoCommand())
rootCmd.AddCommand(AbapEnvironmentCloneGitRepoCommand())

2
go.mod
View File

@ -24,7 +24,7 @@ require (
github.com/go-openapi/strfmt v0.19.5
github.com/google/go-cmp v0.5.2
github.com/google/go-containerregistry v0.1.2
github.com/google/go-github/v28 v28.1.1
github.com/google/go-github/v32 v32.1.1-0.20200822031254-5f5296864910
github.com/google/uuid v1.1.2
github.com/hashicorp/go-multierror v1.1.0 // indirect
github.com/hashicorp/go-retryablehttp v0.6.7 // indirect

2
go.sum
View File

@ -525,6 +525,8 @@ github.com/google/go-containerregistry v0.1.2 h1:YjFNKqxzWUVZND8d4ItF9wuYlE75WQf
github.com/google/go-containerregistry v0.1.2/go.mod h1:GPivBPgdAyd2SU+vf6EpsgOtWDuPqjW0hJZt4rNdTZ4=
github.com/google/go-github/v28 v28.1.1 h1:kORf5ekX5qwXO2mGzXXOjMe/g6ap8ahVe0sBEulhSxo=
github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM=
github.com/google/go-github/v32 v32.1.1-0.20200822031254-5f5296864910 h1:LHut2hbOGGxCSGE4OGRuiah5kPcUBM0dHdmI3FEj2jc=
github.com/google/go-github/v32 v32.1.1-0.20200822031254-5f5296864910/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/go-replayers/grpcreplay v0.1.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE=

View File

@ -3,7 +3,7 @@ package github
import (
"context"
"github.com/google/go-github/v28/github"
"github.com/google/go-github/v32/github"
"golang.org/x/oauth2"
)

View File

@ -0,0 +1,90 @@
metadata:
name: githubCheckBranchProtection
description: Check branch protection of a GitHub branch
longDescription: |
This step allows you to check if certain branch protection rules are fulfilled.
It can for example be used to verify if certain status checks are mandatory. This can be helpful to decide if a certain check needs to be performed again after merging a pull request.
spec:
inputs:
secrets:
- name: githubTokenCredentialsId
description: Jenkins 'Secret text' credentials ID containing token to authenticate to GitHub.
type: jenkins
params:
- name: apiUrl
aliases:
- name: githubApiUrl
description: Set the GitHub API url.
scope:
- GENERAL
- PARAMETERS
- STAGES
- STEPS
type: string
default: https://api.github.com
mandatory: true
- name: branch
description: The name of the branch for which the protection settings should be checked.
scope:
- PARAMETERS
- STAGES
- STEPS
type: string
mandatory: true
- name: owner
aliases:
- name: githubOrg
description: Name of the GitHub organization.
scope:
- PARAMETERS
- STAGES
- STEPS
type: string
mandatory: true
- name: repository
aliases:
- name: githubRepo
description: Name of the GitHub repository.
scope:
- PARAMETERS
- STAGES
- STEPS
type: string
mandatory: true
- name: requiredChecks
description: List of checks which have to be set to required in the GitHub repository configuration.
scope:
- PARAMETERS
- STAGES
- STEPS
type: "[]string"
- name: requireEnforceAdmins
description: Check if 'Include Administrators' option is set in the GitHub repository configuration.
scope:
- PARAMETERS
- STAGES
- STEPS
type: bool
- name: requiredApprovingReviewCount
description: Check if 'Require pull request reviews before merging' option is set with at least the defined number of reviewers in the GitHub repository configuration.
scope:
- PARAMETERS
- STAGES
- STEPS
type: int
- name: token
aliases:
- name: githubToken
description: GitHub personal access token as per https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line.
scope:
- GENERAL
- PARAMETERS
- STAGES
- STEPS
type: string
mandatory: true
secret: true
resourceRef:
- name: githubTokenCredentialsId
type: secret

View File

@ -58,7 +58,7 @@ spec:
- name: owner
aliases:
- name: githubOrg
description: Set the GitHub organization.
description: Name of the GitHub organization.
scope:
- PARAMETERS
- STAGES
@ -68,7 +68,7 @@ spec:
- name: repository
aliases:
- name: githubRepo
description: Set the GitHub repository.
description: Name of the GitHub repository.
scope:
- PARAMETERS
- STAGES

View File

@ -79,7 +79,7 @@ spec:
- name: owner
aliases:
- name: githubOrg
description: "Set the GitHub organization."
description: Name of the GitHub organization.
resourceRef:
- name: commonPipelineEnvironment
param: github/owner
@ -107,7 +107,7 @@ spec:
- name: repository
aliases:
- name: githubRepo
description: "Set the GitHub repository."
description: Name of the GitHub repository.
resourceRef:
- name: commonPipelineEnvironment
param: github/repository

View File

@ -130,6 +130,7 @@ public class CommonStepsTest extends BasePiperTest{
'runClosures',
'checkmarxExecuteScan', //implementing new golang pattern without fields
'githubPublishRelease', //implementing new golang pattern without fields
'githubCheckBranchProtection', //implementing new golang pattern without fields
'kubernetesDeploy', //implementing new golang pattern without fields
'piperExecuteBin', //implementing new golang pattern without fields
'protecodeExecuteScan', //implementing new golang pattern without fields

View File

@ -0,0 +1,11 @@
import groovy.transform.Field
@Field String STEP_NAME = getClass().getName()
@Field String METADATA_FILE = 'metadata/githubbranchprotection.yaml'
void call(Map parameters = [:]) {
List credentials = [
[type: 'token', id: 'githubTokenCredentialsId', env: ['PIPER_token']]
]
piperExecuteBin(parameters, STEP_NAME, METADATA_FILE, credentials)
}