@@ -8,7 +8,7 @@ async function run() {
88 const failOnVulnerabilities = tl . getBoolInput ( 'failOnVulnerabilities' , false ) ;
99
1010 // Construct the retire command
11- let command = 'retire --colors ' ;
11+ let command = 'retire --outputformat json ' ;
1212
1313 if ( verbose ) {
1414 command += ' --verbose' ;
@@ -24,16 +24,70 @@ async function run() {
2424
2525 // Install Retire.js
2626 tl . debug ( 'Installing Retire.js...' ) ;
27- await tl . exec ( 'npm' , [ 'install' , '-g' , 'retire' ] ) ;
27+ await tl . exec ( 'npm' , [ 'install' , '-g' , 'retire' ] , { silent : true } ) ;
2828
29- // Run Retire.js
29+ // Run Retire.js and capture output
3030 tl . debug ( `Executing command: ${ command } ` ) ;
31- await tl . exec ( 'sh' , [ '-c' , command ] ) ; // Use 'sh -c' for cross-platform compatibility
31+ const result = tl . execSync ( 'sh' , [ '-c' , command ] , { silent : true } ) ;
3232
33- tl . setResult ( tl . TaskResult . Succeeded , 'Retire completed successfully' ) ;
33+ const stdout = result . stdout ?. toString ( ) || '' ;
34+ let hasRealVulnerabilities = false ;
35+
36+ if ( stdout . trim ( ) . startsWith ( '{' ) ) {
37+ try {
38+ const parsed = JSON . parse ( stdout ) ;
39+ const matches = parsed . data || [ ] ;
40+
41+ for ( const entry of matches ) {
42+ const file = entry . file ;
43+ const results = Array . isArray ( entry . results ) ? entry . results : [ ] ;
44+
45+ for ( const vuln of results ) {
46+ const vulnerabilities = Array . isArray ( vuln . vulnerabilities ) ? vuln . vulnerabilities : [ ] ;
47+ const hasVulns = vulnerabilities . length > 0 ;
48+
49+ const component = vuln . component || 'unknown' ;
50+ const version = vuln . version || 'unknown' ;
51+ const identifiers = vuln . identifiers || { } ;
52+ const cves = identifiers . CVE ?. join ( ', ' ) || 'None' ;
53+ const infoLinks = hasVulns
54+ ? vulnerabilities . flatMap ( v => v . info || [ ] ) . join ( ', ' ) || 'None'
55+ : 'None' ;
56+ const severity = ( vulnerabilities . length > 0 && vulnerabilities [ 0 ] . severity )
57+ ? vulnerabilities [ 0 ] . severity
58+ : 'none' ;
59+
60+ const message =
61+ `- Component: ${ component }
62+ - Version: ${ version }
63+ - File: ${ file }
64+ - Severity: ${ severity }
65+ - CVEs: ${ cves }
66+ - Info: ${ infoLinks } ` ;
67+
68+ if ( hasVulns ) {
69+ hasRealVulnerabilities = true ;
70+ tl . warning ( `Vulnerable library found:\n${ message } ` ) ;
71+ } else if ( verbose ) {
72+ console . log ( `Library matched but no known vulnerabilities:\n${ message } ` ) ;
73+ }
74+ }
75+ }
76+ } catch ( err ) {
77+ tl . warning ( 'Could not parse JSON output from Retire.js' ) ;
78+ }
79+ } else {
80+ tl . warning ( 'No JSON output detected from Retire.js' ) ;
81+ }
82+
83+ if ( hasRealVulnerabilities && failOnVulnerabilities ) {
84+ tl . setResult ( tl . TaskResult . Failed , 'Vulnerabilities were found and failOnVulnerabilities is true.' ) ;
85+ } else {
86+ tl . setResult ( tl . TaskResult . Succeeded , 'Retire completed successfully' ) ;
87+ }
3488 } catch ( err ) {
3589 tl . setResult ( tl . TaskResult . Failed , `Task failed: ${ err . message } ` ) ;
3690 }
3791}
3892
39- run ( ) ;
93+ run ( ) ;
0 commit comments