@@ -8,7 +8,7 @@ async function run() {
8
8
const failOnVulnerabilities = tl . getBoolInput ( 'failOnVulnerabilities' , false ) ;
9
9
10
10
// Construct the retire command
11
- let command = 'retire --colors ' ;
11
+ let command = 'retire --outputformat json ' ;
12
12
13
13
if ( verbose ) {
14
14
command += ' --verbose' ;
@@ -24,16 +24,70 @@ async function run() {
24
24
25
25
// Install Retire.js
26
26
tl . debug ( 'Installing Retire.js...' ) ;
27
- await tl . exec ( 'npm' , [ 'install' , '-g' , 'retire' ] ) ;
27
+ await tl . exec ( 'npm' , [ 'install' , '-g' , 'retire' ] , { silent : true } ) ;
28
28
29
- // Run Retire.js
29
+ // Run Retire.js and capture output
30
30
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 } ) ;
32
32
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
+ }
34
88
} catch ( err ) {
35
89
tl . setResult ( tl . TaskResult . Failed , `Task failed: ${ err . message } ` ) ;
36
90
}
37
91
}
38
92
39
- run ( ) ;
93
+ run ( ) ;
0 commit comments