Skip to content

Commit

Permalink
Get the Golang code in sync with Bash
Browse files Browse the repository at this point in the history
  • Loading branch information
azeemsgoogle committed Jun 16, 2022
1 parent 1ca6c49 commit 712a1b2
Show file tree
Hide file tree
Showing 4 changed files with 355 additions and 129 deletions.
25 changes: 11 additions & 14 deletions entrypoint/entrypoint.go
Expand Up @@ -17,12 +17,13 @@ package entrypoint
import (
"errors"
"fmt"
"io"
"os"

"github.com/spf13/cobra"

"github.com/ossf/scorecard-action/options"
"github.com/ossf/scorecard/v4/cmd"
sccmd "github.com/ossf/scorecard/v4/cmd"
scopts "github.com/ossf/scorecard/v4/options"
)

Expand All @@ -33,22 +34,20 @@ func New() (*cobra.Command, error) {
if err != nil {
return nil, fmt.Errorf("creating new options: %w", err)
}

if err := opts.Initialize(); err != nil {
return nil, fmt.Errorf("initializing options: %w", err)
if err := opts.Validate(); err != nil {
return nil, fmt.Errorf("validating options: %w", err)
}
opts.Print()

// Adapt Scorecard CMD.
scOpts := opts.ScorecardOpts

actionCmd := cmd.New(scOpts)

actionCmd := sccmd.New(scOpts)
actionCmd.Flags().StringVar(
&scOpts.ResultsFile,
"output-file",
scOpts.ResultsFile,
"path to output results to",
)

actionCmd.Flags().BoolVar(
&opts.PublishResults,
"publish",
Expand All @@ -60,11 +59,6 @@ func New() (*cobra.Command, error) {
// TODO(scorecard): Move this into scorecard
var out, stdout *os.File
actionCmd.PreRunE = func(cmd *cobra.Command, args []string) error {
err := scOpts.Validate()
if err != nil {
return fmt.Errorf("validating options: %w", err)
}

// TODO: the results file should be completed and validated by the time we get it.
if scOpts.ResultsFile != "" {
var err error
Expand All @@ -81,12 +75,15 @@ func New() (*cobra.Command, error) {
os.Stdout = out
actionCmd.SetOut(out)
}

return nil
}

actionCmd.PersistentPostRun = func(cmd *cobra.Command, args []string) {
if out != nil {
if _, err = out.Seek(0, io.SeekStart); err == nil {
// nolint:errcheck
_, _ = io.Copy(stdout, out)
}
_ = out.Close()
}
os.Stdout = stdout
Expand Down
180 changes: 87 additions & 93 deletions options/options.go
Expand Up @@ -26,16 +26,25 @@ import (
"github.com/caarlos0/env/v6"

"github.com/ossf/scorecard-action/github"
"github.com/ossf/scorecard/v4/checks"
scopts "github.com/ossf/scorecard/v4/options"
)

const (
defaultScorecardPolicyFile = "/policy.yml"
trueStr = "true"
formatSarif = scopts.FormatSarif

pullRequestEvent = "pull_request"
pushEvent = "push"
branchProtectionEvent = "branch_protection_rule"
)

var (
// Errors.
errGithubEventPathEmpty = errors.New("GitHub event path is empty")
errResultsPathEmpty = errors.New("results path is empty")
errOnlyDefaultBranchSupported = errors.New("only default branch is supported")

trueStr = "true"
)

// Options are options for running scorecard via GitHub Actions.
Expand Down Expand Up @@ -72,99 +81,20 @@ type Options struct {
PublishResults bool
}

const (
defaultScorecardPolicyFile = "/policy.yml"
formatSarif = scopts.FormatSarif
)

// New creates a new options set for running scorecard via GitHub Actions.
func New() (*Options, error) {
// Enable scorecard command to use SARIF format.
os.Setenv(scopts.EnvVarEnableSarif, trueStr)

opts := &Options{
ScorecardOpts: scopts.New(),
}
opts := &Options{}
if err := env.Parse(opts); err != nil {
return opts, fmt.Errorf("parsing entrypoint env vars: %w", err)
}

opts.ScorecardOpts.ShowDetails = true
// This section restores functionality that was removed in
// https://github.com/ossf/scorecard/pull/1898.
// TODO(options): Consider moving this to its own function.
opts.ScorecardOpts.Repo = opts.GithubRepository

if err := opts.Initialize(); err != nil {
return opts, fmt.Errorf(
"initializing scorecard-action options: %w",
err,
)
}

// TODO(options): Move this set-or-default logic to its own function.
opts.ScorecardOpts.Format = formatSarif
opts.ScorecardOpts.EnableSarif = true
if opts.InputResultsFormat != "" {
opts.ScorecardOpts.Format = opts.InputResultsFormat
}

if opts.ScorecardOpts.Format == formatSarif {
if opts.ScorecardOpts.PolicyFile == "" {
// TODO(policy): Should we default or error here?
opts.ScorecardOpts.PolicyFile = defaultScorecardPolicyFile
}
}

// TODO(scorecard): Reset commit options. Fix this in scorecard.
opts.ScorecardOpts.Commit = scopts.DefaultCommit

if err := opts.ScorecardOpts.Validate(); err != nil {
return opts, fmt.Errorf("validating scorecard options: %w", err)
}

opts.SetPublishResults()

if opts.ScorecardOpts.ResultsFile == "" {
opts.ScorecardOpts.ResultsFile = opts.InputResultsFile
}

if opts.ScorecardOpts.ResultsFile == "" {
// TODO(test): Reassess test case for this code path
return opts, errResultsPathEmpty
if err := opts.setRepoInfo(); err != nil {
return opts, fmt.Errorf("parsing repo info: %w", err)
}

if err := opts.Validate(); err != nil {
return opts, fmt.Errorf("validating scorecard-action options: %w", err)
}

opts.setScorecardOpts()
opts.setPublishResults()
return opts, nil
}

// Initialize initializes the environment variables required for the action.
func (o *Options) Initialize() error {
/*
https://docs.github.com/en/actions/learn-github-actions/environment-variables
GITHUB_EVENT_PATH contains the json file for the event.
GITHUB_SHA contains the commit hash.
GITHUB_WORKSPACE contains the repo folder.
GITHUB_EVENT_NAME contains the event name.
GITHUB_ACTIONS is true in GitHub env.
*/

// TODO(checks): Do we actually expect to use these?
// o.EnableLicense = "1"
// o.EnableDangerousWorkflow = "1"

_, tokenSet := os.LookupEnv(EnvGithubAuthToken)
if !tokenSet {
inputToken := os.Getenv(EnvInputRepoToken)
os.Setenv(EnvGithubAuthToken, inputToken)
}

return o.SetRepoInfo()
}

// Validate validates the scorecard configuration.
func (o *Options) Validate() error {
if os.Getenv(EnvGithubAuthToken) == "" {
Expand All @@ -180,14 +110,20 @@ func (o *Options) Validate() error {
return errEmptyGitHubAuthToken
}

if strings.Contains(o.GithubEventName, "pull_request") &&
o.GithubRef != o.DefaultBranch {
if !o.isPullRequestEvent() &&
!o.isDefaultBranch() {
fmt.Printf("%s not supported with %s event.\n", o.GithubRef, o.GithubEventName)
fmt.Printf("Only the default branch %s is supported.\n", o.DefaultBranch)

return errOnlyDefaultBranchSupported
}

if err := o.ScorecardOpts.Validate(); err != nil {
return fmt.Errorf("validating scorecard options: %w", err)
}
if o.ScorecardOpts.ResultsFile == "" {
// TODO(test): Reassess test case for this code path
return errResultsPathEmpty
}
return nil
}

Expand All @@ -205,9 +141,59 @@ func (o *Options) Print() {
fmt.Printf("Default branch: %s\n", o.DefaultBranch)
}

// SetPublishResults sets whether results should be published based on a
func (o *Options) setScorecardOpts() {
o.ScorecardOpts = scopts.New()
// GITHUB_AUTH_TOKEN
_, tokenSet := os.LookupEnv(EnvGithubAuthToken)
if !tokenSet {
inputToken := os.Getenv(EnvInputRepoToken)
os.Setenv(EnvGithubAuthToken, inputToken)
}

// --repo= | --local
// This section restores functionality that was removed in
// https://github.com/ossf/scorecard/pull/1898.
// TODO(options): Consider moving this to its own function.
if !o.isPullRequestEvent() {
o.ScorecardOpts.Repo = o.GithubRepository
} else {
o.ScorecardOpts.Local = "."
}

// --format=
// Enable scorecard command to use SARIF format (default format).
os.Setenv(scopts.EnvVarEnableSarif, trueStr)
o.ScorecardOpts.EnableSarif = true
o.ScorecardOpts.Format = formatSarif
if o.InputResultsFormat != "" {
o.ScorecardOpts.Format = o.InputResultsFormat
}
if o.ScorecardOpts.Format == formatSarif && o.ScorecardOpts.PolicyFile == "" {
// TODO(policy): Should we default or error here?
o.ScorecardOpts.PolicyFile = defaultScorecardPolicyFile
}

// --checks=
if o.GithubEventName == branchProtectionEvent {
o.ScorecardOpts.ChecksToRun = []string{checks.CheckBranchProtection}
}

// --show-details
o.ScorecardOpts.ShowDetails = true

// --commit=
// TODO(scorecard): Reset commit options. Fix this in scorecard.
o.ScorecardOpts.Commit = scopts.DefaultCommit

// --out-file=
if o.ScorecardOpts.ResultsFile == "" {
o.ScorecardOpts.ResultsFile = o.InputResultsFile
}
}

// setPublishResults sets whether results should be published based on a
// repository's visibility.
func (o *Options) SetPublishResults() {
func (o *Options) setPublishResults() {
privateRepo, err := strconv.ParseBool(o.PrivateRepoStr)
if err != nil {
// TODO(options): Consider making this an error.
Expand All @@ -221,11 +207,11 @@ func (o *Options) SetPublishResults() {
o.PublishResults = o.PublishResults && !privateRepo
}

// SetRepoInfo gets the path to the GitHub event and sets the
// setRepoInfo gets the path to the GitHub event and sets the
// SCORECARD_IS_FORK environment variable.
// TODO(options): Check if this actually needs to be exported.
// TODO(options): Choose a more accurate name for what this does.
func (o *Options) SetRepoInfo() error {
func (o *Options) setRepoInfo() error {
eventPath := o.GithubEventPath
if eventPath == "" {
return errGithubEventPathEmpty
Expand All @@ -247,3 +233,11 @@ func (o *Options) SetRepoInfo() error {

return nil
}

func (o *Options) isPullRequestEvent() bool {
return strings.HasPrefix(o.GithubEventName, pullRequestEvent)
}

func (o *Options) isDefaultBranch() bool {
return o.GithubRef == fmt.Sprintf("refs/heads/%s", o.DefaultBranch)
}

0 comments on commit 712a1b2

Please sign in to comment.