From 41bc7b2497d3e5a20318fe5a4b808051607558ad Mon Sep 17 00:00:00 2001 From: laurentsimon <64505099+laurentsimon@users.noreply.github.com> Date: Wed, 22 Mar 2023 14:40:00 -0700 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Support=20for=20GitHub's=20internal?= =?UTF-8?q?=20integration=20(#2773)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * update Signed-off-by: laurentsimon * update Signed-off-by: laurentsimon * update Signed-off-by: laurentsimon * update Signed-off-by: laurentsimon * update Signed-off-by: laurentsimon * update Signed-off-by: laurentsimon --------- Signed-off-by: laurentsimon Signed-off-by: Avishay --- cmd/root.go | 2 +- options/options.go | 28 ++++++++++++++++++++++++++++ pkg/sarif.go | 12 +++++++++++- pkg/sarif_test.go | 3 ++- pkg/scorecard_result.go | 2 +- 5 files changed, 43 insertions(+), 4 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index 425bdf33dc2..da4cd0610d0 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -113,7 +113,7 @@ func rootCmd(o *options.Options) error { if !strings.EqualFold(o.Commit, clients.HeadSHA) { requiredRequestTypes = append(requiredRequestTypes, checker.CommitBased) } - enabledChecks, err := policy.GetEnabled(pol, o.ChecksToRun, requiredRequestTypes) + enabledChecks, err := policy.GetEnabled(pol, o.Checks(), requiredRequestTypes) if err != nil { return fmt.Errorf("GetEnabled: %w", err) } diff --git a/options/options.go b/options/options.go index 72358684a38..a7d4d4d13c9 100644 --- a/options/options.go +++ b/options/options.go @@ -19,6 +19,7 @@ import ( "errors" "fmt" "os" + "strings" "github.com/caarlos0/env/v6" @@ -205,6 +206,33 @@ func boolSum(bools ...bool) int { // Feature flags. +// GitHub integration support. +// See https://github.com/ossf/scorecard-action/issues/1107. +// NOTE: We don't add a field to to the Option structure to simplify +// integration. If we did, the Action would also need to be aware +// of the integration and pass the relevant values. This +// would add redundancy and complicate maintenance. +func (o *Options) IsInternalGitHubIntegrationEnabled() bool { + return (os.Getenv("CI") == "true") && + (os.Getenv("SCORECARD_INTERNAL_GITHUB_INTEGRATION") == "1") && + (os.Getenv("GITHUB_EVENT_NAME") == "dynamic") +} + +// Checks returns the list of checks and honours the +// GitHub integration. +func (o *Options) Checks() []string { + if o.IsInternalGitHubIntegrationEnabled() { + // Overwrite the list of checks. + s := os.Getenv("SCORECARD_INTERNAL_GITHUB_CHECKS") + l := strings.Split(s, ",") + for i := range l { + l[i] = strings.TrimSpace(l[i]) + } + return l + } + return o.ChecksToRun +} + // isExperimentalEnabled returns true if experimental features were enabled via // environment variable. func (o *Options) isExperimentalEnabled() bool { diff --git a/pkg/sarif.go b/pkg/sarif.go index 2cd2f8cb21c..8977f6d01c0 100644 --- a/pkg/sarif.go +++ b/pkg/sarif.go @@ -18,6 +18,7 @@ import ( "encoding/json" "fmt" "io" + "os" "sort" "strings" "time" @@ -31,6 +32,7 @@ import ( sce "github.com/ossf/scorecard/v4/errors" "github.com/ossf/scorecard/v4/finding" "github.com/ossf/scorecard/v4/log" + "github.com/ossf/scorecard/v4/options" spol "github.com/ossf/scorecard/v4/policy" ) @@ -606,9 +608,17 @@ func createDefaultLocationMessage(check *checker.CheckResult, score int) string return messageWithScore(check.Reason, score) } +func toolName(opts *options.Options) string { + if opts.IsInternalGitHubIntegrationEnabled() { + return strings.TrimSpace(os.Getenv("SCORECARD_INTERNAL_GITHUB_SARIF_TOOL_NAME")) + } + return "scorecard" +} + // AsSARIF outputs ScorecardResult in SARIF 2.1.0 format. func (r *ScorecardResult) AsSARIF(showDetails bool, logLevel log.Level, writer io.Writer, checkDocs docs.Doc, policy *spol.ScorecardPolicy, + opts *options.Options, ) error { //nolint // https://docs.oasis-open.org/sarif/sarif/v2.1.0/cs01/sarif-v2.1.0-cs01.html. @@ -635,7 +645,7 @@ func (r *ScorecardResult) AsSARIF(showDetails bool, logLevel log.Level, if err != nil { return sce.WithMessage(sce.ErrScorecardInternal, fmt.Sprintf("computeCategory: %v: %s", err, check.Name)) } - run := getOrCreateSARIFRun(runs, category, "https://github.com/ossf/scorecard", "scorecard", + run := getOrCreateSARIFRun(runs, category, "https://github.com/ossf/scorecard", toolName(opts), r.Scorecard.Version, r.Scorecard.CommitSHA, r.Date, "supply-chain") // Always add rules to indicate which checks were run. diff --git a/pkg/sarif_test.go b/pkg/sarif_test.go index 739161fd8ad..1fa37e52362 100644 --- a/pkg/sarif_test.go +++ b/pkg/sarif_test.go @@ -26,6 +26,7 @@ import ( "github.com/ossf/scorecard/v4/checker" "github.com/ossf/scorecard/v4/finding" "github.com/ossf/scorecard/v4/log" + "github.com/ossf/scorecard/v4/options" spol "github.com/ossf/scorecard/v4/policy" rules "github.com/ossf/scorecard/v4/rule" ) @@ -847,7 +848,7 @@ func TestSARIFOutput(t *testing.T) { var result bytes.Buffer err = tt.result.AsSARIF(tt.showDetails, tt.logLevel, &result, - checkDocs, &tt.policy) + checkDocs, &tt.policy, &options.Options{}) if err != nil { t.Fatalf("%s: AsSARIF: %v", tt.name, err) } diff --git a/pkg/scorecard_result.go b/pkg/scorecard_result.go index caae7ea5969..1af8a08e143 100644 --- a/pkg/scorecard_result.go +++ b/pkg/scorecard_result.go @@ -114,7 +114,7 @@ func FormatResults( err = results.AsString(opts.ShowDetails, log.ParseLevel(opts.LogLevel), doc, os.Stdout) case options.FormatSarif: // TODO: support config files and update checker.MaxResultScore. - err = results.AsSARIF(opts.ShowDetails, log.ParseLevel(opts.LogLevel), os.Stdout, doc, policy) + err = results.AsSARIF(opts.ShowDetails, log.ParseLevel(opts.LogLevel), os.Stdout, doc, policy, opts) case options.FormatJSON: err = results.AsJSON2(opts.ShowDetails, log.ParseLevel(opts.LogLevel), doc, os.Stdout) case options.FormatSJSON: