|
1 | 1 | import fs from "fs"; |
| 2 | +import path from "path"; |
2 | 3 |
|
3 | 4 | import * as core from "@actions/core"; |
| 5 | +import { globSync } from "glob"; |
4 | 6 |
|
5 | 7 | import * as sarif from "../src/sarif"; |
6 | 8 |
|
@@ -34,59 +36,83 @@ function checkStatusPageNotification(n: sarif.Notification) { |
34 | 36 | } |
35 | 37 | } |
36 | 38 |
|
37 | | -const sarifPath = process.env["SARIF_PATH"]; |
| 39 | +function checkSarif(sarifFile: string) { |
| 40 | + core.info(`Checking SARIF file at '${sarifFile}'`); |
38 | 41 |
|
39 | | -if (sarifPath === undefined) { |
40 | | - throw new Error("The path to a SARIF file must be set in 'SARIF_PATH'."); |
41 | | -} |
| 42 | + const log = JSON.parse(fs.readFileSync(sarifFile, "utf8")) as sarif.Log; |
| 43 | + const run = log.runs[0]; |
42 | 44 |
|
43 | | -const log = JSON.parse(fs.readFileSync(sarifPath, "utf8")) as sarif.Log; |
44 | | -const run = log.runs[0]; |
| 45 | + if (run.invocations === undefined) { |
| 46 | + throw new Error("run.invocations is undefined"); |
| 47 | + } |
45 | 48 |
|
46 | | -if (run.invocations === undefined) { |
47 | | - throw new Error("run.invocations is undefined"); |
48 | | -} |
| 49 | + const toolExecutionNotifications = |
| 50 | + run.invocations[0].toolExecutionNotifications; |
49 | 51 |
|
50 | | -const toolExecutionNotifications = |
51 | | - run.invocations[0].toolExecutionNotifications; |
| 52 | + if (toolExecutionNotifications === undefined) { |
| 53 | + throw new Error("toolExecutionNotifications is undefined"); |
| 54 | + } |
52 | 55 |
|
53 | | -if (toolExecutionNotifications === undefined) { |
54 | | - throw new Error("toolExecutionNotifications is undefined"); |
55 | | -} |
| 56 | + const statusPageNotifications = toolExecutionNotifications.filter( |
| 57 | + (n) => |
| 58 | + n.descriptor?.id === DIAGNOSTIC_ID && |
| 59 | + n.properties?.visibility?.statusPage, |
| 60 | + ); |
| 61 | + if (statusPageNotifications.length !== 1) { |
| 62 | + core.setFailed( |
| 63 | + "Expected exactly one status page reporting descriptor for this diagnostic in the " + |
| 64 | + `'runs[].invocations[].toolExecutionNotifications[]' SARIF property, but found ` + |
| 65 | + `${statusPageNotifications.length}. All notification reporting descriptors: ` + |
| 66 | + `${JSON.stringify(toolExecutionNotifications)}.`, |
| 67 | + ); |
| 68 | + } |
| 69 | + checkStatusPageNotification(statusPageNotifications[0]); |
56 | 70 |
|
57 | | -const statusPageNotifications = toolExecutionNotifications.filter( |
58 | | - (n) => |
59 | | - n.descriptor?.id === DIAGNOSTIC_ID && n.properties?.visibility?.statusPage, |
60 | | -); |
61 | | -if (statusPageNotifications.length !== 1) { |
62 | | - core.setFailed( |
63 | | - "Expected exactly one status page reporting descriptor for this diagnostic in the " + |
64 | | - `'runs[].invocations[].toolExecutionNotifications[]' SARIF property, but found ` + |
65 | | - `${statusPageNotifications.length}. All notification reporting descriptors: ` + |
66 | | - `${JSON.stringify(toolExecutionNotifications)}.`, |
| 71 | + const notifications = run.tool.driver.notifications; |
| 72 | + |
| 73 | + if (notifications === undefined) { |
| 74 | + throw new Error("notifications is undefined"); |
| 75 | + } |
| 76 | + |
| 77 | + const diagnosticNotification = notifications.filter( |
| 78 | + (n) => |
| 79 | + n.id === DIAGNOSTIC_ID && |
| 80 | + n.name === DIAGNOSTIC_ID && |
| 81 | + n.fullDescription?.text === DIAGNOSTIC_NAME, |
67 | 82 | ); |
| 83 | + if (diagnosticNotification.length !== 1) { |
| 84 | + core.setFailed( |
| 85 | + "Expected exactly one notification for this diagnostic in the " + |
| 86 | + `'runs[].tool.driver.notifications[]' SARIF property, but found ` + |
| 87 | + `${diagnosticNotification.length}. All notifications: ` + |
| 88 | + `${JSON.stringify(notifications)}.`, |
| 89 | + ); |
| 90 | + } |
68 | 91 | } |
69 | | -checkStatusPageNotification(statusPageNotifications[0]); |
70 | 92 |
|
71 | | -const notifications = run.tool.driver.notifications; |
| 93 | +const sarifPath = process.env["SARIF_PATH"]; |
72 | 94 |
|
73 | | -if (notifications === undefined) { |
74 | | - throw new Error("notifications is undefined"); |
| 95 | +if (sarifPath === undefined) { |
| 96 | + throw new Error( |
| 97 | + "The path to a SARIF file or directory must be set in 'SARIF_PATH'.", |
| 98 | + ); |
75 | 99 | } |
76 | 100 |
|
77 | | -const diagnosticNotification = notifications.filter( |
78 | | - (n) => |
79 | | - n.id === DIAGNOSTIC_ID && |
80 | | - n.name === DIAGNOSTIC_ID && |
81 | | - n.fullDescription?.text === DIAGNOSTIC_NAME, |
82 | | -); |
83 | | -if (diagnosticNotification.length !== 1) { |
84 | | - core.setFailed( |
85 | | - "Expected exactly one notification for this diagnostic in the " + |
86 | | - `'runs[].tool.driver.notifications[]' SARIF property, but found ` + |
87 | | - `${diagnosticNotification.length}. All notifications: ` + |
88 | | - `${JSON.stringify(notifications)}.`, |
89 | | - ); |
| 101 | +if (fs.statSync(sarifPath).isDirectory()) { |
| 102 | + const sarifFiles = globSync("**/*.sarif", { |
| 103 | + cwd: path.resolve(sarifPath), |
| 104 | + absolute: true, |
| 105 | + }); |
| 106 | + |
| 107 | + if (sarifFiles.length < 1) { |
| 108 | + throw new Error(`Unable to find any .sarif files in '${sarifPath}'.`); |
| 109 | + } |
| 110 | + |
| 111 | + for (const sarifFile of sarifFiles) { |
| 112 | + checkSarif(sarifFile); |
| 113 | + } |
| 114 | +} else { |
| 115 | + checkSarif(sarifPath); |
90 | 116 | } |
91 | 117 |
|
92 | 118 | core.info("Finished diagnostic export test"); |
0 commit comments