@@ -27,8 +27,8 @@ const (
27
27
)
28
28
29
29
const (
30
- JfrogCliSummaryDir = "jfrog-command-summary "
31
- MarkdownFileName = "markdown.md "
30
+ markdownFileName = "markdown.md "
31
+ finalSarifFileName = "final.sarif "
32
32
)
33
33
34
34
var markdownSections = []MarkdownSection {Security , BuildInfo , Upload }
@@ -37,13 +37,22 @@ func (ms MarkdownSection) String() string {
37
37
return string (ms )
38
38
}
39
39
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 {
42
42
if ! shouldGenerateSummary () {
43
43
return fmt .Errorf ("unable to generate the command summary because the output directory is not specified." +
44
44
" Please ensure that the environment variable '%s' is set before running your commands to enable summary generation" , coreutils .SummaryOutputDirPathEnv )
45
45
}
46
46
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 {
47
56
// Get URL and Version to generate summary links
48
57
serverUrl , majorVersion , err := extractServerUrlAndVersion (c )
49
58
if err != nil {
@@ -71,6 +80,26 @@ func GenerateSummaryMarkdown(c *cli.Context) error {
71
80
return saveMarkdownToFileSystem (finalMarkdown )
72
81
}
73
82
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
+
74
103
// The CLI generates summaries in sections, with each section as a separate Markdown file.
75
104
// This function merges all sections into a single Markdown file and saves it in the root of the
76
105
// command summary output directory.
@@ -93,23 +122,29 @@ func saveMarkdownToFileSystem(finalMarkdown string) (err error) {
93
122
if finalMarkdown == "" {
94
123
return nil
95
124
}
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
+ }
97
133
file , err := os .Create (filePath )
98
134
if err != nil {
99
- return fmt . Errorf ( "error creating markdown file: %w" , err )
135
+ return err
100
136
}
101
137
defer func () {
102
138
err = errors .Join (err , file .Close ())
103
139
}()
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
107
142
}
108
143
return nil
109
144
}
110
145
111
146
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 )
113
148
if _ , err := os .Stat (sectionFilepath ); os .IsNotExist (err ) {
114
149
return "" , nil
115
150
}
@@ -124,6 +159,23 @@ func getSectionMarkdownContent(section MarkdownSection) (string, error) {
124
159
return string (contentBytes ), nil
125
160
}
126
161
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
+
127
179
// Initiate the desired command summary implementation and invoke its Markdown generation.
128
180
func invokeSectionMarkdownGeneration (section MarkdownSection ) error {
129
181
switch section {
@@ -151,7 +203,7 @@ func generateBuildInfoMarkdown() error {
151
203
if err != nil {
152
204
return fmt .Errorf ("error generating build-info markdown: %w" , err )
153
205
}
154
- if err = mapScanResults (buildInfoSummary ); err != nil {
206
+ if err = mapScanResults (); err != nil {
155
207
return fmt .Errorf ("error mapping scan results: %w" , err )
156
208
}
157
209
return buildInfoSummary .GenerateMarkdown ()
@@ -170,9 +222,9 @@ func generateUploadMarkdown() error {
170
222
}
171
223
172
224
// mapScanResults maps the scan results saved during runtime into scan components.
173
- func mapScanResults (commandSummary * commandsummary. CommandSummary ) (err error ) {
225
+ func mapScanResults () (err error ) {
174
226
// Gets the saved scan results file paths.
175
- indexedFiles , err := commandSummary .GetIndexedDataFilesPaths ()
227
+ indexedFiles , err := commandsummary .GetIndexedDataFilesPaths ()
176
228
if err != nil {
177
229
return err
178
230
}
@@ -216,7 +268,7 @@ func processScan(index commandsummary.Index, filePath string, scannedName string
216
268
217
269
// shouldGenerateUploadSummary checks if upload summary should be generated.
218
270
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 ))
220
272
if _ , err := os .Stat (buildInfoPath ); os .IsNotExist (err ) {
221
273
return true , nil
222
274
}
0 commit comments