Skip to content

Commit 9295f1a

Browse files
authored
Aggregate code scanning sarifs from command summaries (#2683)
1 parent b0d57de commit 9295f1a

File tree

5 files changed

+76
-23
lines changed

5 files changed

+76
-23
lines changed

general/summary/cli.go

Lines changed: 66 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ const (
2727
)
2828

2929
const (
30-
JfrogCliSummaryDir = "jfrog-command-summary"
31-
MarkdownFileName = "markdown.md"
30+
markdownFileName = "markdown.md"
31+
finalSarifFileName = "final.sarif"
3232
)
3333

3434
var markdownSections = []MarkdownSection{Security, BuildInfo, Upload}
@@ -37,13 +37,22 @@ func (ms MarkdownSection) String() string {
3737
return string(ms)
3838
}
3939

40-
// GenerateSummaryMarkdown creates a summary of recorded CLI commands in Markdown format.
41-
func GenerateSummaryMarkdown(c *cli.Context) error {
40+
// Generates a combined markdown from all sections, and aggregates multiple SARIF files into one.
41+
func FinalizeCommandSummaries(c *cli.Context) error {
4242
if !shouldGenerateSummary() {
4343
return fmt.Errorf("unable to generate the command summary because the output directory is not specified."+
4444
" Please ensure that the environment variable '%s' is set before running your commands to enable summary generation", coreutils.SummaryOutputDirPathEnv)
4545
}
4646

47+
if err := generateSummaryMarkdown(c); err != nil {
48+
return err
49+
}
50+
51+
return aggregatedCodeScanningSarifs()
52+
}
53+
54+
// generateSummaryMarkdown creates a summary of recorded CLI commands in Markdown format.
55+
func generateSummaryMarkdown(c *cli.Context) error {
4756
// Get URL and Version to generate summary links
4857
serverUrl, majorVersion, err := extractServerUrlAndVersion(c)
4958
if err != nil {
@@ -71,6 +80,26 @@ func GenerateSummaryMarkdown(c *cli.Context) error {
7180
return saveMarkdownToFileSystem(finalMarkdown)
7281
}
7382

83+
func aggregatedCodeScanningSarifs() error {
84+
files, err := getSarifFiles()
85+
if err != nil {
86+
return err
87+
}
88+
if len(files) == 0 {
89+
log.Debug("No sarif reports were found")
90+
return nil
91+
}
92+
finalSarif, err := securityUtils.CombineSarifOutputFiles(files)
93+
if err != nil {
94+
return err
95+
}
96+
return saveFinalSarifToFileSystem(string(finalSarif))
97+
}
98+
99+
func getSarifReportsDir() string {
100+
return filepath.Join(os.Getenv(coreutils.SummaryOutputDirPathEnv), commandsummary.OutputDirName, string(Security), string(commandsummary.SarifReport))
101+
}
102+
74103
// The CLI generates summaries in sections, with each section as a separate Markdown file.
75104
// This function merges all sections into a single Markdown file and saves it in the root of the
76105
// command summary output directory.
@@ -93,23 +122,29 @@ func saveMarkdownToFileSystem(finalMarkdown string) (err error) {
93122
if finalMarkdown == "" {
94123
return nil
95124
}
96-
filePath := filepath.Join(os.Getenv(coreutils.SummaryOutputDirPathEnv), JfrogCliSummaryDir, MarkdownFileName)
125+
filePath := filepath.Join(os.Getenv(coreutils.SummaryOutputDirPathEnv), commandsummary.OutputDirName, markdownFileName)
126+
return saveFile(finalMarkdown, filePath)
127+
}
128+
129+
func saveFile(content, filePath string) (err error) {
130+
if content == "" {
131+
return nil
132+
}
97133
file, err := os.Create(filePath)
98134
if err != nil {
99-
return fmt.Errorf("error creating markdown file: %w", err)
135+
return err
100136
}
101137
defer func() {
102138
err = errors.Join(err, file.Close())
103139
}()
104-
// Write to file
105-
if _, err := file.WriteString(finalMarkdown); err != nil {
106-
return fmt.Errorf("error writing to markdown file: %w", err)
140+
if _, err = file.WriteString(content); err != nil {
141+
return err
107142
}
108143
return nil
109144
}
110145

111146
func getSectionMarkdownContent(section MarkdownSection) (string, error) {
112-
sectionFilepath := filepath.Join(os.Getenv(coreutils.SummaryOutputDirPathEnv), JfrogCliSummaryDir, string(section), MarkdownFileName)
147+
sectionFilepath := filepath.Join(os.Getenv(coreutils.SummaryOutputDirPathEnv), commandsummary.OutputDirName, string(section), markdownFileName)
113148
if _, err := os.Stat(sectionFilepath); os.IsNotExist(err) {
114149
return "", nil
115150
}
@@ -124,6 +159,23 @@ func getSectionMarkdownContent(section MarkdownSection) (string, error) {
124159
return string(contentBytes), nil
125160
}
126161

162+
func getSarifFiles() (files []string, err error) {
163+
indexedFiles, err := commandsummary.GetIndexedDataFilesPaths()
164+
if err != nil {
165+
return
166+
}
167+
sarifsMap := indexedFiles[commandsummary.SarifReport]
168+
for i := range sarifsMap {
169+
files = append(files, sarifsMap[i])
170+
}
171+
return
172+
}
173+
174+
func saveFinalSarifToFileSystem(finalSarif string) (err error) {
175+
filePath := filepath.Join(getSarifReportsDir(), finalSarifFileName)
176+
return saveFile(finalSarif, filePath)
177+
}
178+
127179
// Initiate the desired command summary implementation and invoke its Markdown generation.
128180
func invokeSectionMarkdownGeneration(section MarkdownSection) error {
129181
switch section {
@@ -151,7 +203,7 @@ func generateBuildInfoMarkdown() error {
151203
if err != nil {
152204
return fmt.Errorf("error generating build-info markdown: %w", err)
153205
}
154-
if err = mapScanResults(buildInfoSummary); err != nil {
206+
if err = mapScanResults(); err != nil {
155207
return fmt.Errorf("error mapping scan results: %w", err)
156208
}
157209
return buildInfoSummary.GenerateMarkdown()
@@ -170,9 +222,9 @@ func generateUploadMarkdown() error {
170222
}
171223

172224
// mapScanResults maps the scan results saved during runtime into scan components.
173-
func mapScanResults(commandSummary *commandsummary.CommandSummary) (err error) {
225+
func mapScanResults() (err error) {
174226
// Gets the saved scan results file paths.
175-
indexedFiles, err := commandSummary.GetIndexedDataFilesPaths()
227+
indexedFiles, err := commandsummary.GetIndexedDataFilesPaths()
176228
if err != nil {
177229
return err
178230
}
@@ -216,7 +268,7 @@ func processScan(index commandsummary.Index, filePath string, scannedName string
216268

217269
// shouldGenerateUploadSummary checks if upload summary should be generated.
218270
func shouldGenerateUploadSummary() (bool, error) {
219-
buildInfoPath := filepath.Join(os.Getenv(coreutils.SummaryOutputDirPathEnv), JfrogCliSummaryDir, string(BuildInfo))
271+
buildInfoPath := filepath.Join(os.Getenv(coreutils.SummaryOutputDirPathEnv), commandsummary.OutputDirName, string(BuildInfo))
220272
if _, err := os.Stat(buildInfoPath); os.IsNotExist(err) {
221273
return true, nil
222274
}

go.mod

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ require (
1919
github.com/jfrog/build-info-go v1.9.35
2020
github.com/jfrog/gofrog v1.7.5
2121
github.com/jfrog/jfrog-cli-artifactory v0.1.6
22-
github.com/jfrog/jfrog-cli-core/v2 v2.55.6
22+
github.com/jfrog/jfrog-cli-core/v2 v2.55.7
2323
github.com/jfrog/jfrog-cli-platform-services v1.3.0
24-
github.com/jfrog/jfrog-cli-security v1.7.2
24+
github.com/jfrog/jfrog-cli-security v1.8.0
2525
github.com/jfrog/jfrog-client-go v1.46.1
2626
github.com/jszwec/csvutil v1.10.0
2727
github.com/stretchr/testify v1.9.0
@@ -171,9 +171,9 @@ require (
171171
gopkg.in/yaml.v3 v3.0.1 // indirect
172172
)
173173

174-
// replace github.com/jfrog/jfrog-cli-core/v2 => github.com/eyaldelarea/jfrog-cli-core/v2 v2.0.0-20240829171158-7b0f89df2c0c
174+
// replace github.com/jfrog/jfrog-cli-core/v2 => github.com/RobiNino/jfrog-cli-core/v2 v2.0.0-20240904105726-775a1614224e
175175

176-
// replace github.com/jfrog/jfrog-cli-security => github.com/attiasas/jfrog-cli-security v0.0.0-20240829151632-3a7a90969eca
176+
// replace github.com/jfrog/jfrog-cli-security => github.com/attiasas/jfrog-cli-security v0.0.0-20240904061406-f368939ce3a0
177177

178178
// replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20240806162439-01bb7dcd43fc
179179

go.sum

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -941,12 +941,12 @@ github.com/jfrog/jfrog-apps-config v1.0.1 h1:mtv6k7g8A8BVhlHGlSveapqf4mJfonwvXYL
941941
github.com/jfrog/jfrog-apps-config v1.0.1/go.mod h1:8AIIr1oY9JuH5dylz2S6f8Ym2MaadPLR6noCBO4C22w=
942942
github.com/jfrog/jfrog-cli-artifactory v0.1.6 h1:bMfJsrLQJw0dZp4nqUf1xOmtY0rpCatW/I5q88x+fhQ=
943943
github.com/jfrog/jfrog-cli-artifactory v0.1.6/go.mod h1:jbNb22ebtupcjdhrdGq0VBew2vWG6VUK04xxGNDfynE=
944-
github.com/jfrog/jfrog-cli-core/v2 v2.55.6 h1:3tQuEdYgS2q7fkrrSG66OnO0S998FXGaY9BVsxSLst4=
945-
github.com/jfrog/jfrog-cli-core/v2 v2.55.6/go.mod h1:DPO5BfWAeOByahFMMy+PcjmbPlcyoRy7Bf2C5sGKVi0=
944+
github.com/jfrog/jfrog-cli-core/v2 v2.55.7 h1:V4dO2FMNIH49lov3dMj3jYRg8KBTG7hyhHI8ftYByf8=
945+
github.com/jfrog/jfrog-cli-core/v2 v2.55.7/go.mod h1:DPO5BfWAeOByahFMMy+PcjmbPlcyoRy7Bf2C5sGKVi0=
946946
github.com/jfrog/jfrog-cli-platform-services v1.3.0 h1:IblSDZFBjL7WLRi37Ni2DmHrXJJ6ysSMxx7t41AvyDA=
947947
github.com/jfrog/jfrog-cli-platform-services v1.3.0/go.mod h1:Ky4SDXuMeaiNP/5zMT1YSzIuXG+cNYYOl8BaEA7Awbc=
948-
github.com/jfrog/jfrog-cli-security v1.7.2 h1:Kvabj/6LhM+WEb6woIqqbv2VmIj69IFwz859Sys1Tgs=
949-
github.com/jfrog/jfrog-cli-security v1.7.2/go.mod h1:4eztJ+gBb7Xtq/TtnOvIodBOMZutPIAZOuLxqHWXrOo=
948+
github.com/jfrog/jfrog-cli-security v1.8.0 h1:jp/AVaQcItUNXRCud5PMyl8VVjPuzfrNHJWQvWAMnms=
949+
github.com/jfrog/jfrog-cli-security v1.8.0/go.mod h1:DjufYZpsTwILOFJlx7tR/y63oLBRmtPtFIz1WgiP/X4=
950950
github.com/jfrog/jfrog-client-go v1.46.1 h1:ExqOF8ClOG9LO3vbm6jTIwQHHhprbu8lxB2RrM6mMI0=
951951
github.com/jfrog/jfrog-client-go v1.46.1/go.mod h1:UCu2JNBfMp9rypEmCL84DCooG79xWIHVadZQR3Ab+BQ=
952952
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=

main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ func getCommands() ([]cli.Command, error) {
300300
Usage: summaryDocs.GetDescription(),
301301
HelpName: corecommon.CreateUsage("gsm", summaryDocs.GetDescription(), summaryDocs.Usage),
302302
Category: otherCategory,
303-
Action: summary.GenerateSummaryMarkdown,
303+
Action: summary.FinalizeCommandSummaries,
304304
},
305305
}
306306

transfer_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,7 @@ func generateTestRepoSnapshotFile(t *testing.T, repoKey, repoSnapshotFilePath st
369369
func addChildWithFiles(t *testing.T, parent *reposnapshot.Node, dirName string, explored, checkCompleted bool, filesCount int) *reposnapshot.Node {
370370
childNode := reposnapshot.CreateNewNode(dirName, nil)
371371
for i := 0; i < filesCount; i++ {
372+
//#nosec G115
372373
assert.NoError(t, childNode.IncrementFilesCount(uint64(i)))
373374
}
374375

0 commit comments

Comments
 (0)