Skip to content

Commit 4a670bf

Browse files
authored
chore: run bencher on PR or fork (#390)
# Summary - Runs bencher on PR's as per instructions at https://bencher.dev/docs/how-to/github-actions/
1 parent 3a67991 commit 4a670bf

File tree

6 files changed

+153
-19
lines changed

6 files changed

+153
-19
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: Run benchmarks on PR
2+
3+
on:
4+
pull_request:
5+
types: [opened, reopened, edited, synchronize]
6+
7+
jobs:
8+
benchmark_fork_pr_branch:
9+
name: Run Fork PR Benchmarks
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v4
13+
- name: Rust Cache
14+
uses: Swatinem/[email protected]
15+
with:
16+
# reasoning: we want to cache xtask, most of the jobs in the matrix will be sped up a good bit thanks to that
17+
save-if: ${{ github.ref == 'refs/heads/main' }}
18+
cache-all-crates: true
19+
- name: Run `cargo xtask init`
20+
run: |
21+
cargo xtask init
22+
- name: Run `cargo xtask bench` and save results
23+
run: |
24+
cargo xtask bench > benchmark_results.txt
25+
- name: Upload Benchmark Results
26+
uses: actions/upload-artifact@v4
27+
with:
28+
name: benchmark_results.txt
29+
path: ./benchmark_results.txt
30+
- name: Upload GitHub Pull Request Event
31+
uses: actions/upload-artifact@v4
32+
with:
33+
name: event.json
34+
path: ${{ github.event_path }}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
on:
2+
pull_request_target:
3+
types: [closed]
4+
5+
jobs:
6+
archive_fork_pr_branch:
7+
name: Archive closed fork PR branch with Bencher
8+
runs-on: ubuntu-latest
9+
steps:
10+
- uses: actions/checkout@v4
11+
- uses: bencherdev/bencher@main
12+
- name: Archive closed fork PR branch with Bencher
13+
run: |
14+
bencher archive \
15+
--project bms \
16+
--token '${{ secrets.BENCHER_API_TOKEN }}' \
17+
--branch "$GITHUB_HEAD_REF"
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: Upload benchmarks to bencher
2+
3+
on:
4+
workflow_run:
5+
workflows: [Run benchmarks on PR]
6+
types: [completed]
7+
8+
jobs:
9+
track_fork_pr_branch:
10+
if: github.event.workflow_run.conclusion == 'success'
11+
runs-on: ubuntu-latest
12+
env:
13+
BENCHMARK_RESULTS: benchmark_results.txt
14+
PR_EVENT: event.json
15+
steps:
16+
- name: Download Benchmark Results
17+
uses: dawidd6/action-download-artifact@v6
18+
with:
19+
name: ${{ env.BENCHMARK_RESULTS }}
20+
run_id: ${{ github.event.workflow_run.id }}
21+
- name: Download PR Event
22+
uses: dawidd6/action-download-artifact@v6
23+
with:
24+
name: ${{ env.PR_EVENT }}
25+
run_id: ${{ github.event.workflow_run.id }}
26+
- name: Export PR Event Data
27+
uses: actions/github-script@v6
28+
with:
29+
script: |
30+
let fs = require('fs');
31+
let prEvent = JSON.parse(fs.readFileSync(process.env.PR_EVENT, {encoding: 'utf8'}));
32+
core.exportVariable("PR_HEAD", prEvent.pull_request.head.ref);
33+
core.exportVariable("PR_BASE", prEvent.pull_request.base.ref);
34+
core.exportVariable("PR_BASE_SHA", prEvent.pull_request.base.sha);
35+
core.exportVariable("PR_NUMBER", prEvent.number);
36+
- uses: bencherdev/bencher@main
37+
- name: Track Benchmarks with Bencher
38+
run: |
39+
bencher run \
40+
--project bms \
41+
--token '${{ secrets.BENCHER_API_TOKEN }}' \
42+
--branch "$PR_HEAD" \
43+
--start-point "$PR_BASE" \
44+
--start-point-hash "$PR_BASE_SHA" \
45+
--start-point-clone-thresholds \
46+
--start-point-reset \
47+
--testbed linux-gha \
48+
--err \
49+
--adapter rust_criterion \
50+
--github-actions '${{ secrets.GITHUB_TOKEN }}' \
51+
--ci-number "$PR_NUMBER" \
52+
--file "$BENCHMARK_RESULTS"

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ include = ["readme.md", "/src", "/examples", "/assets", "LICENSE", "/badges"]
1515
[lib]
1616
name = "bevy_mod_scripting"
1717
path = "src/lib.rs"
18+
bench = false
1819

1920
[package.metadata."docs.rs"]
2021
features = ["lua54", "rhai"]

benches/benchmarks.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
use std::path::PathBuf;
1+
use std::{path::PathBuf, time::Duration};
22

33
use bevy::utils::HashMap;
4-
use criterion::{
5-
criterion_group, criterion_main, measurement::Measurement, BenchmarkGroup, Criterion,
6-
};
4+
use criterion::{criterion_main, measurement::Measurement, BenchmarkGroup, Criterion};
75
use script_integration_test_harness::{run_lua_benchmark, run_rhai_benchmark};
86
use test_utils::{discover_all_tests, Test};
97

@@ -91,5 +89,10 @@ fn script_benchmarks(criterion: &mut Criterion) {
9189
}
9290
}
9391

