🌱 Change finding Values to map[string]string (#3837)

* make values map string -> string

Signed-off-by: Spencer Schrock <sschrock@google.com>

* fixup branch protection probes

Signed-off-by: Spencer Schrock <sschrock@google.com>

* fix sast probe

Signed-off-by: Spencer Schrock <sschrock@google.com>

* fix signed-releases probes

Signed-off-by: Spencer Schrock <sschrock@google.com>

* fix maintained probes

Signed-off-by: Spencer Schrock <sschrock@google.com>

* fix cii-best-practices probes

Signed-off-by: Spencer Schrock <sschrock@google.com>

* fix cii-best-practices eval

Signed-off-by: Spencer Schrock <sschrock@google.com>

* fix signed-releases eval

Signed-off-by: Spencer Schrock <sschrock@google.com>

* fix sast eval

Signed-off-by: Spencer Schrock <sschrock@google.com>

* fix maintained eval

Signed-off-by: Spencer Schrock <sschrock@google.com>

* fix permissions eval

Signed-off-by: Spencer Schrock <sschrock@google.com>

* appease the linter

Signed-off-by: Spencer Schrock <sschrock@google.com>

* standardize maintained key names

Signed-off-by: Spencer Schrock <sschrock@google.com>

* set lookback days value regardless of outcome

Signed-off-by: Spencer Schrock <sschrock@google.com>

---------

Signed-off-by: Spencer Schrock <sschrock@google.com>
This commit is contained in:
Spencer Schrock 2024-02-07 10:55:16 -08:00 committed by GitHub
parent fb7739049b
commit ca944e8169
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
30 changed files with 302 additions and 344 deletions

View File

@ -56,27 +56,26 @@ func CIIBestPractices(name string,
text = "no effort to earn an OpenSSF best practices badge detected"
return checker.CreateMinScoreResult(name, text)
}
//nolint:nestif
if _, hasKey := f.Values[hasOpenSSFBadge.GoldLevel]; hasKey {
level, ok := f.Values[hasOpenSSFBadge.LevelKey]
if !ok {
return checker.CreateRuntimeErrorResult(name, sce.WithMessage(sce.ErrScorecardInternal, "no badge level present"))
}
switch level {
case hasOpenSSFBadge.GoldLevel:
score = checker.MaxResultScore
text = "badge detected: Gold"
} else if _, hasKey := f.Values[hasOpenSSFBadge.SilverLevel]; hasKey {
case hasOpenSSFBadge.SilverLevel:
score = silverScore
text = "badge detected: Silver"
} else if _, hasKey := f.Values[hasOpenSSFBadge.PassingLevel]; hasKey {
case hasOpenSSFBadge.PassingLevel:
score = passingScore
text = "badge detected: Passing"
} else if _, hasKey := f.Values[hasOpenSSFBadge.InProgressLevel]; hasKey {
case hasOpenSSFBadge.InProgressLevel:
score = inProgressScore
text = "badge detected: InProgress"
} else if _, hasKey := f.Values[hasOpenSSFBadge.UnknownLevel]; hasKey {
text = "unknown badge detected"
e := sce.WithMessage(sce.ErrScorecardInternal, text)
return checker.CreateRuntimeErrorResult(name, e)
} else {
text = "unsupported badge detected"
e := sce.WithMessage(sce.ErrScorecardInternal, text)
return checker.CreateRuntimeErrorResult(name, e)
default:
return checker.CreateRuntimeErrorResult(name, sce.WithMessage(sce.ErrScorecardInternal, "unsupported badge detected"))
}
return checker.CreateResultWithScore(name, text, score)

View File

@ -35,8 +35,8 @@ func TestCIIBestPractices(t *testing.T) {
{
Probe: "hasOpenSSFBadge",
Outcome: finding.OutcomeNegative,
Values: map[string]int{
"Unsupported": 1,
Values: map[string]string{
hasOpenSSFBadge.LevelKey: "Unsupported",
},
},
},
@ -50,8 +50,8 @@ func TestCIIBestPractices(t *testing.T) {
{
Probe: "hasOpenSSFBadge",
Outcome: finding.OutcomePositive,
Values: map[string]int{
"Unsupported": 1,
Values: map[string]string{
hasOpenSSFBadge.LevelKey: "Unsupported",
},
},
},
@ -66,8 +66,8 @@ func TestCIIBestPractices(t *testing.T) {
{
Probe: "hasOpenSSFBadge",
Outcome: finding.OutcomePositive,
Values: map[string]int{
hasOpenSSFBadge.InProgressLevel: 1,
Values: map[string]string{
hasOpenSSFBadge.LevelKey: hasOpenSSFBadge.InProgressLevel,
},
},
},
@ -81,8 +81,8 @@ func TestCIIBestPractices(t *testing.T) {
{
Probe: "hasOpenSSFBadge",
Outcome: finding.OutcomePositive,
Values: map[string]int{
hasOpenSSFBadge.PassingLevel: 1,
Values: map[string]string{
hasOpenSSFBadge.LevelKey: hasOpenSSFBadge.PassingLevel,
},
},
},
@ -96,8 +96,8 @@ func TestCIIBestPractices(t *testing.T) {
{
Probe: "hasOpenSSFBadge",
Outcome: finding.OutcomePositive,
Values: map[string]int{
hasOpenSSFBadge.SilverLevel: 1,
Values: map[string]string{
hasOpenSSFBadge.LevelKey: hasOpenSSFBadge.SilverLevel,
},
},
},
@ -111,8 +111,8 @@ func TestCIIBestPractices(t *testing.T) {
{
Probe: "hasOpenSSFBadge",
Outcome: finding.OutcomePositive,
Values: map[string]int{
hasOpenSSFBadge.GoldLevel: 1,
Values: map[string]string{
hasOpenSSFBadge.LevelKey: hasOpenSSFBadge.GoldLevel,
},
},
},
@ -126,8 +126,8 @@ func TestCIIBestPractices(t *testing.T) {
{
Probe: "hasOpenSSFBadge",
Outcome: finding.OutcomePositive,
Values: map[string]int{
"Unknown": 1,
Values: map[string]string{
hasOpenSSFBadge.LevelKey: hasOpenSSFBadge.UnknownLevel,
},
},
},

View File

@ -16,6 +16,7 @@ package evaluation
import (
"fmt"
"strconv"
"github.com/ossf/scorecard/v4/checker"
sce "github.com/ossf/scorecard/v4/errors"
@ -59,17 +60,22 @@ func Maintained(name string,
return checker.CreateMinScoreResult(name, "project was created in last 90 days. please review its contents carefully")
}
commitsWithinThreshold := 0
numberOfIssuesUpdatedWithinThreshold := 0
var commitsWithinThreshold, numberOfIssuesUpdatedWithinThreshold int
var err error
for i := range findings {
f := &findings[i]
if f.Outcome == finding.OutcomePositive {
switch f.Probe {
case issueActivityByProjectMember.Probe:
numberOfIssuesUpdatedWithinThreshold = f.Values[issueActivityByProjectMember.NoOfIssuesValue]
numberOfIssuesUpdatedWithinThreshold, err = strconv.Atoi(f.Values[issueActivityByProjectMember.NumIssuesKey])
if err != nil {
return checker.CreateRuntimeErrorResult(name, sce.WithMessage(sce.ErrScorecardInternal, err.Error()))
}
case hasRecentCommits.Probe:
commitsWithinThreshold = f.Values[hasRecentCommits.CommitsValue]
commitsWithinThreshold, err = strconv.Atoi(f.Values[hasRecentCommits.NumCommitsKey])
if err != nil {
return checker.CreateRuntimeErrorResult(name, sce.WithMessage(sce.ErrScorecardInternal, err.Error()))
}
}
}
}

View File

@ -18,6 +18,10 @@ import (
sce "github.com/ossf/scorecard/v4/errors"
"github.com/ossf/scorecard/v4/finding"
"github.com/ossf/scorecard/v4/probes/hasRecentCommits"
"github.com/ossf/scorecard/v4/probes/issueActivityByProjectMember"
"github.com/ossf/scorecard/v4/probes/notArchived"
"github.com/ossf/scorecard/v4/probes/notCreatedRecently"
scut "github.com/ossf/scorecard/v4/utests"
)
@ -32,22 +36,22 @@ func TestMaintained(t *testing.T) {
name: "Two commits in last 90 days",
findings: []finding.Finding{
{
Probe: "hasRecentCommits",
Probe: hasRecentCommits.Probe,
Outcome: finding.OutcomePositive,
Values: map[string]int{
"commitsWithinThreshold": 2,
Values: map[string]string{
hasRecentCommits.NumCommitsKey: "2",
},
}, {
Probe: "issueActivityByProjectMember",
Probe: issueActivityByProjectMember.Probe,
Outcome: finding.OutcomePositive,
Values: map[string]int{
"numberOfIssuesUpdatedWithinThreshold": 1,
Values: map[string]string{
issueActivityByProjectMember.NumIssuesKey: "1",
},
}, {
Probe: "notArchived",
Probe: notArchived.Probe,
Outcome: finding.OutcomePositive,
}, {
Probe: "notCreatedRecently",
Probe: notCreatedRecently.Probe,
Outcome: finding.OutcomePositive,
},
},
@ -59,16 +63,16 @@ func TestMaintained(t *testing.T) {
name: "No issues, no commits and not archived",
findings: []finding.Finding{
{
Probe: "hasRecentCommits",
Probe: hasRecentCommits.Probe,
Outcome: finding.OutcomeNegative,
}, {
Probe: "issueActivityByProjectMember",
Probe: issueActivityByProjectMember.Probe,
Outcome: finding.OutcomeNegative,
}, {
Probe: "notArchived",
Probe: notArchived.Probe,
Outcome: finding.OutcomePositive,
}, {
Probe: "notCreatedRecently",
Probe: notCreatedRecently.Probe,
Outcome: finding.OutcomePositive,
},
},
@ -80,16 +84,16 @@ func TestMaintained(t *testing.T) {
name: "Wrong probe name",
findings: []finding.Finding{
{
Probe: "hasRecentCommits",
Probe: hasRecentCommits.Probe,
Outcome: finding.OutcomeNegative,
}, {
Probe: "issueActivityByProjectMember",
Probe: issueActivityByProjectMember.Probe,
Outcome: finding.OutcomeNegative,
}, {
Probe: "archvied", /*misspelling*/
Outcome: finding.OutcomePositive,
}, {
Probe: "notCreatedRecently",
Probe: notCreatedRecently.Probe,
Outcome: finding.OutcomePositive,
},
},
@ -102,16 +106,16 @@ func TestMaintained(t *testing.T) {
name: "Project is archived",
findings: []finding.Finding{
{
Probe: "hasRecentCommits",
Probe: hasRecentCommits.Probe,
Outcome: finding.OutcomeNegative,
}, {
Probe: "issueActivityByProjectMember",
Probe: issueActivityByProjectMember.Probe,
Outcome: finding.OutcomeNegative,
}, {
Probe: "notArchived",
Probe: notArchived.Probe,
Outcome: finding.OutcomeNegative,
}, {
Probe: "notCreatedRecently",
Probe: notCreatedRecently.Probe,
Outcome: finding.OutcomePositive,
},
},

View File

@ -38,56 +38,56 @@ var (
topNoWriteID = "gitHubWorkflowPermissionsTopNoWrite"
)
type permissionLevel int
type permissionLevel string
const (
// permissionLevelNone is a permission set to `none`.
permissionLevelNone permissionLevel = iota
permissionLevelNone permissionLevel = "none"
// permissionLevelRead is a permission set to `read`.
permissionLevelRead
permissionLevelRead permissionLevel = "read"
// permissionLevelUnknown is for other kinds of alerts, mostly to support debug messages.
// TODO: remove it once we have implemented severity (#1874).
permissionLevelUnknown
permissionLevelUnknown permissionLevel = "unknown"
// permissionLevelUndeclared is an undeclared permission.
permissionLevelUndeclared
permissionLevelUndeclared permissionLevel = "undeclared"
// permissionLevelWrite is a permission set to `write` for a permission we consider potentially dangerous.
permissionLevelWrite
permissionLevelWrite permissionLevel = "write"
)
// permissionLocation represents a declaration type.
type permissionLocationType int
type permissionLocationType string
const (
// permissionLocationNil is in case the permission is nil.
permissionLocationNil permissionLocationType = iota
permissionLocationNil permissionLocationType = "nil"
// permissionLocationNotDeclared is for undeclared permission.
permissionLocationNotDeclared
permissionLocationNotDeclared permissionLocationType = "not declared"
// permissionLocationTop is top-level workflow permission.
permissionLocationTop
permissionLocationTop permissionLocationType = "top"
// permissionLocationJob is job-level workflow permission.
permissionLocationJob
permissionLocationJob permissionLocationType = "job"
)
// permissionType represents a permission type.
type permissionType int
type permissionType string
const (
// permissionTypeNone represents none permission type.
permissionTypeNone permissionType = iota
permissionTypeNone permissionType = "none"
// permissionTypeNone is the "all" github permission type.
permissionTypeAll
permissionTypeAll permissionType = "all"
// permissionTypeNone is the "statuses" github permission type.
permissionTypeStatuses
permissionTypeStatuses permissionType = "statuses"
// permissionTypeNone is the "checks" github permission type.
permissionTypeChecks
permissionTypeChecks permissionType = "checks"
// permissionTypeNone is the "security-events" github permission type.
permissionTypeSecurityEvents
permissionTypeSecurityEvents permissionType = "security-events"
// permissionTypeNone is the "deployments" github permission type.
permissionTypeDeployments
permissionTypeDeployments permissionType = "deployments"
// permissionTypeNone is the "packages" github permission type.
permissionTypePackages
permissionTypePackages permissionType = "packages"
// permissionTypeNone is the "actions" github permission type.
permissionTypeActions
permissionTypeActions permissionType = "actions"
)
// TokenPermissions applies the score policy for the Token-Permissions check.
@ -152,19 +152,13 @@ func rawToFindings(results *checker.TokenPermissionsData) ([]finding.Finding, er
switch r.Type {
case checker.PermissionLevelNone:
f = f.WithOutcome(finding.OutcomePositive)
f = f.WithValues(map[string]int{
"PermissionLevel": int(permissionLevelNone),
})
f = f.WithValue("PermissionLevel", string(permissionLevelNone))
case checker.PermissionLevelRead:
f = f.WithOutcome(finding.OutcomePositive)
f = f.WithValues(map[string]int{
"PermissionLevel": int(permissionLevelRead),
})
f = f.WithValue("PermissionLevel", string(permissionLevelRead))
case checker.PermissionLevelUnknown:
f = f.WithValues(map[string]int{
"PermissionLevel": int(permissionLevelUnknown),
}).WithOutcome(finding.OutcomeError)
f = f.WithValue("PermissionLevel", string(permissionLevelUnknown))
f = f.WithOutcome(finding.OutcomeError)
case checker.PermissionLevelUndeclared:
var locationType permissionLocationType
//nolint:gocritic
@ -176,10 +170,10 @@ func rawToFindings(results *checker.TokenPermissionsData) ([]finding.Finding, er
locationType = permissionLocationNotDeclared
}
permType := permTypeToEnum(r.Name)
f = f.WithValues(map[string]int{
"PermissionLevel": int(permissionLevelUndeclared),
"LocationType": int(locationType),
"PermissionType": int(permType),
f = f.WithValues(map[string]string{
"PermissionLevel": string(permissionLevelUndeclared),
"LocationType": string(locationType),
"PermissionType": string(permType),
})
case checker.PermissionLevelWrite:
var locationType permissionLocationType
@ -192,10 +186,10 @@ func rawToFindings(results *checker.TokenPermissionsData) ([]finding.Finding, er
locationType = permissionLocationNotDeclared
}
permType := permTypeToEnum(r.Name)
f = f.WithValues(map[string]int{
"PermissionLevel": int(permissionLevelWrite),
"LocationType": int(locationType),
"PermissionType": int(permType),
f = f.WithValues(map[string]string{
"PermissionLevel": string(permissionLevelWrite),
"LocationType": string(locationType),
"PermissionType": string(permType),
})
f = f.WithOutcome(finding.OutcomeNegative)
}
@ -229,7 +223,7 @@ func permTypeToEnum(tokenName *string) permissionType {
}
}
func permTypeToName(permType int) *string {
func permTypeToName(permType string) *string {
var permName string
switch permissionType(permType) {
case permissionTypeAll:
@ -401,7 +395,7 @@ func warnWithRemediation(logger checker.DetailLogger,
}
func recordPermissionWrite(hm map[string]permissions, path string,
locType permissionLocationType, permType int,
locType permissionLocationType, permType string,
) {
if _, exists := hm[path]; !exists {
hm[path] = permissions{

View File

@ -54,29 +54,6 @@ const (
depTypeKey = "dependencyType"
)
var (
dependencyTypes = map[checker.DependencyUseType]int{
checker.DependencyUseTypeGHAction: 0,
checker.DependencyUseTypeDockerfileContainerImage: 1,
checker.DependencyUseTypeDownloadThenRun: 2,
checker.DependencyUseTypeGoCommand: 3,
checker.DependencyUseTypeChocoCommand: 4,
checker.DependencyUseTypeNpmCommand: 5,
checker.DependencyUseTypePipCommand: 6,
checker.DependencyUseTypeNugetCommand: 7,
}
intToDepType = map[int]checker.DependencyUseType{
0: checker.DependencyUseTypeGHAction,
1: checker.DependencyUseTypeDockerfileContainerImage,
2: checker.DependencyUseTypeDownloadThenRun,
3: checker.DependencyUseTypeGoCommand,
4: checker.DependencyUseTypeChocoCommand,
5: checker.DependencyUseTypeNpmCommand,
6: checker.DependencyUseTypePipCommand,
7: checker.DependencyUseTypeNugetCommand,
}
)
func ruleRemToProbeRem(rem *rule.Remediation) *probe.Remediation {
return &probe.Remediation{
Patch: rem.Patch,
@ -174,9 +151,7 @@ func dependenciesToFindings(r *checker.PinningDependenciesData) ([]finding.Findi
if rr.Remediation != nil {
f.Remediation = ruleRemToProbeRem(rr.Remediation)
}
f = f.WithValues(map[string]int{
depTypeKey: dependencyTypes[rr.Type],
})
f = f.WithValue(depTypeKey, string(rr.Type))
findings = append(findings, *f)
} else {
loc := &finding.Location{
@ -191,9 +166,7 @@ func dependenciesToFindings(r *checker.PinningDependenciesData) ([]finding.Findi
Outcome: finding.OutcomePositive,
Location: loc,
}
f = f.WithValues(map[string]int{
depTypeKey: dependencyTypes[rr.Type],
})
f = f.WithValue(depTypeKey, string(rr.Type))
findings = append(findings, *f)
}
}
@ -259,7 +232,7 @@ func PinningDependencies(name string, c *checker.CheckRequest,
default:
// ignore
}
updatePinningResults(intToDepType[f.Values[depTypeKey]],
updatePinningResults(checker.DependencyUseType(f.Values[depTypeKey]),
f.Outcome, f.Location.Snippet,
&wp, pr)
}

View File

@ -15,6 +15,9 @@
package evaluation
import (
"fmt"
"strconv"
"github.com/ossf/scorecard/v4/checker"
sce "github.com/ossf/scorecard/v4/errors"
"github.com/ossf/scorecard/v4/finding"
@ -46,12 +49,16 @@ func SAST(name string,
}
var sastScore, codeQlScore, pysaScore, qodanaScore, snykScore, sonarScore int
var err error
// Assign sastScore, codeQlScore and sonarScore
for i := range findings {
f := &findings[i]
switch f.Probe {
case sastToolRunsOnAllCommits.Probe:
sastScore = getSASTScore(f, dl)
sastScore, err = getSASTScore(f, dl)
if err != nil {
return checker.CreateRuntimeErrorResult(name, sce.WithMessage(sce.ErrScorecardInternal, err.Error()))
}
case sastToolCodeQLInstalled.Probe:
codeQlScore = getSastToolScore(f, dl)
case sastToolSnykInstalled.Probe:
@ -147,13 +154,13 @@ func SAST(name string,
// getSASTScore returns the proportional score of how many commits
// run SAST tools.
func getSASTScore(f *finding.Finding, dl checker.DetailLogger) int {
func getSASTScore(f *finding.Finding, dl checker.DetailLogger) (int, error) {
switch f.Outcome {
case finding.OutcomeNotApplicable:
dl.Warn(&checker.LogMessage{
Text: f.Message,
})
return checker.InconclusiveResultScore
return checker.InconclusiveResultScore, nil
case finding.OutcomePositive:
dl.Info(&checker.LogMessage{
Text: f.Message,
@ -164,9 +171,15 @@ func getSASTScore(f *finding.Finding, dl checker.DetailLogger) int {
})
default:
}
analyzed := f.Values[sastToolRunsOnAllCommits.AnalyzedPRsKey]
total := f.Values[sastToolRunsOnAllCommits.TotalPRsKey]
return checker.CreateProportionalScore(analyzed, total)
analyzed, err := strconv.Atoi(f.Values[sastToolRunsOnAllCommits.AnalyzedPRsKey])
if err != nil {
return 0, fmt.Errorf("parsing analyzed PR count: %w", err)
}
total, err := strconv.Atoi(f.Values[sastToolRunsOnAllCommits.TotalPRsKey])
if err != nil {
return 0, fmt.Errorf("parsing total PR count: %w", err)
}
return checker.CreateProportionalScore(analyzed, total), nil
}
// getSastToolScore returns positive if the project runs the Sast tool

View File

@ -76,9 +76,9 @@ func TestSAST(t *testing.T) {
{
Probe: sastToolRunsOnAllCommits.Probe,
Outcome: finding.OutcomePositive,
Values: map[string]int{
sastToolRunsOnAllCommits.AnalyzedPRsKey: 1,
sastToolRunsOnAllCommits.TotalPRsKey: 2,
Values: map[string]string{
sastToolRunsOnAllCommits.AnalyzedPRsKey: "1",
sastToolRunsOnAllCommits.TotalPRsKey: "2",
},
},
{
@ -121,9 +121,9 @@ func TestSAST(t *testing.T) {
{
Probe: sastToolRunsOnAllCommits.Probe,
Outcome: finding.OutcomePositive,
Values: map[string]int{
sastToolRunsOnAllCommits.AnalyzedPRsKey: 1,
sastToolRunsOnAllCommits.TotalPRsKey: 2,
Values: map[string]string{
sastToolRunsOnAllCommits.AnalyzedPRsKey: "1",
sastToolRunsOnAllCommits.TotalPRsKey: "2",
},
},
{
@ -202,9 +202,9 @@ func TestSAST(t *testing.T) {
{
Probe: sastToolRunsOnAllCommits.Probe,
Outcome: finding.OutcomeNegative,
Values: map[string]int{
sastToolRunsOnAllCommits.AnalyzedPRsKey: 1,
sastToolRunsOnAllCommits.TotalPRsKey: 3,
Values: map[string]string{
sastToolRunsOnAllCommits.AnalyzedPRsKey: "1",
sastToolRunsOnAllCommits.TotalPRsKey: "3",
},
},
{
@ -232,9 +232,9 @@ func TestSAST(t *testing.T) {
{
Probe: sastToolRunsOnAllCommits.Probe,
Outcome: finding.OutcomePositive,
Values: map[string]int{
sastToolRunsOnAllCommits.AnalyzedPRsKey: 1,
sastToolRunsOnAllCommits.TotalPRsKey: 3,
Values: map[string]string{
sastToolRunsOnAllCommits.AnalyzedPRsKey: "1",
sastToolRunsOnAllCommits.TotalPRsKey: "3",
},
},
{
@ -270,9 +270,9 @@ func TestSAST(t *testing.T) {
{
Probe: sastToolRunsOnAllCommits.Probe,
Outcome: finding.OutcomePositive,
Values: map[string]int{
sastToolRunsOnAllCommits.AnalyzedPRsKey: 1,
sastToolRunsOnAllCommits.TotalPRsKey: 3,
Values: map[string]string{
sastToolRunsOnAllCommits.AnalyzedPRsKey: "1",
sastToolRunsOnAllCommits.TotalPRsKey: "3",
},
},
{

View File

@ -130,20 +130,15 @@ func SignedReleases(name string,
}
func getReleaseName(f *finding.Finding) string {
m := f.Values
for k, v := range m {
var value int
switch f.Probe {
case releasesAreSigned.Probe:
value = int(releasesAreSigned.ValueTypeRelease)
case releasesHaveProvenance.Probe:
value = int(releasesHaveProvenance.ValueTypeRelease)
}
if v == value {
return k
}
var key string
// these keys should be the same, but might as handle situations when they're not
switch f.Probe {
case releasesAreSigned.Probe:
key = releasesAreSigned.ReleaseNameKey
case releasesHaveProvenance.Probe:
key = releasesHaveProvenance.ReleaseNameKey
}
return ""
return f.Values[key]
}
func contains(releases []string, release string) bool {

View File

@ -46,9 +46,9 @@ func signedProbe(release, asset int, outcome finding.Outcome) finding.Finding {
return finding.Finding{
Probe: releasesAreSigned.Probe,
Outcome: outcome,
Values: map[string]int{
fmt.Sprintf("v%d", release): int(releasesAreSigned.ValueTypeRelease),
fmt.Sprintf("artifact-%d", asset): int(releasesAreSigned.ValueTypeReleaseAsset),
Values: map[string]string{
releasesAreSigned.ReleaseNameKey: fmt.Sprintf("v%d", release),
releasesAreSigned.AssetNameKey: fmt.Sprintf("artifact-%d", asset),
},
}
}
@ -57,9 +57,9 @@ func provenanceProbe(release, asset int, outcome finding.Outcome) finding.Findin
return finding.Finding{
Probe: releasesHaveProvenance.Probe,
Outcome: outcome,
Values: map[string]int{
fmt.Sprintf("v%d", release): int(releasesHaveProvenance.ValueTypeRelease),
fmt.Sprintf("artifact-%d", asset): int(releasesHaveProvenance.ValueTypeReleaseAsset),
Values: map[string]string{
releasesHaveProvenance.ReleaseNameKey: fmt.Sprintf("v%d", release),
releasesHaveProvenance.AssetNameKey: fmt.Sprintf("artifact-%d", asset),
},
}
}
@ -322,7 +322,7 @@ func Test_getReleaseName(t *testing.T) {
name: "no release",
args: args{
f: &finding.Finding{
Values: map[string]int{},
Values: map[string]string{},
},
},
want: "",
@ -331,8 +331,8 @@ func Test_getReleaseName(t *testing.T) {
name: "release",
args: args{
f: &finding.Finding{
Values: map[string]int{
"v1": int(releasesAreSigned.ValueTypeRelease),
Values: map[string]string{
releasesAreSigned.ReleaseNameKey: "v1",
},
Probe: releasesAreSigned.Probe,
},
@ -343,9 +343,9 @@ func Test_getReleaseName(t *testing.T) {
name: "release and asset",
args: args{
f: &finding.Finding{
Values: map[string]int{
"v1": int(releasesAreSigned.ValueTypeRelease),
"artifact-1": int(releasesAreSigned.ValueTypeReleaseAsset),
Values: map[string]string{
releasesAreSigned.ReleaseNameKey: "v1",
releasesAreSigned.AssetNameKey: "artifact-1",
},
Probe: releasesAreSigned.Probe,
},

View File

@ -97,7 +97,7 @@ const (
type Finding struct {
Location *Location `json:"location,omitempty"`
Remediation *probe.Remediation `json:"remediation,omitempty"`
Values map[string]int `json:"values,omitempty"`
Values map[string]string `json:"values,omitempty"`
Probe string `json:"probe"`
Message string `json:"message"`
Outcome Outcome `json:"outcome"`
@ -221,7 +221,7 @@ func (f *Finding) WithLocation(loc *Location) *Finding {
// WithValues sets the values to an existing finding.
// No copy is made.
func (f *Finding) WithValues(values map[string]int) *Finding {
func (f *Finding) WithValues(values map[string]string) *Finding {
f.Values = values
return f
}
@ -266,9 +266,9 @@ func (f *Finding) WithRemediationMetadata(values map[string]string) *Finding {
// WithValue adds a value to f.Values.
// No copy is made.
func (f *Finding) WithValue(k string, v int) *Finding {
func (f *Finding) WithValue(k, v string) *Finding {
if f.Values == nil {
f.Values = make(map[string]int)
f.Values = make(map[string]string)
}
f.Values[k] = v
return f

View File

@ -27,7 +27,10 @@ import (
//go:embed *.yml
var fs embed.FS
const Probe = "blocksDeleteOnBranches"
const (
Probe = "blocksDeleteOnBranches"
BranchNameKey = "branchName"
)
func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
if raw == nil {
@ -58,9 +61,7 @@ func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
if err != nil {
return nil, Probe, fmt.Errorf("create finding: %w", err)
}
f = f.WithValues(map[string]int{
*branch.Name: 1,
})
f = f.WithValue(BranchNameKey, *branch.Name)
findings = append(findings, *f)
}
return findings, Probe, nil

View File

@ -27,7 +27,10 @@ import (
//go:embed *.yml
var fs embed.FS
const Probe = "blocksForcePushOnBranches"
const (
Probe = "blocksForcePushOnBranches"
BranchNameKey = "branchName"
)
func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
if raw == nil {
@ -57,9 +60,7 @@ func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
if err != nil {
return nil, Probe, fmt.Errorf("create finding: %w", err)
}
f = f.WithValues(map[string]int{
*branch.Name: 1,
})
f = f.WithValue(BranchNameKey, *branch.Name)
findings = append(findings, *f)
}
return findings, Probe, nil

View File

@ -28,7 +28,10 @@ import (
//go:embed *.yml
var fs embed.FS
const Probe = "branchProtectionAppliesToAdmins"
const (
Probe = "branchProtectionAppliesToAdmins"
BranchNameKey = "branchName"
)
func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
if raw == nil {
@ -52,9 +55,7 @@ func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
if err != nil {
return nil, Probe, fmt.Errorf("create finding: %w", err)
}
f = f.WithValues(map[string]int{
*branch.Name: 1,
})
f = f.WithValue(BranchNameKey, *branch.Name)
findings = append(findings, *f)
}
return findings, Probe, nil

View File

@ -28,7 +28,10 @@ import (
//go:embed *.yml
var fs embed.FS
const Probe = "dismissesStaleReviews"
const (
Probe = "dismissesStaleReviews"
BranchNameKey = "branchName"
)
func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
if raw == nil {
@ -52,9 +55,7 @@ func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
if err != nil {
return nil, Probe, fmt.Errorf("create finding: %w", err)
}
f = f.WithValues(map[string]int{
*branch.Name: 1,
})
f = f.WithValue(BranchNameKey, *branch.Name)
findings = append(findings, *f)
}
return findings, Probe, nil

View File

@ -30,6 +30,7 @@ var fs embed.FS
const (
Probe = "hasOpenSSFBadge"
LevelKey = "badgeLevel"
GoldLevel = "Gold"
SilverLevel = "Silver"
PassingLevel = "Passing"
@ -73,8 +74,6 @@ func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
return nil, Probe, fmt.Errorf("create finding: %w", err)
}
f = f.WithValues(map[string]int{
badgeLevel: 1,
})
f = f.WithValue(LevelKey, badgeLevel)
return []finding.Finding{*f}, Probe, nil
}

View File

@ -18,6 +18,7 @@ package hasRecentCommits
import (
"embed"
"fmt"
"strconv"
"time"
"github.com/ossf/scorecard/v4/checker"
@ -29,13 +30,12 @@ import (
var fs embed.FS
const (
lookBackDays = 90
CommitsValue = "commitsWithinThreshold"
LookBackValue = "lookBackDays"
Probe = "hasRecentCommits"
NumCommitsKey = "commitsWithinThreshold"
LookbackDayKey = "lookBackDays"
lookBackDays = 90
)
const Probe = "hasRecentCommits"
func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
if raw == nil {
return nil, "", fmt.Errorf("%w: raw", uerror.ErrNil)
@ -54,27 +54,24 @@ func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
}
}
var text string
var outcome finding.Outcome
if commitsWithinThreshold > 0 {
f, err := finding.NewWith(fs, Probe,
"Found a contribution within the threshold.", nil,
finding.OutcomePositive)
if err != nil {
return nil, Probe, fmt.Errorf("create finding: %w", err)
}
f = f.WithValues(map[string]int{
CommitsValue: commitsWithinThreshold,
LookBackValue: lookBackDays,
})
findings = append(findings, *f)
text = "Found a contribution within the threshold."
outcome = finding.OutcomePositive
} else {
f, err := finding.NewWith(fs, Probe,
"Did not find contribution within the threshold.", nil,
finding.OutcomeNegative)
if err != nil {
return nil, Probe, fmt.Errorf("create finding: %w", err)
}
findings = append(findings, *f)
text = "Did not find contribution within the threshold."
outcome = finding.OutcomeNegative
}
f, err := finding.NewWith(fs, Probe, text, nil, outcome)
if err != nil {
return nil, Probe, fmt.Errorf("create finding: %w", err)
}
f = f.WithValues(map[string]string{
NumCommitsKey: strconv.Itoa(commitsWithinThreshold),
LookbackDayKey: strconv.Itoa(lookBackDays),
})
findings = append(findings, *f)
return findings, Probe, nil
}

View File

@ -16,6 +16,7 @@
package hasRecentCommits
import (
"strconv"
"testing"
"time"
@ -56,7 +57,7 @@ func Test_Run(t *testing.T) {
name string
raw *checker.RawResults
outcomes []finding.Outcome
values map[string]int
values map[string]string
err error
}{
{
@ -75,9 +76,9 @@ func Test_Run(t *testing.T) {
DefaultBranchCommits: fiveCommitsInThreshold(),
},
},
values: map[string]int{
"commitsWithinThreshold": 5,
"lookBackDays": 90,
values: map[string]string{
NumCommitsKey: "5",
LookbackDayKey: strconv.Itoa(lookBackDays),
},
outcomes: []finding.Outcome{finding.OutcomePositive},
},
@ -88,9 +89,9 @@ func Test_Run(t *testing.T) {
DefaultBranchCommits: twentyCommitsInThresholdAndTwentyNot(),
},
},
values: map[string]int{
"commitsWithinThreshold": 20,
"lookBackDays": 90,
values: map[string]string{
NumCommitsKey: "20",
LookbackDayKey: strconv.Itoa(lookBackDays),
},
outcomes: []finding.Outcome{finding.OutcomePositive},
},

View File

@ -18,6 +18,7 @@ package issueActivityByProjectMember
import (
"embed"
"fmt"
"strconv"
"time"
"github.com/ossf/scorecard/v4/checker"
@ -30,12 +31,12 @@ import (
var fs embed.FS
const (
lookBackDays = 90
NoOfIssuesValue = "numberOfIssuesUpdatedWithinThreshold"
Probe = "issueActivityByProjectMember"
NumIssuesKey = "numberOfIssuesUpdatedWithinThreshold"
LookbackDayKey = "lookBackDays"
lookBackDays = 90
)
const Probe = "issueActivityByProjectMember"
func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
if raw == nil {
return nil, "", fmt.Errorf("%w: raw", uerror.ErrNil)
@ -53,27 +54,26 @@ func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
}
}
var text string
var outcome finding.Outcome
if numberOfIssuesUpdatedWithinThreshold > 0 {
f, err := finding.NewWith(fs, Probe,
"Found a issue within the threshold.", nil,
finding.OutcomePositive)
if err != nil {
return nil, Probe, fmt.Errorf("create finding: %w", err)
}
f = f.WithValues(map[string]int{
NoOfIssuesValue: numberOfIssuesUpdatedWithinThreshold,
})
findings = append(findings, *f)
text = "Found a issue within the threshold."
outcome = finding.OutcomePositive
} else {
f, err := finding.NewWith(fs, Probe,
"Did not find issues within the threshold.", nil,
finding.OutcomeNegative)
if err != nil {
return nil, Probe, fmt.Errorf("create finding: %w", err)
}
findings = append(findings, *f)
text = "Did not find issues within the threshold."
outcome = finding.OutcomeNegative
}
f, err := finding.NewWith(fs, Probe, text, nil, outcome)
if err != nil {
return nil, Probe, fmt.Errorf("create finding: %w", err)
}
f = f.WithValues(map[string]string{
NumIssuesKey: strconv.Itoa(numberOfIssuesUpdatedWithinThreshold),
LookbackDayKey: strconv.Itoa(lookBackDays),
})
findings = append(findings, *f)
return findings, Probe, nil
}

View File

@ -16,6 +16,7 @@
package issueActivityByProjectMember
import (
"strconv"
"testing"
"time"
@ -80,7 +81,7 @@ func Test_Run(t *testing.T) {
//nolint:govet
tests := []struct {
name string
values map[string]int
values map[string]string
raw *checker.RawResults
outcomes []finding.Outcome
err error
@ -101,8 +102,9 @@ func Test_Run(t *testing.T) {
Issues: fiveIssuesInThreshold(),
},
},
values: map[string]int{
"numberOfIssuesUpdatedWithinThreshold": 5,
values: map[string]string{
LookbackDayKey: strconv.Itoa(lookBackDays),
NumIssuesKey: "5",
},
outcomes: []finding.Outcome{finding.OutcomePositive},
},
@ -113,8 +115,9 @@ func Test_Run(t *testing.T) {
Issues: twentyIssuesInThresholdAndTwentyNot(),
},
},
values: map[string]int{
"numberOfIssuesUpdatedWithinThreshold": 20,
values: map[string]string{
LookbackDayKey: strconv.Itoa(lookBackDays),
NumIssuesKey: "20",
},
outcomes: []finding.Outcome{finding.OutcomePositive},
},
@ -125,8 +128,9 @@ func Test_Run(t *testing.T) {
Issues: fiveInThresholdByCollabAndFiveByFirstTimeUser(),
},
},
values: map[string]int{
"numberOfIssuesUpdatedWithinThreshold": 5,
values: map[string]string{
LookbackDayKey: strconv.Itoa(lookBackDays),
NumIssuesKey: "5",
},
outcomes: []finding.Outcome{finding.OutcomePositive},
},

View File

@ -18,6 +18,7 @@ package notCreatedRecently
import (
"embed"
"fmt"
"strconv"
"time"
"github.com/ossf/scorecard/v4/checker"
@ -29,10 +30,11 @@ import (
var fs embed.FS
const (
lookBackDays = 90
)
Probe = "notCreatedRecently"
const Probe = "notCreatedRecently"
LookbackDayKey = "lookBackDays"
lookBackDays = 90
)
func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
if raw == nil {
@ -43,31 +45,19 @@ func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
recencyThreshold := time.Now().AddDate(0 /*years*/, 0 /*months*/, -1*lookBackDays /*days*/)
var text string
var outcome finding.Outcome
if r.CreatedAt.After(recencyThreshold) {
return negativeOutcome()
text = fmt.Sprintf("Repository was created in last %d days.", lookBackDays)
outcome = finding.OutcomeNegative
} else {
text = fmt.Sprintf("Repository was not created in last %d days.", lookBackDays)
outcome = finding.OutcomePositive
}
return positiveOutcome()
}
func negativeOutcome() ([]finding.Finding, string, error) {
f, err := finding.NewWith(fs, Probe,
"Repository was created in last 90 days.", nil,
finding.OutcomeNegative)
f, err := finding.NewWith(fs, Probe, text, nil, outcome)
if err != nil {
return nil, Probe, fmt.Errorf("create finding: %w", err)
}
return []finding.Finding{*f}, Probe, nil
}
func positiveOutcome() ([]finding.Finding, string, error) {
f, err := finding.NewWith(fs, Probe,
"Repository was not created in last 90 days.", nil,
finding.OutcomePositive)
if err != nil {
return nil, Probe, fmt.Errorf("create finding: %w", err)
}
f = f.WithValues(map[string]int{
"lookBackDays": 90,
})
f = f.WithValue(LookbackDayKey, strconv.Itoa(lookBackDays))
return []finding.Finding{*f}, Probe, nil
}

View File

@ -30,19 +30,11 @@ var fs embed.FS
const (
Probe = "releasesAreSigned"
ReleaseNameKey = "releaseName"
AssetNameKey = "assetName"
releaseLookBack = 5
)
// ValueType is the type of a value in the finding values.
type ValueType int
const (
// ValueTypeRelease represents a release name.
ValueTypeRelease ValueType = iota
// ValueTypeReleaseAsset represents a release asset name.
ValueTypeReleaseAsset
)
var signatureExtensions = []string{".asc", ".minisig", ".sig", ".sign", ".sigstore"}
func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
@ -85,9 +77,9 @@ func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
if err != nil {
return nil, Probe, fmt.Errorf("create finding: %w", err)
}
f.Values = map[string]int{
release.TagName: int(ValueTypeRelease),
asset.Name: int(ValueTypeReleaseAsset),
f.Values = map[string]string{
ReleaseNameKey: release.TagName,
AssetNameKey: asset.Name,
}
findings = append(findings, *f)
signed = true
@ -113,9 +105,7 @@ func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
if err != nil {
return nil, Probe, fmt.Errorf("create finding: %w", err)
}
f.Values = map[string]int{
release.TagName: int(ValueTypeRelease),
}
f = f.WithValue(ReleaseNameKey, release.TagName)
findings = append(findings, *f)
}

View File

@ -30,19 +30,11 @@ var fs embed.FS
const (
Probe = "releasesHaveProvenance"
ReleaseNameKey = "releaseName"
AssetNameKey = "assetName"
releaseLookBack = 5
)
// ValueType is the type of a value in the finding values.
type ValueType int
const (
// ValueTypeRelease represents a release name.
ValueTypeRelease ValueType = iota
// ValueTypeReleaseAsset represents a release asset name.
ValueTypeReleaseAsset
)
var provenanceExtensions = []string{".intoto.jsonl"}
//nolint:gocognit // bug hotfix
@ -86,9 +78,9 @@ func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
if err != nil {
return nil, Probe, fmt.Errorf("create finding: %w", err)
}
f.Values = map[string]int{
release.TagName: int(ValueTypeRelease),
asset.Name: int(ValueTypeReleaseAsset),
f.Values = map[string]string{
ReleaseNameKey: release.TagName,
AssetNameKey: asset.Name,
}
findings = append(findings, *f)
hasProvenance = true
@ -114,9 +106,7 @@ func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
if err != nil {
return nil, Probe, fmt.Errorf("create finding: %w", err)
}
f.Values = map[string]int{
release.TagName: int(ValueTypeRelease),
}
f = f.WithValue(ReleaseNameKey, release.TagName)
findings = append(findings, *f)
if totalReleases >= releaseLookBack {

View File

@ -19,6 +19,7 @@ import (
"embed"
"errors"
"fmt"
"strconv"
"github.com/ossf/scorecard/v4/checker"
"github.com/ossf/scorecard/v4/finding"
@ -28,7 +29,11 @@ import (
//go:embed *.yml
var fs embed.FS
const Probe = "requiresApproversForPullRequests"
const (
Probe = "requiresApproversForPullRequests"
BranchNameKey = "branchName"
RequiredReviewersKey = "numberOfRequiredReviewers"
)
var errWrongValue = errors.New("wrong value, should not happen")
@ -52,25 +57,16 @@ func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
if err != nil {
return nil, Probe, fmt.Errorf("create finding: %w", err)
}
f = f.WithValue(BranchNameKey, *branch.Name)
switch {
case p == nil:
f = f.WithMessage(nilMsg).WithOutcome(finding.OutcomeNotAvailable)
f = f.WithValues(map[string]int{
*branch.Name: 1,
})
case *p > 0:
f = f.WithMessage(trueMsg).WithOutcome(finding.OutcomePositive)
f = f.WithValues(map[string]int{
*branch.Name: 1,
"numberOfRequiredReviewers": int(*p),
})
f = f.WithValue(RequiredReviewersKey, strconv.Itoa(int(*p)))
case *p == 0:
f = f.WithMessage(falseMsg).WithOutcome(finding.OutcomeNegative)
f = f.WithValues(map[string]int{
*branch.Name: 1,
"numberOfRequiredReviewers": int(*p),
})
f = f.WithValue(RequiredReviewersKey, strconv.Itoa(int(*p)))
default:
return nil, Probe, fmt.Errorf("create finding: %w", errWrongValue)
}

View File

@ -27,7 +27,10 @@ import (
//go:embed *.yml
var fs embed.FS
const Probe = "requiresCodeOwnersReview"
const (
Probe = "requiresCodeOwnersReview"
BranchNameKey = "branchName"
)
func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
if raw == nil {
@ -61,9 +64,7 @@ func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
if err != nil {
return nil, Probe, fmt.Errorf("create finding: %w", err)
}
f = f.WithValues(map[string]int{
*branch.Name: 1,
})
f = f.WithValue(BranchNameKey, *branch.Name)
findings = append(findings, *f)
}
return findings, Probe, nil

View File

@ -28,7 +28,10 @@ import (
//go:embed *.yml
var fs embed.FS
const Probe = "requiresLastPushApproval"
const (
Probe = "requiresLastPushApproval"
BranchNameKey = "branchName"
)
func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
if raw == nil {
@ -50,9 +53,7 @@ func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
if err != nil {
return nil, Probe, fmt.Errorf("create finding: %w", err)
}
f = f.WithValues(map[string]int{
*branch.Name: 1,
})
f = f.WithValue(BranchNameKey, *branch.Name)
findings = append(findings, *f)
}
return findings, Probe, nil

View File

@ -28,7 +28,10 @@ import (
//go:embed *.yml
var fs embed.FS
const Probe = "requiresUpToDateBranches"
const (
Probe = "requiresUpToDateBranches"
BranchNameKey = "branchName"
)
func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
if raw == nil {
@ -52,9 +55,7 @@ func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
if err != nil {
return nil, Probe, fmt.Errorf("create finding: %w", err)
}
f = f.WithValues(map[string]int{
*branch.Name: 1,
})
f = f.WithValue(BranchNameKey, *branch.Name)
findings = append(findings, *f)
}
return findings, Probe, nil

View File

@ -27,7 +27,10 @@ import (
//go:embed *.yml
var fs embed.FS
const Probe = "runsStatusChecksBeforeMerging"
const (
Probe = "runsStatusChecksBeforeMerging"
BranchNameKey = "branchName"
)
func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
if raw == nil {
@ -47,9 +50,7 @@ func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
if err != nil {
return nil, Probe, fmt.Errorf("create finding: %w", err)
}
f = f.WithValues(map[string]int{
*branch.Name: 1,
})
f = f.WithValue(BranchNameKey, *branch.Name)
findings = append(findings, *f)
default:
f, err := finding.NewWith(fs, Probe,
@ -58,9 +59,7 @@ func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
if err != nil {
return nil, Probe, fmt.Errorf("create finding: %w", err)
}
f = f.WithValues(map[string]int{
*branch.Name: 1,
})
f = f.WithValue(BranchNameKey, *branch.Name)
findings = append(findings, *f)
}
}

View File

@ -18,6 +18,7 @@ package sastToolRunsOnAllCommits
import (
"embed"
"fmt"
"strconv"
"github.com/ossf/scorecard/v4/checker"
"github.com/ossf/scorecard/v4/finding"
@ -65,8 +66,8 @@ func Run(raw *checker.RawResults) ([]finding.Finding, string, error) {
return []finding.Finding{*f}, Probe, nil
}
f = f.WithValue(AnalyzedPRsKey, totalPullRequestsAnalyzed)
f = f.WithValue(TotalPRsKey, totalPullRequestsMerged)
f = f.WithValue(AnalyzedPRsKey, strconv.Itoa(totalPullRequestsAnalyzed))
f = f.WithValue(TotalPRsKey, strconv.Itoa(totalPullRequestsMerged))
if totalPullRequestsAnalyzed == totalPullRequestsMerged {
msg := fmt.Sprintf("all commits (%v) are checked with a SAST tool", totalPullRequestsMerged)

View File

@ -57,9 +57,9 @@ func Test_Run(t *testing.T) {
{
Probe: Probe,
Message: "1 commits out of 2 are checked with a SAST tool",
Values: map[string]int{
AnalyzedPRsKey: 1,
TotalPRsKey: 2,
Values: map[string]string{
AnalyzedPRsKey: "1",
TotalPRsKey: "2",
},
},
},
@ -87,9 +87,9 @@ func Test_Run(t *testing.T) {
Probe: Probe,
Message: "all commits (2) are checked with a SAST tool",
Outcome: finding.OutcomePositive,
Values: map[string]int{
AnalyzedPRsKey: 2,
TotalPRsKey: 2,
Values: map[string]string{
AnalyzedPRsKey: "2",
TotalPRsKey: "2",
},
},
},