|
1 | 1 | import { getBooleanInput, getInput, setFailed, debug } from "@actions/core"; |
2 | 2 | import { exec } from "@actions/exec"; |
3 | 3 | import { getOctokit, context } from "@actions/github"; |
4 | | -import { analyze, eslint, litAnalyzer } from "./scripts/analyze"; |
5 | | -import { formatting } from "./scripts/formatting"; |
6 | | -import { testing } from "./scripts/testing"; |
| 4 | +import { eslint, litAnalyzer } from "./scripts/analyze"; |
| 5 | +import { playwright, testing } from "./scripts/testing"; |
7 | 6 | import { comment } from "./scripts/comment"; |
8 | 7 | import { cwd, chdir } from "process"; |
9 | 8 | // import { coverage } from './scripts/coverage' |
10 | 9 | import minimist from "minimist"; |
11 | | -import { setup } from "./scripts/setup"; |
| 10 | +import { execSync } from "child_process"; |
| 11 | +import { checkModifiedFiles } from "./scripts/post"; |
12 | 12 |
|
13 | 13 | export type Command = { label: string; command: string }; |
14 | 14 |
|
15 | | -export type stepResponse = { output: string; error: boolean }; |
| 15 | +export type StepResponse = { output: string; error: boolean }; |
16 | 16 | export const failedEmoji = "❌"; |
17 | 17 | export const passedEmoji = "✅"; |
18 | 18 |
|
19 | | -export const buildComment = async ( |
20 | | - commands: { label: string; command: string }[], |
21 | | -): Promise<string[]> => { |
22 | | - let commentBody = "\n"; |
23 | | - let errorMessages = ""; |
24 | | - for (const { label, command } of commands) { |
25 | | - const result = await runCommand(command, label); |
26 | | - if (result) { |
27 | | - commentBody += `${failedEmoji} - ${label} |
28 | | -<details><summary>See details</summary>${result}</details>`; |
29 | | - errorMessages += `${result}`; |
30 | | - } else { |
31 | | - commentBody += `${passedEmoji} - ${label}\n`; |
| 19 | +export const runBashCommand = async (command: string): Promise<string> => { |
| 20 | + return new Promise((resolve, reject) => { |
| 21 | + try { |
| 22 | + const output = execSync(command, { encoding: "utf-8" }); |
| 23 | + resolve(output); |
| 24 | + } catch (error) { |
| 25 | + reject(error); |
32 | 26 | } |
33 | | - } |
34 | | - return [commentBody, errorMessages]; |
| 27 | + }); |
35 | 28 | }; |
36 | 29 |
|
37 | 30 | export const runCommand = async ( |
38 | | - command: string, |
39 | | - label: string, |
40 | | -): Promise<string | boolean> => { |
41 | | - let output = ""; |
| 31 | + command: Command, |
| 32 | +): Promise<[StepResponse, string]> => { |
| 33 | + let response: StepResponse = { output: "", error: false }; |
| 34 | + let outputStr = ""; |
42 | 35 | try { |
43 | | - await exec(command, [], { |
| 36 | + await exec(command.command, [], { |
44 | 37 | listeners: { |
45 | 38 | stdout: (data) => { |
46 | | - output += data.toString(); |
| 39 | + outputStr += data.toString(); |
47 | 40 | }, |
48 | 41 | }, |
49 | 42 | }); |
50 | | - return false; |
51 | | - } catch (error: unknown) { |
52 | | - if (error instanceof Error) { |
53 | | - debug(`${label} failed: ${error.message}`); |
54 | | - return output; |
55 | | - } else if (typeof error === "string") { |
56 | | - debug(`${label} failed: ${error}`); |
57 | | - return output; |
58 | | - } else { |
59 | | - return true; |
60 | | - } |
| 43 | + } catch (error) { |
| 44 | + response.error = true; |
| 45 | + setFailed(`Failed ${command.label}: ${error as string}`); |
| 46 | + } |
| 47 | + return [response, outputStr]; |
| 48 | +}; |
| 49 | + |
| 50 | +export const buildComment = async ( |
| 51 | + response: StepResponse, |
| 52 | + outputStr: string, |
| 53 | + label: string, |
| 54 | +): Promise<StepResponse> => { |
| 55 | + if (response.error == true) { |
| 56 | + response.output = `${failedEmoji} - ${label}\n<details><summary>See Details</summary>${outputStr}</details>`; |
| 57 | + } else { |
| 58 | + response.output = `${passedEmoji} - ${label}\n`; |
61 | 59 | } |
| 60 | + return response; |
| 61 | +}; |
| 62 | + |
| 63 | +export const commandComment = async ( |
| 64 | + command: Command, |
| 65 | +): Promise<StepResponse> => { |
| 66 | + const [response, outputStr] = await runCommand(command); |
| 67 | + return await buildComment(response, outputStr, command.label); |
| 68 | +}; |
| 69 | + |
| 70 | +const checkIfLocal = (): boolean => { |
| 71 | + const argv = minimist(process.argv.slice(2)); |
| 72 | + |
| 73 | + return argv._.findLast((x: string) => x == "--local") == "--local" |
| 74 | + ? true |
| 75 | + : false; |
| 76 | +}; |
| 77 | + |
| 78 | +const getInputs = ( |
| 79 | + isLocal: boolean, |
| 80 | +): [string, string, boolean, boolean, boolean, boolean] => { |
| 81 | + // get the token and octokit |
| 82 | + let token = ""; |
| 83 | + if (process.env.GITHUB_TOKEN && isLocal) { |
| 84 | + token = process.env.GITHUB_TOKEN; |
| 85 | + } else { |
| 86 | + token = getInput("token"); |
| 87 | + } |
| 88 | + |
| 89 | + const workingDirectory = getInput("working-directory"); |
| 90 | + |
| 91 | + // get static analysis input |
| 92 | + const doStaticAnalysis: boolean = isLocal |
| 93 | + ? true |
| 94 | + : getBooleanInput("run-static-analysis"); |
| 95 | + |
| 96 | + // get code formatting input |
| 97 | + const doCodeFormatting: boolean = isLocal |
| 98 | + ? true |
| 99 | + : getBooleanInput("run-code-formatting"); |
| 100 | + |
| 101 | + // get tests input |
| 102 | + const doTests: boolean = isLocal ? true : getBooleanInput("run-tests"); |
| 103 | + |
| 104 | + // const runCoverage: boolean = getBooleanInput('run-coverage'); |
| 105 | + // const coveragePassScore: string = getInput('coverage-pass-score'); |
| 106 | + // get comment input |
| 107 | + const createComment: boolean = isLocal |
| 108 | + ? true |
| 109 | + : getBooleanInput("create-comment"); |
| 110 | + |
| 111 | + return [ |
| 112 | + token, |
| 113 | + workingDirectory, |
| 114 | + doStaticAnalysis, |
| 115 | + doCodeFormatting, |
| 116 | + doTests, |
| 117 | + createComment, |
| 118 | + ]; |
62 | 119 | }; |
63 | 120 |
|
64 | 121 | /** |
65 | 122 | * The main function for the action. |
66 | 123 | * @returns {Promise<void>} Resolves when the action is complete. |
67 | 124 | */ |
68 | 125 | export async function run(): Promise<void> { |
69 | | - const argv = minimist(process.argv.slice(2)); |
70 | | - |
71 | | - const isLocal = |
72 | | - argv._.findLast((x: string) => x == "--local") == "--local" ? true : false; |
| 126 | + const isLocal = checkIfLocal(); |
73 | 127 |
|
74 | 128 | try { |
75 | | - const workingDirectory = getInput("working-directory"); |
| 129 | + const [ |
| 130 | + token, |
| 131 | + workingDirectory, |
| 132 | + doStaticAnalysis, |
| 133 | + doCodeFormatting, |
| 134 | + doTests, |
| 135 | + createComment, |
| 136 | + ] = getInputs(isLocal); |
| 137 | + |
76 | 138 | // Check if the working directory is different from the current directory |
77 | 139 | const currentDirectory = cwd(); |
78 | 140 | if (workingDirectory && workingDirectory !== currentDirectory) { |
79 | 141 | chdir(workingDirectory); |
80 | 142 | } |
81 | 143 |
|
82 | | - // get the token and octokit |
83 | | - let token = ""; |
84 | | - if (process.env.GITHUB_TOKEN && isLocal) { |
85 | | - token = process.env.GITHUB_TOKEN; |
86 | | - } else { |
87 | | - token = getInput("token"); |
88 | | - } |
89 | | - const octokit = getOctokit(token); |
90 | | - |
91 | | - // get static analysis input |
92 | | - const doStaticAnalysis: boolean = isLocal |
93 | | - ? true |
94 | | - : getBooleanInput("run-static-analysis"); |
95 | | - |
96 | | - // get code formatting input |
97 | | - const doCodeFormatting: boolean = isLocal |
98 | | - ? true |
99 | | - : getBooleanInput("run-code-formatting"); |
100 | | - |
101 | | - // get tests input |
102 | | - const doTests: boolean = isLocal ? true : getBooleanInput("run-tests"); |
103 | | - |
104 | | - // const runCoverage: boolean = getBooleanInput('run-coverage'); |
105 | | - // const coveragePassScore: string = getInput('coverage-pass-score'); |
106 | | - // get comment input |
107 | | - const createComment: boolean = isLocal |
108 | | - ? true |
109 | | - : getBooleanInput("create-comment"); |
110 | | - |
111 | 144 | // run set up |
112 | | - const setupStr: stepResponse | undefined = await setup(); |
| 145 | + const npmIStr: StepResponse | undefined = await commandComment({ |
| 146 | + label: "Install Dependencies", |
| 147 | + command: "npm i --ignore-scripts", |
| 148 | + }); |
113 | 149 |
|
114 | 150 | // run Static Analysis |
115 | | - const analyzeStr: stepResponse | undefined = doStaticAnalysis |
116 | | - ? await analyze() |
117 | | - : undefined; |
| 151 | + const cemStr: StepResponse | undefined = await commandComment({ |
| 152 | + label: "Custom Elements Manifest", |
| 153 | + command: "npm run analyze", |
| 154 | + }); |
118 | 155 |
|
119 | | - const eslintStr: stepResponse | undefined = doStaticAnalysis |
| 156 | + const eslintStr: StepResponse | undefined = doStaticAnalysis |
120 | 157 | ? await eslint({ label: "ESLint", command: "npm run lint" }) |
121 | 158 | : undefined; |
122 | 159 |
|
123 | | - const litAnalyzerStr: stepResponse | undefined = doStaticAnalysis |
| 160 | + const litAnalyzerStr: StepResponse | undefined = doStaticAnalysis |
124 | 161 | ? await litAnalyzer({ |
125 | 162 | label: "Lit Analyzer", |
126 | 163 | command: "npm run lint:lit-analyzer -- --format markdown", |
127 | 164 | }) |
128 | 165 | : undefined; |
129 | 166 |
|
130 | 167 | // run Code Formatting |
131 | | - const codeFormattingStr: stepResponse | undefined = doCodeFormatting |
132 | | - ? await formatting() |
| 168 | + const prettierStr: StepResponse | undefined = doCodeFormatting |
| 169 | + ? await commandComment({ label: "Prettier", command: "npm run prettier" }) |
| 170 | + : undefined; |
| 171 | + |
| 172 | + const playwrightStr: StepResponse | undefined = doTests |
| 173 | + ? await playwright({ |
| 174 | + label: "Install PlayWright Browsers", |
| 175 | + command: "npx playwright install --with-deps", |
| 176 | + }) |
133 | 177 | : undefined; |
134 | 178 |
|
135 | 179 | // run Tests |
136 | | - const testingStr: stepResponse | undefined = doTests |
137 | | - ? await testing() |
| 180 | + const testingStr: StepResponse | undefined = doTests |
| 181 | + ? await testing({ |
| 182 | + label: "Testing", |
| 183 | + command: "npm run test -- --coverage", |
| 184 | + }) |
| 185 | + : undefined; |
| 186 | + |
| 187 | + const tsDocStr: StepResponse | undefined = doTests |
| 188 | + ? await commandComment({ label: "TSDoc", command: "npm run docs" }) |
138 | 189 | : undefined; |
139 | 190 |
|
| 191 | + const checkModifiedFilesStr: StepResponse | undefined = |
| 192 | + await checkModifiedFiles({ |
| 193 | + label: "Check for modified files", |
| 194 | + command: |
| 195 | + 'echo "modified=$(if [ -n "$(git status --porcelain)" ]; then echo "true"; else echo "false"; fi)" >> $GITHUB_ENV', |
| 196 | + }); |
| 197 | + |
140 | 198 | // runCoverage |
141 | | - // const coverageStr: stepResponse | undefined = runCoverage |
| 199 | + // const coverageStr: StepResponse | undefined = runCoverage |
142 | 200 | // ? await coverage() |
143 | 201 | // : undefined |
144 | 202 |
|
145 | 203 | // createComment |
146 | 204 | if (createComment) { |
147 | 205 | await comment( |
148 | | - octokit, |
| 206 | + getOctokit(token), |
149 | 207 | context, |
150 | | - setupStr, |
151 | | - analyzeStr, |
| 208 | + npmIStr, |
| 209 | + cemStr, |
152 | 210 | eslintStr, |
153 | 211 | litAnalyzerStr, |
154 | | - codeFormattingStr, |
| 212 | + prettierStr, |
| 213 | + playwrightStr, |
155 | 214 | testingStr, |
| 215 | + tsDocStr, |
156 | 216 | ); |
157 | 217 | } |
158 | 218 | } catch (error) { |
|
0 commit comments