diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index ffe5584dd0b0d..bb535cd6a0c14 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -30,18 +30,15 @@ IF THESE COMMANDS FAIL, CI WILL FAIL, AND YOUR PR WILL BE REJECTED OUT OF HAND. FIXING ERRORS FROM THESE COMMANDS IS YOUR HIGHEST PRIORITY. ENSURE YOU DO THE RIGHT THINGS TO MAKE THEM PASS. ```sh -npx hereby build # Build the project -npx hereby test # Run tests -npx hereby lint # Run linters -npx hereby format # Format the code +npx hereby validate # Build, test, lint, and format the project ``` If you are writing or testing TS API features (eg, code in packages/typescript/src/api/async/api.ts), additionally, you need to run ```sh -npx hereby test:api +npx hereby validate --api # Also run the TypeScript API tests ``` -which is not run as part of the primary suite. +instead. API tests are not run by `npx hereby validate` without `--api`. ## Compiler Features, Fixes, and Tests @@ -134,10 +131,8 @@ Were alternate fixes considered? Describe them briefly if so ## Copilot Checklist -I successfully ran these commands at the end of my session, and they completed without error: - * [ ] npx hereby build - * [ ] npx hereby test - * [ ] npx hereby lint - * [ ] npx hereby format +I successfully ran the applicable command at the end of my session, and it completed without error: + * [ ] npx hereby validate + * [ ] npx hereby validate --api (for TypeScript API changes) ``` diff --git a/Herebyfile.mjs b/Herebyfile.mjs index 381b13808b5e4..1fc5f78576006 100644 --- a/Herebyfile.mjs +++ b/Herebyfile.mjs @@ -103,6 +103,7 @@ const { values: rawOptions } = parseArgs({ options: { tests: { type: "string", short: "t" }, fix: { type: "boolean" }, + api: { type: "boolean" }, debug: { type: "boolean" }, dirty: { type: "boolean" }, release: { type: "boolean" }, @@ -1364,6 +1365,43 @@ async function runFormat() { await run("dprint", ["fmt"]); } +export const validate = task({ + name: "validate", + description: "Builds, tests, lints, and formats the repo. Pass --api to include API tests.", + dependencies: [build], + run: async () => { + /** @type {{ name: string; error: unknown }[]} */ + const failures = []; + /** @param {string} name @param {() => Promise} action */ + const runValidation = async (name, action) => { + try { + await action(); + } + catch (error) { + failures.push({ name, error }); + console.error(styleText("red", `${name} failed; continuing validation.`)); + } + }; + + await runValidation("test", async () => { + await runTests(); + await runTestExtension(); + }); + if (options.api) { + await runValidation("test:api", runTestAPI); + } + await runValidation("lint", runLint); + await runValidation("format", runFormat); + + if (failures.length) { + throw new AggregateError( + failures.map(failure => failure.error), + `Validation failed: ${failures.map(failure => failure.name).join(", ")}`, + ); + } + }, +}); + export const checkFormat = task({ name: "check:format", description: "Checks that the repo is formatted.",