From 69afdd8aaae6e18fbbd4f7c89d51e9be294ebd37 Mon Sep 17 00:00:00 2001 From: Jad Dayoub Date: Tue, 18 Aug 2026 12:50:48 +0200 Subject: [PATCH 1/4] Add target to run JSROOT tests for different .root files --- Makefile | 6 ++++++ README.md | 2 ++ 2 files changed, 8 insertions(+) diff --git a/Makefile b/Makefile index d33c119..1ed4730 100644 --- a/Makefile +++ b/Makefile @@ -64,6 +64,12 @@ $(READ_DIR_JSROOT): check: @test -x "$(ROOT_EXE)" || { echo "Could not find root.exe"; exit 1; } +.PHONY: validate_jsroot +validate_jsroot: + @for w_dir in write/*; do \ + $(MAKE) read_jsroot write_dir=$$(basename "$$w_dir"); \ + done + .PHONY: validate validate: @if [ "$(source_scripts)" = "" ]; then\ diff --git a/README.md b/README.md index 908d402..98e5266 100644 --- a/README.md +++ b/README.md @@ -84,3 +84,5 @@ npm install jsroot Run `make read_jsroot` to read the generated `.root` files with [JSROOT](https://github.com/root-project/jsroot), a JavaScript library that is capable of reading ROOT files. The supported tests are inside `jsroot`. The resulting `.json` files are stored inside `read/jsroot`. Run `make write` first to create the `.root` files using the ROOT macros! + +Run `make validate_jsroot` to read the `.root` files for each subdir in `write/` and store them in subdirs in `read//jsroot`. From 4bc5cdad0e8a2223fa3f4a57fed877a53e441b10 Mon Sep 17 00:00:00 2001 From: Jad Dayoub Date: Tue, 18 Aug 2026 12:57:10 +0200 Subject: [PATCH 2/4] Add workflow job for JSROOT in CI --- .github/workflows/root.yml | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/.github/workflows/root.yml b/.github/workflows/root.yml index 4fdbc70..f604ae5 100644 --- a/.github/workflows/root.yml +++ b/.github/workflows/root.yml @@ -1,4 +1,4 @@ -name: Execute ROOT macros +name: Run Cross-Validation on: schedule: - cron: '17 2 * * 1' # every monday at 02:17 UTC @@ -17,6 +17,11 @@ on: description: 'Run latest LCG nightly build' type: boolean default: false + jsroot_version: + description: 'JSROOT Version (leave empty to not run tests)' + required: false + default: '7.11.1' + type: string jobs: cross-validation: @@ -28,6 +33,8 @@ jobs: # run LCG releases 108, 109 and 110 for each schedules, and 110 for each PR/push VERSIONS: ${{ inputs.versions || (github.event_name == 'schedule' && '108,109,110' || '110') }} RUN_DEV3: ${{ inputs.run_dev3 == true || github.event_name == 'schedule' }} + JSROOT_SETUP: /cvmfs/sft.cern.ch/lcg/views/LCG_110/x86_64-el9-gcc13-opt/setup.sh + JSROOT_VERSION: ${{ inputs.jsroot_version || '~7.11.0' }} # use JSROOT version 7.11.x with newest patch version container: image: gitlab-registry.cern.ch/sft/docker/alma9-core:latest @@ -59,7 +66,14 @@ jobs: fi eval "SCRIPTS=(/cvmfs/sft.cern.ch/lcg/views/$PATTERN/x86_64-el9-gcc13-opt/setup.sh)" make -j$(nproc) validate source_scripts="${SCRIPTS[*]}" - shell: bash + shell: bash + + - name: Run JSROOT tests + if: ${{ env.JSROOT_VERSION != '' }} + run: | + source "$JSROOT_SETUP" + npm install "jsroot@$JSROOT_VERSION" + make -j$(nproc) validate_jsroot - name: Create HTML run: make export_html From 3248debbda5a814670bf3ee383f48e9c3e2152a9 Mon Sep 17 00:00:00 2001 From: Jad Dayoub Date: Wed, 19 Aug 2026 10:57:52 +0200 Subject: [PATCH 3/4] Skip JSROOT tests if version is too low List of skipped tests: - structure/empty - structure/cluster_groups - types/fundamental/integer - types/fundamental/real32quant --- jsroot/jsroot_reader.mjs | 13 ++++++++++++- jsroot/structure/cluster_groups/read.mjs | 7 ++++++- jsroot/structure/empty/read.mjs | 7 ++++++- jsroot/types/fundamental/integer/read.mjs | 10 +++++----- jsroot/types/fundamental/real32quant/read.mjs | 7 ++++++- 5 files changed, 35 insertions(+), 9 deletions(-) diff --git a/jsroot/jsroot_reader.mjs b/jsroot/jsroot_reader.mjs index b995541..29e8bf0 100644 --- a/jsroot/jsroot_reader.mjs +++ b/jsroot/jsroot_reader.mjs @@ -1,5 +1,5 @@ import { writeFileSync, mkdirSync, existsSync } from "fs"; -import { openFile, TSelector } from "jsroot"; +import { openFile, TSelector, version } from "jsroot"; import { rntupleProcess } from "jsroot/rntuple"; /** @@ -133,3 +133,14 @@ export function pairArrayToMap(arr) { ]), ); } + +// check if current version is newer than target +export function isNewer(target) { + const [major, minor, patch] = version.split(" ")[0].split(".").map(Number); + const [tMajor, tMinor, tPatch] = target.split(".").map(Number); + return ( + major > tMajor || + (major === tMajor && minor > tMinor) || + (major === tMajor && minor === tMinor && patch > tPatch) + ); +} diff --git a/jsroot/structure/cluster_groups/read.mjs b/jsroot/structure/cluster_groups/read.mjs index 33b1f85..8ffe88a 100644 --- a/jsroot/structure/cluster_groups/read.mjs +++ b/jsroot/structure/cluster_groups/read.mjs @@ -1,4 +1,9 @@ -import { read } from "../../jsroot_reader.mjs"; +import { read, isNewer } from "../../jsroot_reader.mjs"; + +if (!isNewer("7.11.1")) { + console.log(" -> Skipped structure/cluster_groups: version too low") + process.exit(); +} const fields = [ "Int32", diff --git a/jsroot/structure/empty/read.mjs b/jsroot/structure/empty/read.mjs index 6ec4680..38b14ce 100644 --- a/jsroot/structure/empty/read.mjs +++ b/jsroot/structure/empty/read.mjs @@ -1,4 +1,9 @@ -import { read } from "../../jsroot_reader.mjs"; +import { read, isNewer } from "../../jsroot_reader.mjs"; + +if (!isNewer("7.11.1")) { + console.log(" -> Skipped structure/empty: version too low") + process.exit(); +} const fields = ["Int32"]; diff --git a/jsroot/types/fundamental/integer/read.mjs b/jsroot/types/fundamental/integer/read.mjs index 0385caa..fd0ea50 100644 --- a/jsroot/types/fundamental/integer/read.mjs +++ b/jsroot/types/fundamental/integer/read.mjs @@ -1,9 +1,9 @@ -import { read } from "../../../jsroot_reader.mjs"; +import { read, isNewer } from "../../../jsroot_reader.mjs"; -/* -The following change in rntuple.mjs was necessary to make this test run: -1. line 910 & 919: remove Number() to avoid rounding of BigInt values -*/ +if (!isNewer("7.11.1")) { + console.log(" -> Skipped types/fundamental/integer: version too low") + process.exit(); +} function checkBigInt(value, { marker }) { const res = typeof value === "bigint" ? `${marker}${value}${marker}` : value; diff --git a/jsroot/types/fundamental/real32quant/read.mjs b/jsroot/types/fundamental/real32quant/read.mjs index 0d23ad9..631fa1c 100644 --- a/jsroot/types/fundamental/real32quant/read.mjs +++ b/jsroot/types/fundamental/real32quant/read.mjs @@ -1,4 +1,9 @@ -import { read, floatToHex } from "../../../jsroot_reader.mjs"; +import { read, floatToHex, isNewer } from "../../../jsroot_reader.mjs"; + +if (!isNewer("7.11.1")) { + console.log(" -> Skipped types/fundamental/real32quant: version too low") + process.exit(); +} function formatFloat(num, { field }) { // round num to single-precision float to match the required field precision From ca00c7546e931b37087280f4404cc70136c30d3c Mon Sep 17 00:00:00 2001 From: Jad Dayoub Date: Tue, 25 Aug 2026 11:13:13 +0200 Subject: [PATCH 4/4] Prevent CI to run on forks --- .github/workflows/root.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/root.yml b/.github/workflows/root.yml index f604ae5..3841f1e 100644 --- a/.github/workflows/root.yml +++ b/.github/workflows/root.yml @@ -25,6 +25,7 @@ on: jobs: cross-validation: + if: github.repository_owner == 'root-project' || github.event_name == 'pull_request' name: Cross Validation runs-on: labels: [self-hosted]