Skip to content

Commit 841cc07

Browse files
authored
Add a npx hereby validate command to group all repo validations (#64161)
1 parent 1f70213 commit 841cc07

2 files changed

Lines changed: 85 additions & 29 deletions

File tree

‎.github/copilot-instructions.md‎

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,18 @@ IF THESE COMMANDS FAIL, CI WILL FAIL, AND YOUR PR WILL BE REJECTED OUT OF HAND.
3030
FIXING ERRORS FROM THESE COMMANDS IS YOUR HIGHEST PRIORITY.
3131
ENSURE YOU DO THE RIGHT THINGS TO MAKE THEM PASS.
3232
```sh
33-
npx hereby build # Build the project
34-
npx hereby test # Run tests
35-
npx hereby lint # Run linters
36-
npx hereby format # Format the code
33+
npx hereby validate # Build, test, lint, and format the project
3734
```
3835
</critical>
3936

4037
If you are writing or testing TS API features (eg, code in packages/typescript/src/api/async/api.ts), additionally, you need to run
4138
```sh
42-
npx hereby test:api
39+
npx hereby validate --api # Also run the TypeScript API tests
4340
```
44-
which is not run as part of the primary suite.
41+
instead. API tests are not run by `npx hereby validate` without `--api`.
42+
43+
If as part of your change you edit tools, benchmarks, or other ancillary parts of the repository, you should instead run `npx hereby validate --all` to ensure *everything* is working correctly. This will
44+
most accurately approximate the results of a full CI run.
4545

4646
## Compiler Features, Fixes, and Tests
4747

@@ -134,10 +134,8 @@ Were alternate fixes considered? Describe them briefly if so
134134
## Copilot Checklist
135135

136136
<!-- don't lie! -->
137-
I successfully ran these commands at the end of my session, and they completed without error:
138-
* [ ] npx hereby build
139-
* [ ] npx hereby test
140-
* [ ] npx hereby lint
141-
* [ ] npx hereby format
137+
I successfully ran the applicable command at the end of my session, and it completed without error:
138+
* [ ] npx hereby validate
139+
* [ ] npx hereby validate --api (for TypeScript API changes)
142140

143141
```

‎Herebyfile.mjs‎

Lines changed: 76 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ const { values: rawOptions } = parseArgs({
103103
options: {
104104
tests: { type: "string", short: "t" },
105105
fix: { type: "boolean" },
106+
api: { type: "boolean" },
107+
all: { type: "boolean" },
106108
debug: { type: "boolean" },
107109
dirty: { type: "boolean" },
108110
release: { type: "boolean" },
@@ -967,13 +969,15 @@ export const generateAST = task({
967969
run: () => run("node", ["./tools/scripts/tsc/generate.ts"]),
968970
});
969971

972+
async function runGenerateAPI() {
973+
await run("go", ["-C", "./tools", "run", "./gen-proto", "../tsc/internal/api/proto.go", "../packages/typescript/src/api/proto.generated.ts"]);
974+
await run("npx", ["dprint", "fmt", "packages/typescript/src/api/proto.generated.ts"]);
975+
}
976+
970977
export const generateAPI = task({
971978
name: "generate:api",
972979
description: "Generates API files from internal/api/proto.go and internal/api/session.go.",
973-
run: async () => {
974-
await run("go", ["-C", "./tools", "run", "./gen-proto", "../tsc/internal/api/proto.go", "../packages/typescript/src/api/proto.generated.ts"]);
975-
await run("npx", ["dprint", "fmt", "packages/typescript/src/api/proto.generated.ts"]);
976-
},
980+
run: runGenerateAPI,
977981
});
978982

979983
// ── Vendored npm dependencies ───────────────────────────────────
@@ -1186,13 +1190,16 @@ export const testTsc = task({
11861190
run: runTests,
11871191
});
11881192

1193+
export const testExtension = task({
1194+
name: "test:extension",
1195+
description: "Runs the VS Code extension tests.",
1196+
run: runTestExtension,
1197+
});
1198+
11891199
export const test = task({
11901200
name: "test",
1191-
description: "Runs all tests. This is the most typical test task to need.",
1192-
run: async () => {
1193-
await runTests();
1194-
await runTestExtension();
1195-
},
1201+
description: "Alias for test:tsc.",
1202+
dependencies: [testTsc],
11961203
});
11971204

11981205
async function runTestBenchmarks() {
@@ -1223,12 +1230,6 @@ export const testTools = task({
12231230
run: runTestTools,
12241231
});
12251232

1226-
export const testExtension = task({
1227-
name: "test:extension",
1228-
description: "Runs the VS Code extension tests.",
1229-
run: runTestExtension,
1230-
});
1231-
12321233
export const buildAPI = task({
12331234
name: "build:api",
12341235
description: "Builds @typescript/typescript JS API.",
@@ -1237,13 +1238,15 @@ export const buildAPI = task({
12371238
},
12381239
});
12391240

1241+
async function runBuildAPITests() {
1242+
await run("npm", ["run", "-w", "@typescript/typescript", "build:test"]);
1243+
}
1244+
12401245
export const buildAPITests = task({
12411246
name: "build:api:test",
12421247
description: "Builds the @typescript/typescript JS API tests.",
12431248
dependencies: [generateEnums, generateAPI],
1244-
run: async () => {
1245-
await run("npm", ["run", "-w", "@typescript/typescript", "build:test"]);
1246-
},
1249+
run: runBuildAPITests,
12471250
});
12481251

12491252
export const testAPI = task({
@@ -1364,6 +1367,61 @@ async function runFormat() {
13641367
await run("dprint", ["fmt"]);
13651368
}
13661369

1370+
export const validate = task({
1371+
name: "validate",
1372+
description: "Builds, tests, lints, and formats the repo. Pass --api to include API tests, or --all to include all ancilliary repository tests.",
1373+
dependencies: [build],
1374+
run: async () => {
1375+
/** @type {{ name: string; error: unknown }[]} */
1376+
const failures = [];
1377+
/** @param {string} name @param {() => Promise<void>} action */
1378+
const runValidation = async (name, action) => {
1379+
try {
1380+
await action();
1381+
}
1382+
catch (error) {
1383+
failures.push({ name, error });
1384+
console.error(styleText("red", `${name} failed; continuing validation.`));
1385+
}
1386+
};
1387+
1388+
await runValidation("test:tsc", runTests);
1389+
await runValidation("test:extension", runTestExtension);
1390+
if (options.api || options.all) {
1391+
await runGenerateEnums(); // prereqs for test:api not included in `validate` deps
1392+
await runGenerateAPI();
1393+
await runBuildAPITests();
1394+
await runValidation("test:api", runTestAPI);
1395+
}
1396+
if (options.all) {
1397+
await runValidation("test:benchmarks", runTestBenchmarks);
1398+
await runValidation("test:tools", runTestTools);
1399+
await runValidation("test:smoke", runSmokeTest); // in CI this is run with `--race`
1400+
}
1401+
await runValidation("lint", runLint);
1402+
await runValidation("format", runFormat);
1403+
1404+
if (failures.length) {
1405+
throw new AggregateError(
1406+
failures.map(failure => failure.error),
1407+
`Validation failed: ${failures.map(failure => failure.name).join(", ")}`,
1408+
);
1409+
}
1410+
},
1411+
});
1412+
1413+
async function runSmokeTest() {
1414+
await run("./built/local/tsc", ["-p", "./tsc/testdata/fixtures/compiler", "--noEmit", "--singleThreaded"]);
1415+
await run("./built/local/tsc", ["-p", "./tsc/testdata/fixtures/compiler", "--noEmit"]);
1416+
}
1417+
1418+
export const smokeTest = task({
1419+
name: "test:smoke",
1420+
description: "Runs the smoke tests.",
1421+
dependencies: [build],
1422+
run: runSmokeTest,
1423+
});
1424+
13671425
export const checkFormat = task({
13681426
name: "check:format",
13691427
description: "Checks that the repo is formatted.",

0 commit comments

Comments
 (0)