@@ -36,6 +36,7 @@ func init() {
3636 releaseCmd .Flags ().Bool ("cs" , false , "cs criteria status" )
3737 releaseCmd .Flags ().Bool ("iac" , false , "iac criteria status" )
3838 releaseCmd .Flags ().Bool ("mast" , false , "mast criteria status" )
39+ releaseCmd .Flags ().Bool ("sbom" , false , "sbom criteria status" )
3940 releaseCmd .Flags ().Int ("timeout" , 5 , "minutes to wait for release criteria check to finish" )
4041 _ = releaseCmd .MarkFlagRequired ("project" )
4142}
@@ -79,12 +80,17 @@ func releaseRootCommand(cmd *cobra.Command, _ []string) {
7980 }
8081
8182 releaseCriteriaRows := []Row {
82- {Columns : []string {"STATUS" , "SAST" , "DAST" , "PENTEST" , "IAST" , "SCA" , "CS" , "IAC" , "MAST" }},
83- {Columns : []string {"------" , "----" , "----" , "-------" , "----" , "---" , "--" , "---" , "----" }},
84- {Columns : []string {rs .Status , rs .SAST .Status , rs .DAST .Status , rs .PENTEST .Status , rs .IAST .Status , rs .SCA .Status , rs .CS .Status , rs .IAC .Status , rs .MAST .Status }},
83+ {Columns : []string {"STATUS" , "SAST" , "DAST" , "PENTEST" , "IAST" , "SCA" , "CS" , "IAC" , "MAST" , "SBOM" }},
84+ {Columns : []string {"------" , "----" , "----" , "-------" , "----" , "---" , "--" , "---" , "----" , "----" }},
85+ {Columns : []string {rs .Status , rs .SAST .Status , rs .DAST .Status , rs .PENTEST .Status , rs .IAST .Status , rs .SCA .Status , rs .CS .Status , rs .IAC .Status , rs .MAST .Status , rs . SBOM . Status }},
8586 }
8687 TableWriter (releaseCriteriaRows ... )
8788
89+ scannerTypeSpecified , scannerTypeMap := parseReleaseFlags (cmd )
90+ isReleaseFailed (rs , scannerTypeSpecified , scannerTypeMap )
91+ }
92+
93+ func parseReleaseFlags (cmd * cobra.Command ) (bool , map [string ]bool ) {
8894 sast , err := cmd .Flags ().GetBool ("sast" )
8995 if err != nil {
9096 qwm (ExitCodeError , "failed to parse sast flag" )
@@ -125,22 +131,29 @@ func releaseRootCommand(cmd *cobra.Command, _ []string) {
125131 qwm (ExitCodeError , "failed to parse mast flag" )
126132 }
127133
128- isSpecific := sast || dast || pentest || iast || sca || cs || iac || mast
134+ sbom , err := cmd .Flags ().GetBool ("sbom" )
135+ if err != nil {
136+ qwm (ExitCodeError , "failed to parse sbom flag" )
137+ }
138+
139+ scannerTypeSpecified := sast || dast || pentest || iast || sca || cs || iac || mast || sbom
129140
130- var spesificMap = make (map [string ]bool , 0 )
131- spesificMap ["SAST" ] = sast
132- spesificMap ["DAST" ] = dast
133- spesificMap ["PENTEST" ] = pentest
134- spesificMap ["IAST" ] = iast
135- spesificMap ["SCA" ] = sca
136- spesificMap ["CS" ] = cs
137- spesificMap ["IAC" ] = iac
138- spesificMap ["MAST" ] = mast
141+ scannerTypeMap := map [string ]bool {
142+ "SAST" : sast ,
143+ "DAST" : dast ,
144+ "PENTEST" : pentest ,
145+ "IAST" : iast ,
146+ "SCA" : sca ,
147+ "CS" : cs ,
148+ "IAC" : iac ,
149+ "MAST" : mast ,
150+ "SBOM" : sbom ,
151+ }
139152
140- isReleaseFailed ( rs , isSpecific , spesificMap )
153+ return scannerTypeSpecified , scannerTypeMap
141154}
142155
143- func isReleaseFailed (release * client.ReleaseStatus , isSpecific bool , specificMap map [string ]bool ) {
156+ func isReleaseFailed (release * client.ReleaseStatus , scannerTypeSpecified bool , scannerTypeMap map [string ]bool ) {
144157 const statusFail = "fail"
145158
146159 if release .Status != statusFail {
@@ -173,6 +186,9 @@ func isReleaseFailed(release *client.ReleaseStatus, isSpecific bool, specificMap
173186 if release .MAST .Status == statusFail {
174187 failedScans ["MAST" ] = release .MAST .ScanID
175188 }
189+ if release .SBOM .Status == statusFail {
190+ failedScans ["SBOM" ] = ""
191+ }
176192
177193 if verbose {
178194 c , err := client .New ()
@@ -181,30 +197,33 @@ func isReleaseFailed(release *client.ReleaseStatus, isSpecific bool, specificMap
181197 }
182198
183199 for toolType , scanID := range failedScans {
184- if isSpecific {
185- if ! specificMap [toolType ] {
200+ if scannerTypeSpecified {
201+ if ! scannerTypeMap [toolType ] {
186202 continue
187203 }
188204 }
189205
190206 fmt .Println ()
191207 fmt .Println ("-----------------------------------------------------------------" )
192208 fmt .Printf ("[!] project does not pass release criteria due to [%s] failure\n " , toolType )
193- scan , err := c .FindScanByID (scanID )
194- if err != nil {
195- qwe (ExitCodeError , err , "failed to fetch scan summary" )
196- }
197209
198- printScanSummary (scan )
210+ // SBOM doesn't have a scan_id, skip fetching scan details
211+ if scanID != "" {
212+ scan , err := c .FindScanByID (scanID )
213+ if err != nil {
214+ qwe (ExitCodeError , err , "failed to fetch scan summary" )
215+ }
216+ printScanSummary (scan )
217+ }
199218 fmt .Println ("-----------------------------------------------------------------" )
200219 }
201220 }
202221
203222 var failedToolTypes []string
204223
205224 for toolType := range failedScans {
206- if isSpecific {
207- if specificMap [toolType ] {
225+ if scannerTypeSpecified {
226+ if scannerTypeMap [toolType ] {
208227 failedToolTypes = append (failedToolTypes , toolType )
209228 }
210229 } else {
@@ -213,7 +232,7 @@ func isReleaseFailed(release *client.ReleaseStatus, isSpecific bool, specificMap
213232 }
214233
215234 if len (failedToolTypes ) == 0 {
216- returnMSG := fmt . Sprintf ( "project passes release criteria" )
235+ returnMSG := "project passes release criteria"
217236 qwe (ExitCodeSuccess , errors .New (returnMSG ))
218237 } else {
219238 returnMSG := fmt .Sprintf ("project does not pass release criteria due to [%s] failure" , strings .Join (failedToolTypes , ", " ))
0 commit comments