94-
criterion_group!(benches, script_benchmarks);
92+
pub fn benches() {
93+
let mut criterion: criterion::Criterion<_> = (criterion::Criterion::default())
94+
.configure_from_args()
95+
.measurement_time(Duration::from_secs(10));
96+
script_benchmarks(&mut criterion);
97+
}
9598
criterion_main!(benches);

crates/xtask/src/main.rs

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::{
99
ffi::{OsStr, OsString},
1010
io::Write,
1111
path::{Path, PathBuf},
12-
process::Command,
12+
process::{Command, Output},
1313
str::FromStr,
1414
};
1515
use strum::{IntoEnumIterator, VariantNames};
@@ -349,13 +349,16 @@ impl App {
349349
Xtasks::Install { binary } => {
350350
cmd.arg("install").arg(binary.as_ref());
351351
}
352-
Xtasks::Bench { publish } => {
353-
cmd.arg("bench");
352+
Xtasks::Bencher { publish } => {
353+
cmd.arg("bencher");
354354

355355
if publish {
356356
cmd.arg("--publish");
357357
}
358358
}
359+
Xtasks::Bench {} => {
360+
cmd.arg("bench");
361+
}
359362
}
360363

361364
cmd
@@ -643,11 +646,13 @@ enum Xtasks {
643646
CiMatrix,
644647
/// Runs bencher in dry mode by default if not on the main branch
645648
/// To publish main branch defaults set publish mode to true
646-
Bench {
649+
Bencher {
647650
/// Publish the benchmarks when on main
648651
#[clap(long, default_value = "false", help = "Publish the benchmarks")]
649652
publish: bool,
650653
},
654+
/// Runs criterion benchmarks generates json required to be published by bencher and generates html performance report
655+
Bench {},
651656
}
652657

653658
#[derive(Serialize, Clone)]
@@ -691,8 +696,10 @@ impl Xtasks {
691696
let mut rows = Vec::default();
692697
for os in <CiOs as strum::VariantArray>::VARIANTS {
693698
for row in output.iter() {
694-
let step_should_run_on_main_os =
695-
matches!(row.subcmd, Xtasks::Build | Xtasks::Docs { .. });
699+
let step_should_run_on_main_os = matches!(
700+
row.subcmd,
701+
Xtasks::Build | Xtasks::Docs { .. } | Xtasks::Bencher { .. }
702+
);
696703
let is_coverage_step = row.global_args.coverage;
697704

698705
if !os.is_main_os() && step_should_run_on_main_os {
@@ -723,7 +730,8 @@ impl Xtasks {
723730
bevy_features,
724731
} => Self::codegen(app_settings, output_dir, bevy_features),
725732
Xtasks::Install { binary } => Self::install(app_settings, binary),
726-
Xtasks::Bench { publish: execute } => Self::bench(app_settings, execute),
733+
Xtasks::Bencher { publish } => Self::bencher(app_settings, publish),
734+
Xtasks::Bench {} => Self::bench(app_settings),
727735
}?;
728736

729737
Ok("".into())
@@ -811,7 +819,7 @@ impl Xtasks {
811819
context: &str,
812820
add_args: I,
813821
dir: Option<&Path>,
814-
) -> Result<()> {
822+
) -> Result<Output> {
815823
let coverage_mode = app_settings
816824
.coverage
817825
.then_some("with coverage")
@@ -878,7 +886,7 @@ impl Xtasks {
878886

879887
let output = cmd.output().with_context(|| context.to_owned())?;
880888
match output.status.code() {
881-
Some(0) => Ok(()),
889+
Some(0) => Ok(output),
882890
_ => bail!(
883891
"{} failed with exit code: {}. Features: {}",
884892
context,
@@ -1223,7 +1231,26 @@ impl Xtasks {
12231231
Ok(())
12241232
}
12251233

1226-
fn bench(app_settings: GlobalArgs, execute: bool) -> Result<()> {
1234+
fn bench(app_settings: GlobalArgs) -> Result<()> {
1235+
Self::run_workspace_command(
1236+
// run with just lua54
1237+
&app_settings.with_features(Features::new(vec![
1238+
Feature::Lua54,
1239+
Feature::Rhai,
1240+
Feature::CoreFunctions,
1241+
Feature::BevyBindings,
1242+
])),
1243+
"bench",
1244+
"Failed to run benchmarks",
1245+
Vec::<String>::default(),
1246+
None,
1247+
)
1248+
.with_context(|| "when executing criterion benchmarks")?;
1249+
1250+
Ok(())
1251+
}
1252+
1253+
fn bencher(app_settings: GlobalArgs, publish: bool) -> Result<()> {
12271254
// // first of all figure out which branch we're on
12281255
// // run // git rev-parse --abbrev-ref HEAD
12291256
let workspace_dir = Self::workspace_dir(&app_settings).unwrap();
@@ -1277,13 +1304,13 @@ impl Xtasks {
12771304
bencher_cmd.args(["--github-actions", token]);
12781305
}
12791306

1280-
if !is_main || !execute {
1307+
if !is_main || !publish {
12811308
bencher_cmd.args(["--dry-run"]);
12821309
}
12831310

12841311
bencher_cmd
12851312
.args(["--adapter", "rust_criterion"])
1286-
.arg("cargo bench --features=lua54");
1313+
.arg("cargo xtask bench");
12871314

12881315
log::info!("Running bencher command: {:?}", bencher_cmd);
12891316

@@ -1295,7 +1322,7 @@ impl Xtasks {
12951322
}
12961323

12971324
// if we're on linux and publishing and on main synch graphs
1298-
if os == "linux" && is_main && execute && github_token.is_some() {
1325+
if os == "linux" && is_main && publish && github_token.is_some() {
12991326
Self::synch_bencher_graphs()?;
13001327
}
13011328

@@ -1625,7 +1652,7 @@ impl Xtasks {
16251652
// on non-main branches this will just dry run
16261653
output.push(App {
16271654
global_args: default_args.clone(),
1628-
subcmd: Xtasks::Bench { publish: true },
1655+
subcmd: Xtasks::Bencher { publish: true },
16291656
});
16301657

16311658
// and finally run tests with coverage

0 commit comments

Comments
 (0)