ci: typecheck github-script code#485846
Conversation
Add jsconfig.json with checkJs enabled to catch common JavaScript bugs like using Set.length instead of Set.size, undeclared variables, and mismatched function signatures. Add typescript and @types/node as devDependencies. Document how to run the type checker in README.md.
The dismissReviews function requires core for logging warnings, but the call site was missing this parameter. Found by TypeScript.
The for-of loop was using an undeclared variable 'line', which would create an implicit global. Add const declaration. Found by TypeScript.
Add missing workflowRunId parameter to all downloadArtifact calls. The @actions/artifact API requires this field in the findBy object. Also fix Date arithmetic by calling .getTime() - TypeScript correctly flags that Date objects can't be subtracted from numbers without explicit conversion. Found by TypeScript.
The postReview function has a default value for event, so the JSDoc type should mark it as optional with ?. Found by TypeScript.
The runChecklist function is intentionally called without user and userIsMaintainer when checking label eligibility (vs actual merging). Add default values to make this explicit. Found by TypeScript.
The bottleneck npm package doesn't have TypeScript type definitions. Add @ts-expect-error comments to suppress the "not constructable" errors while still enabling type checking for the rest of the file.
module.parent has been deprecated since Node.js 14. Use the modern require.main === module pattern instead. Found by TypeScript.
Add a Nix derivation that runs TypeScript type checking on the ci/github-script JavaScript files. This ensures type errors are caught in CI, not just locally. The check is defined in ci/github-script/default.nix and exposed via: - `nix-build ci -A typecheck-ci-scripts` - `typecheck-ci-scripts` command in the development shell (via passthru.driver)
mdaniels5757
left a comment
There was a problem hiding this comment.
This looks great! A couple of minor things:
One issue (which is mostly pre-existing, but made a bit worse here): nodejs is v24 on master (and v24 is used by actions/github-script). But nodejs is v22 on stable, and the @types/node version added in this PR is v22 as well. I think pinning to v24 would be prudent, given that's what is used by actions/github-script.
In addition to the suggestions below, there's one more place to pin nodejs to 24 in: ci/github-script/shell.nix (which is untouched by this PR).
Also in ci/github-script/shell.nix, it would also be nice to add (pkgs.callPackage ./. { }).passthru.driver to packages, so typecheck-ci-scripts can be run directly from the shell without extra nix-shell/nix-build invocations. (The documentation could then be updated accordingly.)
| "commander": "14.0.0" | ||
| }, | ||
| "devDependencies": { | ||
| "@types/node": "^22.0.0", |
There was a problem hiding this comment.
Node 24 is used by the github-script action, and is the current version of nodejs on master.
package-lock.json will also need to be updated, of course.
| "@types/node": "^22.0.0", | |
| "@types/node": "^24.0.0", |
| # Type check the CI scripts in ci/github-script using TypeScript | ||
| { | ||
| importNpmLock, | ||
| nodejs, |
There was a problem hiding this comment.
nodejs on master is v24, but v22 on stable.
| nodejs, | |
| nodejs_24, |
| let | ||
| npmDeps = importNpmLock.buildNodeModules { | ||
| npmRoot = ./.; | ||
| inherit nodejs; |
There was a problem hiding this comment.
| inherit nodejs; | |
| nodejs = nodejs_24; |
| in | ||
| runCommand "typecheck-ci-scripts" | ||
| { | ||
| nativeBuildInputs = [ nodejs ]; |
There was a problem hiding this comment.
| nativeBuildInputs = [ nodejs ]; | |
| nativeBuildInputs = [ nodejs_24 ]; |
| @@ -1,3 +1,3 @@ | |||
| #!/usr/bin/env nix-shell | |||
| /* | |||
| #!nix-shell -i node -p nodejs | |||
There was a problem hiding this comment.
| #!nix-shell -i node -p nodejs_24 |
There was a problem hiding this comment.
Seems like this shebang isn't necessary anymore since it's always imported directly from node
There was a problem hiding this comment.
Yes, I think I should delete this -- but instead of doing the "nix-build to run the tool thing that I have done, instead use nix-shell in the shebang to have the tool be runnable outside of Nix.
| "allowJs": true, | ||
| "noEmit": true, | ||
| "target": "ES2024", | ||
| "lib": ["ESNext"], |
There was a problem hiding this comment.
Per https://github.com/tsconfig/bases/blob/main/bases/node24.json:
| "lib": ["ESNext"], | |
| "lib": [ | |
| "es2024", | |
| "ESNext.Array", | |
| "ESNext.Collection", | |
| "ESNext.Error", | |
| "ESNext.Iterator", | |
| "ESNext.Promise" | |
| ], |
There was a problem hiding this comment.
LGTM and tested (the type checks even work with my neovim), thank you!
I agree with @mdaniels5757 that it would be good to pin this to node 24 (even better would be if GitHub actions would use the node version from Nix, but oh well)
| @@ -1,3 +1,3 @@ | |||
| #!/usr/bin/env nix-shell | |||
| /* | |||
| #!nix-shell -i node -p nodejs | |||
There was a problem hiding this comment.
Seems like this shebang isn't necessary anymore since it's always imported directly from node
|
Thanks for the reviews @infinisil and @mdaniels5757 -- will push an updated version sometime today hopefully. I plan on including a CI step gated on changes to these files so that it actually will mark the CI red if there are errors in typechecking. 🎉 |
Summary
Add TypeScript type checking for
ci/github-script/JavaScript files to catch bugs at development time rather than in production.Motivation
While reviewing PR #456481, I found several bugs that TypeScript's --checkJs mode catches automatically:
Changes
Infrastructure (commit 1):
Bug fixes (commits 2-8):
CI integration (commit 9):
I didn't wire this into any ran-by-CI workflow because I ran out of time. But having it here is a step in that direction.
Testing
Run
nix-build ci -A typecheck-ci-scriptsornix-shell --run typecheck-ci-scripts.Things done
passthru.tests.nixpkgs-reviewon this PR. See nixpkgs-review usage../result/bin/.