1414 * limitations under the License.
1515 */
1616
17- import { errorMessage , parseDuration } from '@google-github-actions/actions-utils/dist' ;
17+ import { debug as logDebug } from '@actions/core' ;
18+
19+ import { errorMessage } from '@google-github-actions/actions-utils' ;
1820import { FailureCriteria , Operator } from './input_configuration' ;
1921import { Severity , Violation } from './accessor' ;
20- import {
21- DEFAULT_FAILURE_CRITERIA ,
22- DEFAULT_FAIL_SILENTLY ,
23- DEFAULT_IGNORE_VIOLATIONS ,
24- DEFAULT_SCAN_TIMEOUT ,
25- MAX_SCAN_TIMEOUT ,
26- MIN_SCAN_TIMEOUT ,
27- SCAN_TIMEOUT_CONFIG_KEY ,
28- } from './commons/constants' ;
29-
30- /**
31- * validateAndParseScanTimeOut validates whether given string is valid timeout for scan.
32- *
33- * If the string is empty or null, this returns the default value for scan_timeout.
34- */
35- export function validateAndParseScanTimeOut ( scan_timeout ?: string ) : number {
36- if ( isEmptyString ( scan_timeout ) ) {
37- return DEFAULT_SCAN_TIMEOUT ;
38- }
39-
40- try {
41- const scanTimeOutNum = parseDuration ( scan_timeout ?? '' ) * 1000 ;
42- if ( scanTimeOutNum > MAX_SCAN_TIMEOUT || scanTimeOutNum < MIN_SCAN_TIMEOUT ) {
43- throw new Error (
44- `Expected ${ SCAN_TIMEOUT_CONFIG_KEY } to be less than or equal to ${ MAX_SCAN_TIMEOUT } and greater than or equal to ${ MIN_SCAN_TIMEOUT } , found: ${ scanTimeOutNum } ` ,
45- ) ;
46- }
47- return scanTimeOutNum ;
48- } catch ( err ) {
49- const msg = errorMessage ( err ) ;
50- throw new Error ( `scan_timeout validation failed: ${ msg } ` ) ;
51- }
52- }
53-
54- /**
55- * validateAndParseIgnoreViolations valdiates whether given string is valid boolean..
56- *
57- * If the string is empty or null, this returns the default value for ignore_violations.
58- */
59- export function validateAndParseIgnoreViolations ( ignore_violation ?: string ) : boolean {
60- if ( isEmptyString ( ignore_violation ) ) {
61- return DEFAULT_IGNORE_VIOLATIONS ;
62- }
63- try {
64- return validateAndReturnBoolean ( ignore_violation ) ;
65- } catch ( err ) {
66- const msg = errorMessage ( err ) ;
67- throw new Error ( `ignore_violations validation failed: ${ msg } ` ) ;
68- }
69- }
22+ import { DEFAULT_FAILURE_CRITERIA } from './commons/constants' ;
7023
7124/**
7225 * validateAndParseFailureCriteria valdiates whether given string is valid representation for FailureCriteria.
@@ -80,7 +33,7 @@ export function validateAndParseIgnoreViolations(ignore_violation?: string): boo
8033 * Example of a valid failure_criteria string: "CRITICAL:2, HIGH:1, LOW:1, Operator:and".
8134 */
8235export function validateAndParseFailureCriteria ( failure_criteria ?: string ) : FailureCriteria {
83- if ( isEmptyString ( failure_criteria ) ) {
36+ if ( ! failure_criteria || failure_criteria == '' ) {
8437 failure_criteria = DEFAULT_FAILURE_CRITERIA ;
8538 }
8639 try {
@@ -93,19 +46,28 @@ export function validateAndParseFailureCriteria(failure_criteria?: string): Fail
9346}
9447
9548/**
96- * validateAndParseFailSilently valdiates whether given string is valid boolean .
49+ * isFailureCriteriaSatisfied decides if the failure criteria was satisfied .
9750 *
98- * If the string is empty or null, this returns the default value for fail_silently.
51+ * It decides this on the basis of configuration customer has set in their workflow and the violations
52+ * present in their plan file.
9953 */
100- export function validateAndParseFailSilently ( fail_silently ?: string ) : boolean {
101- if ( isEmptyString ( fail_silently ) ) {
102- return DEFAULT_FAIL_SILENTLY ;
103- }
104- try {
105- return validateAndReturnBoolean ( fail_silently ) ;
106- } catch ( err ) {
107- const msg = errorMessage ( err ) ;
108- throw new Error ( `fail_silently validation failed: ${ msg } ` ) ;
54+ export function isFailureCriteriaSatisfied (
55+ failure_criteria : FailureCriteria ,
56+ violations : Violation [ ] ,
57+ ) : boolean {
58+ const violationsCountBySeverity : Map < Severity , number > = getViolationCountBySeverity ( violations ) ;
59+ logDebug ( `Violations count by Severity: ${ [ ...violationsCountBySeverity . entries ( ) ] } ` ) ;
60+ const violationsThresholdBySeverity = failure_criteria . violationsThresholdBySeverity ;
61+ const failureCriteriasViolated : boolean [ ] = getFailureCriteriasViolated (
62+ violationsCountBySeverity ,
63+ violationsThresholdBySeverity ,
64+ ) ;
65+ const operator : Operator = failure_criteria . operator ;
66+
67+ if ( operator == Operator . AND ) {
68+ return failureCriteriasViolated . reduce ( ( acc , currentValue ) => acc && currentValue , true ) ;
69+ } else {
70+ return failureCriteriasViolated . reduce ( ( acc , currentValue ) => acc || currentValue , false ) ;
10971 }
11072}
11173
@@ -115,7 +77,7 @@ export function validateAndParseFailSilently(fail_silently?: string): boolean {
11577 * It compares the violations count found in reported violation summary with the violation severity threshold provided by the customer.
11678 * returns an array of boolean denoting whether a failure criteria was violated or not.
11779 */
118- export function getFailureCriteriasViolated (
80+ function getFailureCriteriasViolated (
11981 violationsCountBySeverity : Map < Severity , number > ,
12082 violationsThresholdBySeverity : Map < Severity , number > ,
12183) : boolean [ ] {
@@ -133,7 +95,7 @@ export function getFailureCriteriasViolated(
13395/**
13496 * getViolationCountBySeverity generates a map of Severity to the Violation's count.
13597 */
136- export function getViolationCountBySeverity ( violations : Violation [ ] ) : Map < Severity , number > {
98+ function getViolationCountBySeverity ( violations : Violation [ ] ) : Map < Severity , number > {
13799 const violationsCountBySeverity : Map < Severity , number > = new Map ( ) ;
138100 violations . forEach ( ( violation ) => {
139101 const severity : Severity = violation . severity ?? Severity . SeverityUnspecified ;
@@ -176,14 +138,10 @@ function validateAndExtractFailureCriteriaFromMap(
176138 if ( violationsThresholdBySeverity . has ( severity ) ) {
177139 throw new Error ( `multiple severities of type ${ key } found.` ) ;
178140 }
179- let valueNum ;
180- try {
181- valueNum = validateAndReturnNumber ( value ) ;
182- } catch ( err ) {
183- const msg = errorMessage ( err ) ;
184- throw new Error ( `invalid severity count, ${ msg } ` ) ;
141+ if ( isNaN ( + value ) ) {
142+ throw new Error ( `invalid severity count` ) ;
185143 }
186- violationsThresholdBySeverity . set ( severity , valueNum ) ;
144+ violationsThresholdBySeverity . set ( severity , + value ) ;
187145 } ) ;
188146
189147 if ( ! operator ) {
@@ -225,28 +183,3 @@ export function extractSeverityKey(key: string, errMsg: string): Severity {
225183 }
226184 return severityKey ;
227185}
228-
229- function validateAndReturnNumber ( number ?: string ) : number {
230- if ( ! number ) {
231- throw new Error ( `Number is empty` ) ;
232- }
233- if ( isNaN ( + number ) ) {
234- throw new Error ( `Invalid number: ${ number } ` ) ;
235- }
236- return + number ;
237- }
238-
239- function validateAndReturnBoolean ( str ?: string ) : boolean {
240- str = str ?. toUpperCase ( ) ;
241- if ( str == 'TRUE' ) {
242- return true ;
243- }
244- if ( str == 'FALSE' ) {
245- return false ;
246- }
247- throw new Error ( `Expected true or false, found: ${ str } ` ) ;
248- }
249-
250- function isEmptyString ( str ?: string ) : boolean {
251- return str == null || str == '' ;
252- }
0 commit comments