Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions ci/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ The goal is to eventually have all GitHub specific code in `ci/github-script` an
A lot of code has already been migrated, but some Bash code still remains.
New CI features need to be introduced in JavaScript, not Bash.

The JavaScript code is type-checked using TypeScript.
Run `nix-build ci -A typecheck-ci-scripts` or use `typecheck-ci-scripts` from the repository's `nix-shell`.
See [`ci/github-script/README.md`](./github-script/README.md) for more details.

## Nixpkgs merge bot

The Nixpkgs merge bot empowers package maintainers by enabling them to merge PRs related to their own packages.
Expand Down
1 change: 1 addition & 0 deletions ci/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ in
rec {
inherit pkgs fmt;
codeownersValidator = pkgs.callPackage ./codeowners-validator { };
typecheck-ci-scripts = pkgs.callPackage ./github-script { };

# FIXME(lf-): it might be useful to test other Nix implementations
# (nixVersions.stable and Lix) here somehow at some point to ensure we don't
Expand Down
24 changes: 24 additions & 0 deletions ci/github-script/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,27 @@ Run `./run commits OWNER REPO PR`, where OWNER is your username or "NixOS", REPO
## Labeler

Run `./run labels OWNER REPO`, where OWNER is your username or "NixOS" and REPO the name of your fork or "nixpkgs".

## Type checking

The JavaScript files are type-checked using TypeScript with `--checkJs`. This catches common bugs like using `Set.length` instead of `Set.size`, undeclared variables, and mismatched function signatures.

To run the type checker from the repository root:

```
nix-build ci -A typecheck-ci-scripts
```

Or use the `typecheck-ci-scripts` command from the repository's development shell:

```
nix-shell --run typecheck-ci-scripts
```

For interactive development, enter `nix-shell` in this directory and run:

```
tsc --project jsconfig.json
```

Editors that support `jsconfig.json` (VS Code, etc.) will show type errors inline.
5 changes: 4 additions & 1 deletion ci/github-script/bot.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ module.exports = async ({ github, context, core, dry }) => {

await artifactClient.downloadArtifact(artifact.id, {
findBy: {
workflowRunId: run.id,
repositoryName: context.repo.repo,
repositoryOwner: context.repo.owner,
token: core.getInput('github-token'),
Expand Down Expand Up @@ -218,7 +219,7 @@ module.exports = async ({ github, context, core, dry }) => {
// This is intentionally less than the time that Eval takes, so that the label job
// running after Eval can indeed label the PR as conflicted if that is the case.
const merge_commit_sha_valid =
Date.now() - new Date(pull_request.created_at) > 3 * 60 * 1000
Date.now() - new Date(pull_request.created_at).getTime() > 3 * 60 * 1000

const prLabels = {
// We intentionally don't use the mergeable or mergeable_state attributes.
Expand Down Expand Up @@ -313,6 +314,7 @@ module.exports = async ({ github, context, core, dry }) => {

await artifactClient.downloadArtifact(artifact.id, {
findBy: {
workflowRunId: run_id,
repositoryName: context.repo.repo,
repositoryOwner: context.repo.owner,
token: core.getInput('github-token'),
Expand Down Expand Up @@ -669,6 +671,7 @@ module.exports = async ({ github, context, core, dry }) => {
artifact.id,
{
findBy: {
workflowRunId: lastRun.id,
repositoryName: context.repo.repo,
repositoryOwner: context.repo.owner,
token: core.getInput('github-token'),
Expand Down
4 changes: 2 additions & 2 deletions ci/github-script/commits.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ module.exports = async ({ github, context, core, dry, cherryPicks }) => {
// An empty results array will always trigger this condition, which is helpful
// to clean up reviews created by the prepare step when on the wrong branch.
if (results.every(({ severity }) => severity === 'info')) {
await dismissReviews({ github, context, dry, reviewKey })
await dismissReviews({ github, context, core, dry, reviewKey })
return
}

Expand Down Expand Up @@ -286,7 +286,7 @@ module.exports = async ({ github, context, core, dry, cherryPicks }) => {
// that's too long. We think this is unlikely to happen, and so don't deal with it explicitly.
const truncated = []
let total_length = 0
for (line of diff) {
for (const line of diff) {
total_length += line.length
if (total_length > 10000) {
truncated.push('', '[...truncated...]')
Expand Down
44 changes: 44 additions & 0 deletions ci/github-script/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Type check the CI scripts in ci/github-script using TypeScript
{
importNpmLock,
nodejs,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nodejs on master is v24, but v22 on stable.

Suggested change
nodejs,
nodejs_24,

runCommand,
writeShellScriptBin,
}:
let
npmDeps = importNpmLock.buildNodeModules {
npmRoot = ./.;
inherit nodejs;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
inherit nodejs;
nodejs = nodejs_24;

};

# Files from ci/ that are referenced by the scripts
parentFiles = {
"supportedBranches.js" = ../supportedBranches.js;
"supportedSystems.json" = ../supportedSystems.json;
};
in
runCommand "typecheck-ci-scripts"
{
nativeBuildInputs = [ nodejs ];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
nativeBuildInputs = [ nodejs ];
nativeBuildInputs = [ nodejs_24 ];

passthru.driver = writeShellScriptBin "typecheck-ci-scripts" ''
nix-build --no-out-link "$@" \
${toString ./..} -A typecheck-ci-scripts
'';
}
''
# Set up directory structure matching the source layout
mkdir -p github-script
cp -r ${./.}/* github-script/
chmod -R u+w github-script
ln -s ${npmDeps}/node_modules github-script/node_modules

# Copy files from ci/ that are referenced by the scripts
${builtins.concatStringsSep "\n" (
builtins.attrValues (builtins.mapAttrs (name: path: "cp ${path} ${name}") parentFiles)
)}

cd github-script
node node_modules/typescript/bin/tsc --project jsconfig.json
echo "typecheck-ci-scripts: ok"
touch $out
''
16 changes: 16 additions & 0 deletions ci/github-script/jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"compilerOptions": {
"checkJs": true,
"allowJs": true,
"noEmit": true,
"target": "ES2024",
"lib": ["ESNext"],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per https://github.com/tsconfig/bases/blob/main/bases/node24.json:

Suggested change
"lib": ["ESNext"],
"lib": [
"es2024",
"ESNext.Array",
"ESNext.Collection",
"ESNext.Error",
"ESNext.Iterator",
"ESNext.Promise"
],

"module": "commonjs",
"moduleResolution": "node",
"resolveJsonModule": true,
"strict": false,
"skipLibCheck": true
},
"include": ["*.js"],
"exclude": ["node_modules"]
}
4 changes: 2 additions & 2 deletions ci/github-script/merge.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ function runChecklist({
pull_request,
log,
maintainers,
user,
userIsMaintainer,
user = null,
userIsMaintainer = false,
}) {
const allByName = files.every(
({ filename }) =>
Expand Down
45 changes: 41 additions & 4 deletions ci/github-script/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions ci/github-script/package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
{
"private": true,
"scripts": {
"typecheck": "tsc --project jsconfig.json"
},
"dependencies": {
"@actions/artifact": "2.3.2",
"@actions/core": "1.11.1",
"@actions/github": "6.0.1",
"bottleneck": "2.19.5",
"commander": "14.0.0"
},
"devDependencies": {
"@types/node": "^22.0.0",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
"@types/node": "^22.0.0",
"@types/node": "^24.0.0",

"typescript": "^5.7.0"
}
}
2 changes: 1 addition & 1 deletion ci/github-script/reviews.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ async function dismissReviews({ github, context, core, dry, reviewKey }) {
* core: import('@actions/core'),
* dry: boolean,
* body: string,
* event: keyof eventToState,
* event?: keyof eventToState,
* reviewKey: string,
* }} PostReviewProps
*/
Expand Down
2 changes: 2 additions & 0 deletions ci/github-script/withRateLimit.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ module.exports = async ({ github, core, maxConcurrent = 1 }, callback) => {
// Rate-Limiting and Throttling, see for details:
// https://github.com/octokit/octokit.js/issues/1069#throttling
// https://docs.github.com/en/rest/using-the-rest-api/best-practices-for-using-the-rest-api
// @ts-expect-error bottleneck lacks TypeScript types
const allLimits = new Bottleneck({
// Avoid concurrent requests
maxConcurrent,
// Will be updated with first `updateReservoir()` call below.
reservoir: 0,
})
// Pause between mutative requests
// @ts-expect-error bottleneck lacks TypeScript types
const writeLimits = new Bottleneck({ minTime: 1000 }).chain(allLimits)
github.hook.wrap('request', async (request, options) => {
// Requests to a different host do not count against the rate limit.
Expand Down
2 changes: 1 addition & 1 deletion ci/supportedBranches.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ function classify(branch) {
module.exports = { classify, split }

// If called directly via CLI, runs the following tests:
if (!module.parent) {
if (require.main === module) {
console.log('split(branch)')
function testSplit(branch) {
console.log(branch, split(branch))
Expand Down
10 changes: 6 additions & 4 deletions shell.nix
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
nixpkgs ? null,
}:
let
inherit (import ./ci { inherit nixpkgs system; }) pkgs fmt;
inherit (import ./ci { inherit nixpkgs system; }) pkgs fmt typecheck-ci-scripts;

# For `nix-shell -A hello`
curPkgs = removeAttrs (import ./. { inherit system; }) [
Expand All @@ -31,12 +31,14 @@ curPkgs
inputsFrom = [
fmt.shell
];
packages = with pkgs; [
packages = [
# Helper to review Nixpkgs PRs
# See CONTRIBUTING.md
nixpkgs-reviewFull
pkgs.nixpkgs-reviewFull
# Command-line utility for working with GitHub
# Used by nixpkgs-review to fetch eval results
gh
pkgs.gh
# Type check CI scripts
typecheck-ci-scripts.passthru.driver
];
}
Loading