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
112 changes: 112 additions & 0 deletions components/git/benchmark.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import auth from '../../lib/auth.js';
import { parsePRFromURL } from '../../lib/links.js';
import CLI from '../../lib/cli.js';
import Request from '../../lib/request.js';
import { runPromise } from '../../lib/run.js';
import BenchmarkSession from '../../lib/benchmark.js';

export const command = 'benchmark <identifier>';
export const describe =
'Trigger the benchmark GitHub Actions workflow for a pull request';

const options = {
owner: {
alias: 'o',
describe: 'GitHub owner of the PR repository',
default: 'nodejs',
type: 'string'
},
repo: {
alias: 'r',
describe: 'GitHub repository of the PR',
default: 'node',
type: 'string'
},
'workflow-owner': {
describe: 'GitHub owner of the repository hosting the benchmark workflow ' +
'(defaults to the PR owner)',
type: 'string'
},
'workflow-repo': {
describe: 'GitHub repository hosting the benchmark workflow ' +
'(defaults to the PR repository)',
type: 'string'
},
workflow: {
describe: 'The workflow file to dispatch',
default: 'benchmark.yml',
type: 'string'
},
ref: {
describe: 'The git ref of the workflow repository to run the workflow from',
default: 'main',
type: 'string'
},
runs: {
describe: 'How many times to repeat each benchmark',
type: 'number'
}
};

let yargsInstance;

export function builder(yargs) {
yargsInstance = yargs;
return yargs
.options(options)
.positional('identifier', {
type: 'string',
describe: 'ID or URL of the pull request. A commit URL ' +
'(…/pull/<id>/commits/<sha>) benchmarks that commit instead of the ' +
'PR head.'
})
.example('git node benchmark 12344',
'Pick benchmark categories to run on ' +
'https://github.com/nodejs/node/pull/12344')
.example('git node benchmark https://github.com/nodejs/node/pull/12344',
'Pick benchmark categories to run on ' +
'https://github.com/nodejs/node/pull/12344')
.example(
'git node benchmark ' +
'https://github.com/nodejs/node/pull/12344/commits/abc1234',
'Benchmark commit abc1234 rather than the current PR head')
.wrap(90);
}

const COMMIT_URL_RE = /\/pull\/\d+\/commits\/([0-9a-f]{7,40})/i;

// Parse the positional identifier into { prid, owner?, repo?, commit? }.
// A PR commit URL (…/pull/<id>/commits/<sha>) also yields the commit SHA.
export function parseIdentifier(identifier) {
const prid = Number.parseInt(identifier);
if (!Number.isNaN(prid)) {
return { prid };
}
const parsed = parsePRFromURL(identifier);
if (!parsed) {
return undefined;
}
const commit = COMMIT_URL_RE.exec(identifier);
if (commit) {
parsed.commit = commit[1];
}
return parsed;
}

export function handler(argv) {
const parsed = parseIdentifier(argv.identifier);
if (!parsed) {
return yargsInstance.showHelp();
}
Object.assign(argv, parsed);

return runPromise(main(argv));
}

async function main(argv) {
const cli = new CLI(process.stderr);
const credentials = await auth({ github: true });
const request = new Request(credentials);
const session = new BenchmarkSession(cli, request, argv);
return session.start();
}
66 changes: 65 additions & 1 deletion docs/git-node.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ A custom Git command for managing pull requests. You can run it as
- [Usage](#usage)
- [`git node status`](#git-node-status)
- [Example](#example-2)
- [`git node wpt`](#git-node-wpt)
- [`git node benchmark`](#git-node-benchmark)
- [Example](#example-3)
- [`git node wpt`](#git-node-wpt)
- [Example](#example-4)

## `git node land`

Expand Down Expand Up @@ -568,6 +570,66 @@ Upstream: upstream
Branch: main
```

## `git node benchmark`

Trigger the [`benchmark.yml`][] GitHub Actions workflow on a pull request. The
command fetches the PR, then prompts you to pick which benchmark categories to
run (the folders in [`benchmark/`][] at the PR head). Categories whose files are
touched by the PR are checked by default; if the PR touches no benchmark file,
the pre-selection is guessed from the PR's subsystem labels. You are then prompted for an optional
filter substring; if the PR touches a single benchmark file and only that file's
category is selected, the filter is pre-filled with that file's name. Finally you
are asked whether the workflow should post the results as a comment on the PR. It
then dispatches the workflow with the PR number and its head commit.

```
git-node benchmark <identifier>

Trigger the benchmark GitHub Actions workflow for a pull request

Positionals:
identifier ID or URL of the pull request; a commit URL
(…/pull/<id>/commits/<sha>) benchmarks that commit [string] [required]

Options:
--version Show version number [boolean]
--help Show help [boolean]
--owner, -o GitHub owner of the PR repository [string] [default: "nodejs"]
--repo, -r GitHub repository of the PR [string] [default: "node"]
--workflow-owner GitHub owner of the repository hosting the benchmark workflow
(defaults to the PR owner) [string]
--workflow-repo GitHub repository hosting the benchmark workflow (defaults to the PR
repository) [string]
--workflow The workflow file to dispatch [string] [default: "benchmark.yml"]
--ref The git ref of the workflow repository to run the workflow from
[string] [default: "main"]
--runs How many times to repeat each benchmark [number]
```

The workflow is dispatched on the PR's repository by default. When the workflow
lives in a different repository (for example a fork that hosts `benchmark.yml`),
pass `--workflow-owner`/`--workflow-repo`, and the PR repository is forwarded to
the workflow so it fetches the PR from the right place.

### Example

```bash
# Interactively pick benchmark categories to run on nodejs/node#12344
# (categories touched by the PR are pre-selected)
$ git node benchmark 12344
# is equivalent to
$ git node benchmark https://github.com/nodejs/node/pull/12344

# Repeat each benchmark 10 times (the filter is asked interactively)
$ git node benchmark 12344 --runs 10

# Dispatch the workflow hosted on a fork for a nodejs/node PR
$ git node benchmark 12344 --workflow-owner my-user --workflow-repo node

# Benchmark a specific PR commit instead of the current PR head
$ git node benchmark https://github.com/nodejs/node/pull/12344/commits/abc1234
```

## `git node wpt`

Update or patch the Web Platform Tests in core.
Expand Down Expand Up @@ -603,3 +665,5 @@ $ git node wpt url --commit=43feb7f612fe9160639e09a47933a29834904d69

[node.js abi version registry]: https://github.com/nodejs/node/blob/main/doc/abi_version_registry.json
[Security Release Process]: https://github.com/nodejs/node/blob/main/doc/contributing/security-release-process.md
[`benchmark.yml`]: https://github.com/nodejs/node/blob/main/.github/workflows/benchmark.yml
[`benchmark/`]: https://github.com/nodejs/node/tree/main/benchmark
Loading
Loading