Skip to content

Perf

Perf #3368

Workflow file for this run

name: ES-Actions
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
workflow_dispatch:
env:
RUNNER: tools/run-tests.py
jobs:
check-tidy:
runs-on: ubuntu-24.04
steps:
# No submodules needed here -- this job only runs clang-format/clang-tidy
# over src/, it never builds the engine or runs a test suite. (Previously
# fetched all 9 -- test262 alone is a multi-hundred-MB clone -- for nothing.)
- uses: Wandalen/wretry.action@v3
with:
action: actions/checkout@v5
attempt_limit: 3
attempt_delay: 10000
- name: Install Packages
run: |
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -
sudo add-apt-repository "deb [trusted=yes] http://apt.llvm.org/noble/ llvm-toolchain-noble-20 main"
sudo apt-get update
sudo apt-get install -y clang-format-20
- name: Test
run: tools/check_tidy.py
build-on-macos:
runs-on: macos-15
steps:
- uses: Wandalen/wretry.action@v3
with:
action: actions/checkout@v5
attempt_limit: 3
attempt_delay: 10000
# Only the submodules this job's build (GCutil, Walrus for -DESCARGOT_WASM=ON)
# and test runs (new-es -> vendortest, octane) actually touch.
- name: Init required submodules
run: |
for i in 1 2 3; do
git submodule update --init --recursive -- third_party/GCutil third_party/walrus test/vendortest test/octane && break
echo "submodule update failed (attempt $i/3), retrying in 10s..." >&2
sleep 10
done
- name: Install Packages
run: |
brew update
brew install ninja icu4c
- name: Build x64
env:
BUILD_OPTIONS: -DESCARGOT_WASM=ON -DESCARGOT_TEMPORAL=ON -DESCARGOT_TCO=ON -DESCARGOT_TEST=ON -DESCARGOT_SHADOWREALM=ON -DENABLE_SHELL=ON -GNinja
run: |
# check cpu
sysctl -a | grep machdep.cpu
# add icu path to pkg_config_path
export PKG_CONFIG_PATH="$(brew --prefix icu4c)/lib/pkgconfig"
echo $PKG_CONFIG_PATH
cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.10 -H. -Bout/debug/ -DCMAKE_BUILD_TYPE=Debug $BUILD_OPTIONS
ninja -Cout/debug/
$RUNNER --engine="./out/debug/escargot" new-es
cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.10 -H. -Bout/release/ -DCMAKE_BUILD_TYPE=Release $BUILD_OPTIONS
ninja -Cout/release/
cp test/octane/*.js .
./out/release/escargot run.js
build-on-macos-arm64:
runs-on: macos-latest
steps:
- uses: Wandalen/wretry.action@v3
with:
action: actions/checkout@v5
attempt_limit: 3
attempt_delay: 10000
# Same submodule set as build-on-macos above (same build + test commands).
- name: Init required submodules
run: |
for i in 1 2 3; do
git submodule update --init --recursive -- third_party/GCutil third_party/walrus test/vendortest test/octane && break
echo "submodule update failed (attempt $i/3), retrying in 10s..." >&2
sleep 10
done
- name: Install Packages
run: |
brew update
brew install ninja icu4c
- name: Build arm64
env:
BUILD_OPTIONS: -DESCARGOT_WASM=ON -DESCARGOT_TEMPORAL=ON -DESCARGOT_TCO=ON -DESCARGOT_TEST=ON -DESCARGOT_SHADOWREALM=ON -DENABLE_SHELL=ON -GNinja
run: |
# check cpu
sysctl -a | grep machdep.cpu
# add icu path to pkg_config_path
export PKG_CONFIG_PATH="$(brew --prefix icu4c)/lib/pkgconfig"
echo $PKG_CONFIG_PATH
cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.10 -H. -Bout/debug/ -DCMAKE_BUILD_TYPE=Debug $BUILD_OPTIONS
ninja -Cout/debug/
$RUNNER --engine="./out/debug/escargot" new-es
cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.10 -H. -Bout/release/ -DCMAKE_BUILD_TYPE=Release $BUILD_OPTIONS
ninja -Cout/release/
cp test/octane/*.js .
./out/release/escargot run.js
# -DESCARGOT_TEST_ABI=<cpu-abi>,<device-abi> (build/android/escargot/
# build.gradle) restricts each matrix leg's native build to its own tested
# emulator ABI paired with the real-device ABI in the same word size
# (x86+armeabi-v7a, x86_64+arm64-v8a), instead of unconditionally compiling
# all four abiFilters on every leg as before -- 8 native builds down to 4,
# while still compile-verifying armeabi-v7a/arm64-v8a (never installable on
# a hosted emulator, see the comment below) as their own signal instead of
# only ever building them incidentally.
build-test-on-android:
# Real arm64 ABI is not achievable on any GitHub-hosted runner right now:
# hosted arm64 Linux exposes no /dev/kvm at all, and Apple Silicon hosted
# macOS fails "HVF error: HV_UNSUPPORTED" even after ad-hoc codesigning
# the qemu binary with the com.apple.security.hypervisor entitlement
# (confirmed by actually running it -- codesign applied cleanly, HVF
# init still failed) -- an infra-level nested-virt restriction on that
# runner class, not an entitlement/signing problem. See
# https://github.com/ReactiveCircus/android-emulator-runner/issues/350
# and https://github.com/actions/runner-images/issues/9472 (both
# unresolved upstream, no known fix). Back to x86/x86_64 on
# ubuntu-latest, a known-working KVM-accelerated fast stand-in for real
# (arm) devices -- don't retry the macOS route without a fix landing in
# one of those two upstream issues first.
runs-on: ubuntu-latest
strategy:
matrix:
include:
- arch: x86
device_abi: armeabi-v7a
api: 28
- arch: x86_64
device_abi: arm64-v8a
api: 28
steps:
- uses: Wandalen/wretry.action@v3
with:
action: actions/checkout@v5
attempt_limit: 3
attempt_delay: 10000
# This job builds via the Android CMakeLists (GCutil only) and runs no
# submodule-backed test suite (its instrumented test lives in-tree under
# build/android/).
- name: Init required submodules
run: |
for i in 1 2 3; do
git submodule update --init -- third_party/GCutil && break
echo "submodule update failed (attempt $i/3), retrying in 10s..." >&2
sleep 10
done
- name: Enable KVM
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- name: Set up JDK
uses: actions/setup-java@v4.1.0
with:
distribution: "zulu"
java-version: 17
- name: Gradle cache
uses: gradle/actions/setup-gradle@v3
- name: Create AVD and run tests
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: ${{ matrix.api }}
arch: ${{ matrix.arch }}
force-avd-creation: false
emulator-options: -no-window -gpu swiftshader_indirect -camera-back none -no-snapshot-save -gpu swiftshader_indirect -noaudio -no-boot-anim
disable-animations: true
script: cd build/android/;./gradlew connectedDebugAndroidTest -DESCARGOT_TEST_ABI=${{ matrix.arch }},${{ matrix.device_abi }}
build-test-tizen:
runs-on: ubuntu-24.04
steps:
- uses: Wandalen/wretry.action@v3
with:
action: actions/checkout@v5
attempt_limit: 3
attempt_delay: 10000
# gbs builds via packaging/escargot.spec, which only needs GCutil -- no
# test suite runs in this job.
- name: Init required submodules
run: |
for i in 1 2 3; do
git submodule update --init --recursive -- third_party/GCutil && break
echo "submodule update failed (attempt $i/3), retrying in 10s..." >&2
sleep 10
done
- name: prepare deb sources for GBS
run: echo "deb [trusted=yes] http://download.tizen.org/tools/latest-release/Ubuntu_24.04/ /" | sudo tee /etc/apt/sources.list.d/tizen.list
- name: install GBS
run: sudo apt-get update && sudo apt-get install -y gbs
- name: build
run: |
gbs -c .github/workflows/gbs.conf build -A armv7l -P profile.tizen --incremental --define "enable_shell 1"
test-on-windows-clang-cl:
runs-on: windows-2022
strategy:
matrix:
# clang-cl with cannot generate c++ exception code well
# if clang-cl bug fixed, we can add x64
# clang version and STL version are sometimes not matched in github actions,
# so I add -D_ALLOW_COMPILER_AND_STL_VERSION_MISMATCH
arch: [
{cpu: "x86", flag: "-m32 -D_ALLOW_COMPILER_AND_STL_VERSION_MISMATCH"}
#, {cpu: "x64", flag: "-D_ALLOW_COMPILER_AND_STL_VERSION_MISMATCH"}
]
steps:
- name: Set git cllf config
run: |
git config --global core.autocrlf input
git config --global core.eol lf
- uses: Wandalen/wretry.action@v3
with:
action: actions/checkout@v5
attempt_limit: 3
attempt_delay: 10000
# Build needs GCutil only; "Run octane" needs test/octane. test262 is
# commented out below, so test/test262 isn't fetched here.
- name: Init required submodules
shell: bash
run: |
for i in 1 2 3; do
git submodule update --init -- third_party/GCutil test/octane && break
echo "submodule update failed (attempt $i/3), retrying in 10s..." >&2
sleep 10
done
- uses: szenius/set-timezone@v2.0
with:
timezoneWindows: "Pacific Standard Time"
- uses: lukka/get-cmake@latest
with:
cmakeVersion: "~3.25.0"
- uses: GuillaumeFalourd/setup-windows10-sdk-action@v2
with:
sdk-version: 26100
- uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Download and Install Visual C++ Redistributable
shell: powershell
run: |
$vcRedistUrl64 = "https://aka.ms/vs/17/release/vc_redist.x64.exe" # Or the appropriate URL for your target architecture/version
$vcRedistPath64 = "$env:TEMP\vc_redist.x64.exe"
$vcRedistUrl32 = "https://aka.ms/vs/17/release/vc_redist.x86.exe" # Or the appropriate URL for your target architecture/version
$vcRedistPath32 = "$env:TEMP\vc_redist.x86.exe"
Write-Host "Downloading Visual C++ Redistributable from $vcRedistUrl64"
Invoke-WebRequest -Uri $vcRedistUrl64 -OutFile $vcRedistPath64
Write-Host "Downloading Visual C++ Redistributable from $vcRedistUrl32"
Invoke-WebRequest -Uri $vcRedistUrl32 -OutFile $vcRedistPath32
Write-Host "Installing Visual C++ Redistributable silently"
Start-Process -FilePath $vcRedistPath64 -ArgumentList "/install /quiet /norestart" -Wait
Start-Process -FilePath $vcRedistPath32 -ArgumentList "/install /quiet /norestart" -Wait
Write-Host "Visual C++ Redistributable installation complete."
- uses: ilammy/msvc-dev-cmd@v1.13.0
with:
arch: ${{ matrix.arch.cpu }}
sdk: "10.0.26100.0"
- uses: egor-tensin/setup-clang@v1
with:
version: 19.1.7
platform: ${{ matrix.arch.cpu }}
- name: Build ${{ matrix.arch.cpu }} Release
run: |
CMake -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_SYSTEM_VERSION:STRING="10.0" -DCMAKE_SYSTEM_PROCESSOR=${{ matrix.arch.cpu }} -Bout/ -DENABLE_SHELL=ON -DESCARGOT_LIBICU_SUPPORT=ON -DESCARGOT_THREADING=ON -DESCARGOT_TCO=ON -DESCARGOT_TEST=ON -DESCARGOT_SHADOWREALM=ON -G Ninja -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl -DCMAKE_BUILD_TYPE=release -DCMAKE_C_FLAGS="${{ matrix.arch.flag }}" -DCMAKE_CXX_FLAGS="${{ matrix.arch.flag }}"
CMake --build out/ --config Release
- name: Run octane
run: |
copy test\octane\*.js
dir
.\out\escargot.exe run.js
# clang-cl with cannot generate c++ exception code well. if clang-cl bug fixed, we can enable test262
# - name: Run test262
# run: |
# set GC_FREE_SPACE_DIVISOR=1
# pip install chardet
# python tools\run-tests.py --engine=%cd%\out\escargot.exe test262 --test262-extra-arg="--skip Temporal --skip intl402 --skip Atomics"
# shell: cmd
- if: ${{ failure() }}
uses: mxschmitt/action-tmate@v3
timeout-minutes: 15
# Build once per arch, then fan out into test262/octane jobs below instead of
# running build->test262->octane serially in one job -- test262 (~14m) and
# octane (~3m) no longer block each other this way. Also builds
# ESCARGOT_BUILD_SHARED_LIBS=ON (the escargot.dll the old
# build-on-windows-x86-shared job built separately, x86-only) together with
# the shell in the SAME configure: ESCARGOT_ENABLE_SHELL=ON +
# ESCARGOT_BUILD_SHARED_LIBS=ON links escargot_shell dynamically against
# escargot.dll (see build/escargot.cmake), so test262/octane below now
# exercise the DLL directly instead of a separate untested static build --
# this is a combination no platform's CI has ever tried (ESCARGOT_CXXFLAGS_SHELL
# forces -DESCARGOT_EXPORT= unconditionally, so the shell consumes the DLL's
# exports without __declspec(dllimport) -- fine for plain member functions,
# unverified for exported data). If this specific link fails, that macro is
# the first place to look. Also newly covers x64 DLL linking, which nothing
# tested before.
build-on-windows-x86-x64:
runs-on: windows-2022
strategy:
matrix:
arch: [x86, x64]
steps:
- name: Set git cllf config
run: |
git config --global core.autocrlf input
git config --global core.eol lf
- uses: Wandalen/wretry.action@v3
with:
action: actions/checkout@v5
attempt_limit: 3
attempt_delay: 10000
# Build-only job (uploads an artifact for test262/octane-on-windows below
# to consume) -- needs GCutil + Walrus (-DESCARGOT_WASM=ON), no test suite.
- name: Init required submodules
shell: bash
run: |
for i in 1 2 3; do
git submodule update --init --recursive -- third_party/GCutil third_party/walrus && break
echo "submodule update failed (attempt $i/3), retrying in 10s..." >&2
sleep 10
done
- uses: lukka/get-cmake@latest
with:
cmakeVersion: "~3.25.0" # <--= optional, use most recent 3.25.x version
- uses: GuillaumeFalourd/setup-windows10-sdk-action@v2
with:
sdk-version: 26100
- uses: ilammy/msvc-dev-cmd@v1.13.0
with:
arch: ${{ matrix.arch }}
sdk: "10.0.26100.0"
- name: Build ${{ matrix.arch }} Release
run: |
CMake -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_SYSTEM_VERSION:STRING="10.0" -DCMAKE_SYSTEM_PROCESSOR=${{ matrix.arch }} -Bout/ -DENABLE_SHELL=ON -DESCARGOT_BUILD_SHARED_LIBS=ON -DESCARGOT_LIBICU_SUPPORT=ON -DESCARGOT_WASM=ON -DESCARGOT_THREADING=ON -DESCARGOT_TCO=ON -DESCARGOT_TEST=ON -DESCARGOT_SHADOWREALM=ON -G Ninja -DCMAKE_C_COMPILER=cl -DCMAKE_CXX_COMPILER=cl -DCMAKE_BUILD_TYPE=release
CMake --build out/ --config Release
shell: cmd
- name: Upload build artifact
uses: actions/upload-artifact@v6
with:
name: build-artifact-win-${{ matrix.arch }}
# walrus.dll: -DESCARGOT_WASM=ON below unconditionally builds Walrus
# (the WASM engine) as WALRUS_OUTPUT="shared_lib" regardless of
# ESCARGOT_BUILD_SHARED_LIBS (see build/escargot.cmake) -- escargot.exe
# dynamically depends on it at runtime even in an otherwise-static
# build. The old single combined build+test job never surfaced this
# because build and run happened in the same working directory; once
# split across jobs via artifact upload/download, walrus.dll has to be
# carried across explicitly too, or escargot.exe fails to start.
path: |
out/escargot.exe
out/escargot.dll
out/walrus.dll
- if: ${{ failure() }}
uses: mxschmitt/action-tmate@v3
timeout-minutes: 15
# test262.py runs each applicable test in BOTH strict and non-strict mode by
# default (roughly doubling the test count), so splitting strict/non-strict
# into separate matrix legs via the pre-existing (but previously unused --
# and buggy, now fixed in tools/run-tests.py -- see that commit) test262-strict/
# test262-nonstrict runners roughly halves this job's wall time per arch, on
# top of the arch-level x86/x64 parallelism already here.
test262-on-windows:
needs: build-on-windows-x86-x64
runs-on: windows-2022
strategy:
matrix:
arch: [x86, x64]
mode: [strict, nonstrict]
steps:
- name: Set git cllf config
run: |
git config --global core.autocrlf input
git config --global core.eol lf
- uses: Wandalen/wretry.action@v3
with:
action: actions/checkout@v5
attempt_limit: 3
attempt_delay: 10000
# Only downloads+runs the prebuilt binary against test262 here.
- name: Init required submodules
shell: bash
run: |
for i in 1 2 3; do
git submodule update --init --recursive -- test/test262 && break
echo "submodule update failed (attempt $i/3), retrying in 10s..." >&2
sleep 10
done
- uses: szenius/set-timezone@v2.0
with:
timezoneWindows: "Pacific Standard Time"
- uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Download and Install Visual C++ Redistributable
shell: powershell
run: |
$vcRedistUrl64 = "https://aka.ms/vs/17/release/vc_redist.x64.exe" # Or the appropriate URL for your target architecture/version
$vcRedistPath64 = "$env:TEMP\vc_redist.x64.exe"
$vcRedistUrl32 = "https://aka.ms/vs/17/release/vc_redist.x86.exe" # Or the appropriate URL for your target architecture/version
$vcRedistPath32 = "$env:TEMP\vc_redist.x86.exe"
Write-Host "Downloading Visual C++ Redistributable from $vcRedistUrl64"
Invoke-WebRequest -Uri $vcRedistUrl64 -OutFile $vcRedistPath64
Write-Host "Downloading Visual C++ Redistributable from $vcRedistUrl32"
Invoke-WebRequest -Uri $vcRedistUrl32 -OutFile $vcRedistPath32
Write-Host "Installing Visual C++ Redistributable silently"
Start-Process -FilePath $vcRedistPath64 -ArgumentList "/install /quiet /norestart" -Wait
Start-Process -FilePath $vcRedistPath32 -ArgumentList "/install /quiet /norestart" -Wait
Write-Host "Visual C++ Redistributable installation complete."
- name: Download build artifact
uses: actions/download-artifact@v6
with:
name: build-artifact-win-${{ matrix.arch }}
path: out
# windows internal ICU doesn't support Temporal and intl402 well
# github action windows runner only have 2 CPUs. that's why I disable Atomics(timeout occured with some tests)
# property-escapes / property-of-strings: \p{} classes are now built from the
# runtime ICU (see YarrUnicodeProperties.cpp), so these test262 cases follow the
# host ICU's Unicode version. The Windows runner's bundled ICU version does not
# match test262's generated expectations, so skip that class here (Linux/arm CI
# pin a matching ICU instead).
# identifiers/{part,start}-unicode-<version>: IdentifierStart / IdentifierPart
# are decided by ICU's ID_Start / ID_Continue (see Lexer.cpp), so these follow
# the host ICU's Unicode version too. Skipped for the same reason; the
# version independent identifier tests (zwj-zwnj, other_id_start, ...) still run.
- name: Run test262 (${{ matrix.mode }})
run: |
set GC_FREE_SPACE_DIVISOR=1
pip install chardet
python tools\run-tests.py --engine=%cd%\out\escargot.exe test262-${{ matrix.mode }} --test262-extra-arg="--skip Temporal --skip intl402 --skip Atomics --skip sm --skip property-escapes --skip property-of-strings --skip rgi-emoji --skip identifiers\part-unicode- --skip identifiers\start-unicode-"
shell: cmd
- if: ${{ failure() }}
uses: mxschmitt/action-tmate@v3
timeout-minutes: 15
octane-on-windows:
needs: build-on-windows-x86-x64
runs-on: windows-2022
strategy:
matrix:
arch: [x86, x64]
steps:
- uses: Wandalen/wretry.action@v3
with:
action: actions/checkout@v5
attempt_limit: 3
attempt_delay: 10000
# Only downloads+runs the prebuilt binary against octane here.
- name: Init required submodules
shell: bash
run: |
for i in 1 2 3; do
git submodule update --init --recursive -- test/octane && break
echo "submodule update failed (attempt $i/3), retrying in 10s..." >&2
sleep 10
done
- name: Download and Install Visual C++ Redistributable
shell: powershell
run: |
$vcRedistUrl64 = "https://aka.ms/vs/17/release/vc_redist.x64.exe" # Or the appropriate URL for your target architecture/version
$vcRedistPath64 = "$env:TEMP\vc_redist.x64.exe"
$vcRedistUrl32 = "https://aka.ms/vs/17/release/vc_redist.x86.exe" # Or the appropriate URL for your target architecture/version
$vcRedistPath32 = "$env:TEMP\vc_redist.x86.exe"
Write-Host "Downloading Visual C++ Redistributable from $vcRedistUrl64"
Invoke-WebRequest -Uri $vcRedistUrl64 -OutFile $vcRedistPath64
Write-Host "Downloading Visual C++ Redistributable from $vcRedistUrl32"
Invoke-WebRequest -Uri $vcRedistUrl32 -OutFile $vcRedistPath32
Write-Host "Installing Visual C++ Redistributable silently"
Start-Process -FilePath $vcRedistPath64 -ArgumentList "/install /quiet /norestart" -Wait
Start-Process -FilePath $vcRedistPath32 -ArgumentList "/install /quiet /norestart" -Wait
Write-Host "Visual C++ Redistributable installation complete."
- name: Download build artifact
uses: actions/download-artifact@v6
with:
name: build-artifact-win-${{ matrix.arch }}
path: out
- name: Run octane
run: |
copy test\octane\*.js
dir
.\out\escargot.exe run.js
- if: ${{ failure() }}
uses: mxschmitt/action-tmate@v3
timeout-minutes: 15
# Was one job whose 5-way `tc` matrix each independently reran the exact
# same x86 release configure+build just to test a different suite subset --
# 5 redundant builds of 1 real binary. Split build (once) from test (fanned
# out), same pattern as build-on-windows-x86-x64/test262-on-windows/
# octane-on-windows below. Also absorbs build-test-on-x86-release-extra's
# gcc leg (byte-identical BUILD_OPTIONS to this build, previously built a
# second time there) as the `tc: test262` entry -- that job now only builds
# clang.
build-on-x86-release:
runs-on: ubuntu-24.04
steps:
- uses: Wandalen/wretry.action@v3
with:
action: actions/checkout@v5
attempt_limit: 3
attempt_delay: 10000
# Build-only job (uploads an artifact for build-test-on-x86-release below
# to consume) -- needs GCutil only, no test suite runs here.
- name: Init required submodules
run: |
for i in 1 2 3; do
git submodule update --init -- third_party/GCutil && break
echo "submodule update failed (attempt $i/3), retrying in 10s..." >&2
sleep 10
done
- name: Install Packages
run: |
sudo apt-get update
sudo apt-get install -y ninja-build gcc-multilib g++-multilib pkg-config
- name: Cache ICU release-78.1 (m32)
id: cache-icu-m32
uses: actions/cache@v5
with:
path: icu32
key: icu-linux-m32-release-78.1
- name: Build ICU
if: steps.cache-icu-m32.outputs.cache-hit != 'true'
run: |
git clone --depth 1 --single-branch -b release-78.1 https://github.com/unicode-org/icu.git $GITHUB_WORKSPACE/icu-build/
cd $GITHUB_WORKSPACE/icu-build/icu4c/source
LDFLAGS="-m32 -Wl,-rpath=$GITHUB_WORKSPACE/icu32/lib/" CFLAGS="-m32" CXXFLAGS="-m32" ./runConfigureICU Linux/gcc --prefix="$GITHUB_WORKSPACE/icu32/"
make -j8
make install
ls $GITHUB_WORKSPACE/icu32/lib/
- name: Build x86
env:
BUILD_OPTIONS: -DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_PROCESSOR=x86 -DESCARGOT_THREADING=ON -DESCARGOT_TEMPORAL=ON -DESCARGOT_TCO=ON -DESCARGOT_TEST=ON -DESCARGOT_SHADOWREALM=ON -DENABLE_SHELL=ON -GNinja
run: |
export CXXFLAGS="-I$GITHUB_WORKSPACE/icu32/include"
export LDFLAGS="-L$GITHUB_WORKSPACE/icu32/lib/ -Wl,-rpath=$GITHUB_WORKSPACE/icu32/lib/"
export PKG_CONFIG_PATH=$GITHUB_WORKSPACE/icu32/lib/pkgconfig
cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H. -Bout/release/x86 $BUILD_OPTIONS
ninja -Cout/release/x86
- name: Upload build artifact
uses: actions/upload-artifact@v6
with:
name: build-artifact-x86-release
path: out/release/x86/escargot
build-test-on-x86-release:
needs: build-on-x86-release
runs-on: ubuntu-24.04
strategy:
matrix:
tc: ['new-es octane', 'v8 chakracore spidermonkey', 'jetstream-only-simple-parallel-1', 'jetstream-only-simple-parallel-2 jsc-stress', 'jetstream-only-simple-parallel-3 jetstream-only-cdjs', 'test262']
steps:
- uses: Wandalen/wretry.action@v3
with:
action: actions/checkout@v5
attempt_limit: 3
attempt_delay: 10000
# Downloads a prebuilt x86 binary (build-on-x86-release) and only runs
# the ${{ matrix.tc }} suites against it -- new-es/v8/chakracore/spidermonkey/
# jetstream-*/jsc-stress resolve under vendortest, test262 under test262.
- name: Init required submodules
run: |
for i in 1 2 3; do
git submodule update --init -- test/vendortest test/octane test/test262 && break
echo "submodule update failed (attempt $i/3), retrying in 10s..." >&2
sleep 10
done
- name: Install Packages
run: |
sudo apt-get update
sudo apt-get install -y gcc-multilib g++-multilib make g++ pkg-config automake libtool git build-essential checkinstall libncurses-dev libssl-dev libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev libffi-dev
- name: Build python2
run: |
mkdir $GITHUB_WORKSPACE/python2-build/
cd $GITHUB_WORKSPACE/python2-build/
wget https://www.python.org/ftp/python/2.7.18/Python-2.7.18.tgz
tar xzf Python-2.7.18.tgz
cd Python-2.7.18
./configure --prefix=/usr/local/python2.7
make -j8
sudo make install
sudo update-alternatives --install /usr/bin/python python /usr/local/python2.7/bin/python2.7 1
- name: Cache ICU release-78.1 (m32)
id: cache-icu-m32
uses: actions/cache@v5
with:
path: icu32
key: icu-linux-m32-release-78.1
- name: Build ICU
if: steps.cache-icu-m32.outputs.cache-hit != 'true'
run: |
git clone --depth 1 --single-branch -b release-78.1 https://github.com/unicode-org/icu.git $GITHUB_WORKSPACE/icu-build/
cd $GITHUB_WORKSPACE/icu-build/icu4c/source
LDFLAGS="-m32 -Wl,-rpath=$GITHUB_WORKSPACE/icu32/lib/" CFLAGS="-m32" CXXFLAGS="-m32" ./runConfigureICU Linux/gcc --prefix="$GITHUB_WORKSPACE/icu32/"
make -j8
make install
ls $GITHUB_WORKSPACE/icu32/lib/
- name: Download build artifact
uses: actions/download-artifact@v6
with:
name: build-artifact-x86-release
path: out/release/x86
- name: Run release-x86 test
env:
GC_FREE_SPACE_DIVISOR: 1
run: |
chmod +x "$GITHUB_WORKSPACE/out/release/x86/escargot"
sudo locale-gen en_US.UTF-8
export LANG=en_US.UTF-8
LD_LIBRARY_PATH=$GITHUB_WORKSPACE/icu32/lib $RUNNER --arch=x86 --engine="$GITHUB_WORKSPACE/out/release/x86/escargot" ${{ matrix.tc }}
- if: ${{ failure() }}
uses: mxschmitt/action-tmate@v3
timeout-minutes: 15
# Was one job whose (tc x build_opt) matrix rebuilt x64 from scratch per tc
# leg sharing the same build_opt -- 3 distinct builds actually needed, 5
# built. Split build (once per build_opt variant) from test (fanned out
# over the tc legs that consume it). Also absorbs
# build-test-on-x64-release-extra's gcc leg (its BUILD_OPTIONS match the
# "threading-tco" variant below) as that variant's extra `tc: test262`
# entry -- that job now only builds clang.
build-on-x64-release:
runs-on: ubuntu-24.04
strategy:
matrix:
variant:
- {tag: default, opt: ''}
- {tag: threading-tco, opt: '-DESCARGOT_THREADING=ON -DESCARGOT_TCO=ON'}
- {tag: small-config, opt: '-DESCARGOT_SMALL_CONFIG=ON -DESCARGOT_USE_CUSTOM_LOGGING=ON'}
steps:
- uses: Wandalen/wretry.action@v3
with:
action: actions/checkout@v5
attempt_limit: 3
attempt_delay: 10000
# Build-only job (uploads an artifact for build-test-on-x64-release below
# to consume) -- needs GCutil only, no test suite runs here.
- name: Init required submodules
run: |
for i in 1 2 3; do
git submodule update --init -- third_party/GCutil && break
echo "submodule update failed (attempt $i/3), retrying in 10s..." >&2
sleep 10
done
- name: Install Packages
run: |
sudo apt-get update
sudo apt-get install -y ninja-build g++ pkg-config
- name: Cache ICU release-78.1 (x64)
id: cache-icu-x64
uses: actions/cache@v5
with:
path: icu64
key: icu-linux-x64-release-78.1
- name: Build ICU(64)
if: steps.cache-icu-x64.outputs.cache-hit != 'true'
run: |
git clone --depth 1 --single-branch -b release-78.1 https://github.com/unicode-org/icu.git $GITHUB_WORKSPACE/icu64-build/
cd $GITHUB_WORKSPACE/icu64-build/icu4c/source
LDFLAGS="-Wl,-rpath=$GITHUB_WORKSPACE/icu64/lib/" ./runConfigureICU Linux/gcc --prefix="$GITHUB_WORKSPACE/icu64/"
make -j8
make install
- name: Build x64 (${{ matrix.variant.tag }})
env:
BUILD_OPTIONS: -DESCARGOT_TEMPORAL=ON -DESCARGOT_TCO=ON -DESCARGOT_TEST=ON -DESCARGOT_SHADOWREALM=ON -DENABLE_SHELL=ON -GNinja
run: |
export CXXFLAGS="-I$GITHUB_WORKSPACE/icu64/include"
export LDFLAGS="-L$GITHUB_WORKSPACE/icu64/lib -Wl,-rpath=$GITHUB_WORKSPACE/icu64/lib"
export PKG_CONFIG_PATH=$GITHUB_WORKSPACE/icu64/lib/pkgconfig
cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H. -Bout/release/x64 $BUILD_OPTIONS ${{ matrix.variant.opt }}
ninja -Cout/release/x64
- name: Upload build artifact
uses: actions/upload-artifact@v6
with:
name: build-artifact-x64-release-${{ matrix.variant.tag }}
path: out/release/x64/escargot
build-test-on-x64-release:
needs: build-on-x64-release
runs-on: ubuntu-24.04
strategy:
matrix:
include:
- {tag: default, tc: 'octane v8 web-tooling-benchmark'}
- {tag: default, tc: 'chakracore spidermonkey new-es'}
- {tag: threading-tco, tc: 'octane v8 web-tooling-benchmark'}
- {tag: threading-tco, tc: 'chakracore spidermonkey new-es'}
- {tag: threading-tco, tc: 'test262'}
# exclude octane, v8, web-tooling-benchmark due to low performance incurred by SMALL_CONFIG
- {tag: small-config, tc: 'chakracore spidermonkey new-es'}
steps:
- uses: Wandalen/wretry.action@v3
with:
action: actions/checkout@v5
attempt_limit: 3
attempt_delay: 10000
# Downloads a prebuilt x64 binary (build-on-x64-release) and only runs
# the ${{ matrix.tc }} suites against it -- octane/v8/web-tooling-benchmark,
# chakracore/spidermonkey/new-es (vendortest), test262.
- name: Init required submodules
run: |
for i in 1 2 3; do
git submodule update --init -- test/octane test/vendortest test/web-tooling-benchmark test/test262 && break
echo "submodule update failed (attempt $i/3), retrying in 10s..." >&2
sleep 10
done
- name: Install Packages
run: |
sudo apt-get update
sudo apt-get install -y g++ pkg-config automake libtool git build-essential checkinstall libncurses-dev libssl-dev libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev libffi-dev
- name: Cache ICU release-78.1 (x64)
id: cache-icu-x64
uses: actions/cache@v5
with:
path: icu64
key: icu-linux-x64-release-78.1
- name: Build ICU(64)
if: steps.cache-icu-x64.outputs.cache-hit != 'true'
run: |
git clone --depth 1 --single-branch -b release-78.1 https://github.com/unicode-org/icu.git $GITHUB_WORKSPACE/icu64-build/
cd $GITHUB_WORKSPACE/icu64-build/icu4c/source
LDFLAGS="-Wl,-rpath=$GITHUB_WORKSPACE/icu64/lib/" ./runConfigureICU Linux/gcc --prefix="$GITHUB_WORKSPACE/icu64/"
make -j8
make install
- name: Build python2
run: |
mkdir $GITHUB_WORKSPACE/python2-build/
cd $GITHUB_WORKSPACE/python2-build/
wget https://www.python.org/ftp/python/2.7.18/Python-2.7.18.tgz
tar xzf Python-2.7.18.tgz
cd Python-2.7.18
./configure --prefix=/usr/local/python2.7
make -j8
sudo make install
sudo update-alternatives --install /usr/bin/python python /usr/local/python2.7/bin/python2.7 1
- name: Download build artifact
uses: actions/download-artifact@v6
with:
name: build-artifact-x64-release-${{ matrix.tag }}
path: out/release/x64
- name: Run release-x64 test
env:
GC_FREE_SPACE_DIVISOR: 1
run: |
chmod +x "$GITHUB_WORKSPACE/out/release/x64/escargot"
export LD_LIBRARY_PATH=$GITHUB_WORKSPACE/icu64/lib
# set locale
sudo locale-gen en_US.UTF-8
export LANG=en_US.UTF-8
locale
$RUNNER --arch=x86_64 --engine="$GITHUB_WORKSPACE/out/release/x64/escargot" ${{ matrix.tc }}
- if: ${{ failure() }}
uses: mxschmitt/action-tmate@v3
timeout-minutes: 15
build-test-on-x86-x64-debug:
runs-on: ubuntu-24.04
steps:
- uses: Wandalen/wretry.action@v3
with:
action: actions/checkout@v5
attempt_limit: 3
attempt_delay: 10000
# Build needs GCutil; "Run debug-mode test" runs modifiedVendorTest/
# regression-tests/new-es/intl/sunspider-js, all under vendortest.
- name: Init required submodules
run: |
for i in 1 2 3; do
git submodule update --init -- third_party/GCutil test/vendortest && break
echo "submodule update failed (attempt $i/3), retrying in 10s..." >&2
sleep 10
done
- name: Install Packages
run: |
sudo apt-get update
sudo apt-get install -y ninja-build gcc-multilib g++-multilib make g++ pkg-config automake libtool git build-essential checkinstall libncurses-dev libssl-dev libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev libffi-dev
- name: Cache ICU release-78.1 (m32)
id: cache-icu-m32
uses: actions/cache@v5
with:
path: icu32
key: icu-linux-m32-release-78.1
- name: Build ICU(32)
if: steps.cache-icu-m32.outputs.cache-hit != 'true'
run: |
git clone --depth 1 --single-branch -b release-78.1 https://github.com/unicode-org/icu.git $GITHUB_WORKSPACE/icu32-build/
cd $GITHUB_WORKSPACE/icu32-build/icu4c/source
LDFLAGS="-m32 -Wl,-rpath=$GITHUB_WORKSPACE/icu32/lib/" CFLAGS="-m32" CXXFLAGS="-m32" ./runConfigureICU Linux/gcc --prefix="$GITHUB_WORKSPACE/icu32/"
make -j8
make install
- name: Cache ICU release-78.1 (x64)
id: cache-icu-x64
uses: actions/cache@v5
with:
path: icu64
key: icu-linux-x64-release-78.1
- name: Build ICU(64)
if: steps.cache-icu-x64.outputs.cache-hit != 'true'
run: |
git clone --depth 1 --single-branch -b release-78.1 https://github.com/unicode-org/icu.git $GITHUB_WORKSPACE/icu64-build/
cd $GITHUB_WORKSPACE/icu64-build/icu4c/source
LDFLAGS="-Wl,-rpath=$GITHUB_WORKSPACE/icu64/lib/" ./runConfigureICU Linux/gcc --prefix="$GITHUB_WORKSPACE/icu64/"
make -j8
make install
- name: Build x86/x64
env:
BUILD_OPTIONS_X86: -DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_PROCESSOR=x86 -DCMAKE_BUILD_TYPE=Debug -DESCARGOT_TEMPORAL=ON -DESCARGOT_TCO=ON -DESCARGOT_TEST=ON -DESCARGOT_SHADOWREALM=ON -DENABLE_SHELL=ON -GNinja
BUILD_OPTIONS_X64: -DCMAKE_BUILD_TYPE=Debug -DESCARGOT_TEMPORAL=ON -DESCARGOT_TCO=ON -DESCARGOT_TEST=ON -DESCARGOT_SHADOWREALM=ON -DENABLE_SHELL=ON -GNinja
run: |
cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H. -Bout/debug/x86 $BUILD_OPTIONS_X86
cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H. -Bout/debug/x64 $BUILD_OPTIONS_X64
ninja -Cout/debug/x86
ninja -Cout/debug/x64
- name: Run debug-mode test
run: |
export LD_LIBRARY_PATH=$GITHUB_WORKSPACE/icu32/lib
$RUNNER --arch=x86 --engine="$GITHUB_WORKSPACE/out/debug/x86/escargot" modifiedVendorTest regression-tests new-es intl sunspider-js
export LD_LIBRARY_PATH=$GITHUB_WORKSPACE/icu64/lib
$RUNNER --arch=x86_64 --engine="$GITHUB_WORKSPACE/out/debug/x64/escargot" modifiedVendorTest regression-tests new-es intl sunspider-js
# Tried splitting this across hosted ubuntu-24.04 runners (parallel
# instead of 6 combos serialized on one self-hosted box) -- but hosted
# runners are only 2-4 vCPU vs this self-hosted box's much higher core
# count, and test262 parallelizes across all cores
# (multiprocessing.Pool(cpu_count()) in tools/test/test262/test262.py), so
# each combo ran ~3x slower there (measured: x86-release test262 5min
# self-hosted vs 14.5min hosted, x64-release 4.5min vs 15min). The
# debug+backtrace-hooking combo alone then approached or exceeded the
# original 6-combo serial total, negating the parallelization win. Back
# to the single self-hosted job.
# Only the two debug combos stay here now (see build-test-on-x86-release-extra
# / build-test-on-x64-release-extra for why): debug+backtrace-hooking is the
# one combo that's disproportionately slow on weak hosted CPUs (measured
# ~3x), so it stays on this fast dedicated box; release-gcc/release-clang
# moved to hosted where they can run concurrently instead of serialized
# behind this. New critical path for this whole split ~= max(this job,
# slowest hosted release job) instead of all 6 summed.
build-test-on-self-hosted-linux:
if: github.repository == 'Samsung/escargot'
runs-on: [self-hosted, linux, x64, test]
timeout-minutes: 60
steps:
- uses: Wandalen/wretry.action@v3
with:
action: actions/checkout@v5
attempt_limit: 3
attempt_delay: 10000
# Build needs GCutil; Test runs test262 (test/test262) + kangax
# (test/kangax). This is a persistent self-hosted runner, so this is an
# incremental fetch either way, not a fresh clone -- narrowing it just
# avoids leaving vendortest/octane/googletest/walrus/web-tooling-benchmark/
# FreeRTOS-Kernel on disk unused.
- name: Init required submodules
run: |
for i in 1 2 3; do
git submodule update --init -- third_party/GCutil test/test262 test/kangax && break
echo "submodule update failed (attempt $i/3), retrying in 10s..." >&2
sleep 10
done
- name: Build
env:
BUILD_OPTIONS: -DESCARGOT_THREADING=ON -DESCARGOT_TEMPORAL=ON -DESCARGOT_TCO=ON -DESCARGOT_TEST=ON -DESCARGOT_SHADOWREALM=ON -DENABLE_SHELL=ON -GNinja
run: |
LDFLAGS=" -L/usr/icu78-32/lib/ -Wl,-rpath=/usr/icu78-32/lib/" PKG_CONFIG_PATH="/usr/icu78-32/lib/pkgconfig/" cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H./ -Bbuild/out_linux -DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_PROCESSOR=x86 -DCMAKE_BUILD_TYPE=Debug -DESCARGOT_TCO_DEBUG=ON $BUILD_OPTIONS
gcc -shared -m32 -fPIC -o backtrace-hooking-32.so tools/test/test262/backtrace-hooking.c
LDFLAGS=" -L/usr/icu78-64/lib/ -Wl,-rpath=/usr/icu78-64/lib/" PKG_CONFIG_PATH="/usr/icu78-64/lib/pkgconfig/" cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H./ -Bbuild/out_linux64 -DCMAKE_BUILD_TYPE=Debug -DESCARGOT_TCO_DEBUG=ON $BUILD_OPTIONS
cmake --build build/out_linux/
cmake --build build/out_linux64/
- name: Test
run: |
# intl402/Temporal/ZonedDateTime/prototype/equals/canonical-not-equal
# loops over every pairwise combination of Intl.supportedValuesOf("timeZone")
# (~400 IANA zones => ~80k Temporal.ZonedDateTime constructions +
# .equals() calls) -- excessively slow on this runner and occasionally
# times out the whole 60-minute job, losing coverage of every test
# that would've run after it. Skipped from the main run and re-run in
# isolation below (own timeout, doesn't gate the rest of the suite).
LD_LIBRARY_PATH=/usr/icu78-32/lib/ GC_FREE_SPACE_DIVISOR=1 ESCARGOT_LD_PRELOAD=${{ github.workspace }}/backtrace-hooking-32.so $RUNNER --arch=x86 --engine="${{ github.workspace }}/build/out_linux/escargot" test262 --test262-extra-arg="--skip intl402/Temporal/ZonedDateTime/prototype/equals/canonical-not-equal"
LD_LIBRARY_PATH=/usr/icu78-64/lib/ python tools/kangax/run-kangax.py --engine="${{ github.workspace }}/build/out_linux64/escargot"
# Isolated re-run of the slow test skipped above -- own timeout so a slow
# (or hung) run here can't eat into/kill the main Test step's results.
# continue-on-error: a timeout here is a known perf characteristic of this
# runner, not a correctness signal; a genuine correctness failure (wrong
# assertion, crash) would show up the same way a timeout does in this
# job's exit code, so this can't distinguish them automatically -- if this
# step is red, check its own log before assuming it's just slow again.
- name: Test (slow Temporal canonical-not-equal, isolated)
timeout-minutes: 20
continue-on-error: true
run: |
LD_LIBRARY_PATH=/usr/icu78-32/lib/ GC_FREE_SPACE_DIVISOR=1 ESCARGOT_LD_PRELOAD=${{ github.workspace }}/backtrace-hooking-32.so $RUNNER --arch=x86 --engine="${{ github.workspace }}/build/out_linux/escargot" test262 --test262-extra-arg="intl402/Temporal/ZonedDateTime/prototype/equals/canonical-not-equal"
# Split off from build-test-on-self-hosted-linux: these release combos are
# only ~3x slower on hosted vCPUs (measured), and running 4 of them
# concurrently on hosted beats running them serially on the one
# self-hosted box, even at 3x per-job cost. See that job's comment for the
# debug combo that stayed behind. Mirrors build-test-on-x86-release's
# ICU-78.1 cache pattern (same cache key, shared).
# gcc coverage for this combo now comes from build-on-x86-release's build +
# build-test-on-x86-release's own `tc: test262` leg -- only clang needs a
# dedicated build here now.
build-test-on-x86-release-extra:
runs-on: ubuntu-24.04
steps:
- uses: Wandalen/wretry.action@v3
with:
action: actions/checkout@v5
attempt_limit: 3
attempt_delay: 10000
# Build needs GCutil; "Run test262" needs test/test262.
- name: Init required submodules
run: |
for i in 1 2 3; do
git submodule update --init -- third_party/GCutil test/test262 && break
echo "submodule update failed (attempt $i/3), retrying in 10s..." >&2
sleep 10
done
- name: Install Packages
run: |
sudo apt-get update
sudo apt-get install -y ninja-build gcc-multilib g++-multilib clang
- name: Cache ICU release-78.1 (m32)
id: cache-icu-m32
uses: actions/cache@v5
with:
path: icu32
key: icu-linux-m32-release-78.1
- name: Build ICU
if: steps.cache-icu-m32.outputs.cache-hit != 'true'
run: |
git clone --depth 1 --single-branch -b release-78.1 https://github.com/unicode-org/icu.git $GITHUB_WORKSPACE/icu-build/
cd $GITHUB_WORKSPACE/icu-build/icu4c/source
LDFLAGS="-m32 -Wl,-rpath=$GITHUB_WORKSPACE/icu32/lib/" CFLAGS="-m32" CXXFLAGS="-m32" ./runConfigureICU Linux/gcc --prefix="$GITHUB_WORKSPACE/icu32/"
make -j8
make install
- name: Build x86 (clang)
env:
BUILD_OPTIONS: -DESCARGOT_THREADING=ON -DESCARGOT_TEMPORAL=ON -DESCARGOT_TCO=ON -DESCARGOT_TEST=ON -DESCARGOT_SHADOWREALM=ON -DENABLE_SHELL=ON -GNinja
run: |
export CXXFLAGS="-I$GITHUB_WORKSPACE/icu32/include"
export LDFLAGS="-L$GITHUB_WORKSPACE/icu32/lib/ -Wl,-rpath=$GITHUB_WORKSPACE/icu32/lib/"
export PKG_CONFIG_PATH=$GITHUB_WORKSPACE/icu32/lib/pkgconfig
cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H. -Bout -DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_PROCESSOR=x86 $BUILD_OPTIONS
ninja -Cout
- name: Run test262
env:
GC_FREE_SPACE_DIVISOR: 1
run: |
# See build-test-on-x64-release's locale step -- same reason.
sudo locale-gen en_US.UTF-8
export LANG=en_US.UTF-8
export LD_LIBRARY_PATH=$GITHUB_WORKSPACE/icu32/lib
$RUNNER --arch=x86 --engine="$GITHUB_WORKSPACE/out/escargot" test262
# gcc coverage for this combo now comes from build-on-x64-release's
# "threading-tco" variant + build-test-on-x64-release's own `tc: test262`
# leg -- only clang needs a dedicated build here now.
build-test-on-x64-release-extra:
runs-on: ubuntu-24.04
steps:
- uses: Wandalen/wretry.action@v3
with:
action: actions/checkout@v5
attempt_limit: 3
attempt_delay: 10000
# Build needs GCutil; "Run test262" needs test/test262.
- name: Init required submodules
run: |
for i in 1 2 3; do
git submodule update --init -- third_party/GCutil test/test262 && break
echo "submodule update failed (attempt $i/3), retrying in 10s..." >&2
sleep 10
done
- name: Install Packages
run: |
sudo apt-get update
sudo apt-get install -y ninja-build clang pkg-config
- name: Cache ICU release-78.1 (x64)
id: cache-icu-x64
uses: actions/cache@v5
with:
path: icu64
key: icu-linux-x64-release-78.1
- name: Build ICU(64)
if: steps.cache-icu-x64.outputs.cache-hit != 'true'
run: |
git clone --depth 1 --single-branch -b release-78.1 https://github.com/unicode-org/icu.git $GITHUB_WORKSPACE/icu64-build/
cd $GITHUB_WORKSPACE/icu64-build/icu4c/source
LDFLAGS="-Wl,-rpath=$GITHUB_WORKSPACE/icu64/lib/" ./runConfigureICU Linux/gcc --prefix="$GITHUB_WORKSPACE/icu64/"
make -j8
make install
- name: Build x64 (clang)
env:
BUILD_OPTIONS: -DESCARGOT_THREADING=ON -DESCARGOT_TEMPORAL=ON -DESCARGOT_TCO=ON -DESCARGOT_TEST=ON -DESCARGOT_SHADOWREALM=ON -DENABLE_SHELL=ON -GNinja
run: |
export CXXFLAGS="-I$GITHUB_WORKSPACE/icu64/include"
export LDFLAGS="-L$GITHUB_WORKSPACE/icu64/lib -Wl,-rpath=$GITHUB_WORKSPACE/icu64/lib"
export PKG_CONFIG_PATH=$GITHUB_WORKSPACE/icu64/lib/pkgconfig
cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H. -Bout $BUILD_OPTIONS
ninja -Cout
- name: Run test262
env:
GC_FREE_SPACE_DIVISOR: 1
run: |
sudo locale-gen en_US.UTF-8
export LANG=en_US.UTF-8
export LD_LIBRARY_PATH=$GITHUB_WORKSPACE/icu64/lib
$RUNNER --arch=x86_64 --engine="$GITHUB_WORKSPACE/out/escargot" test262
# Was its own dedicated self-hosted runner registration ("arm" label), but
# that runner was always just a docker container on the SAME physical box
# as build-test-on-self-hosted-arm64-linux -- same CPU/resource, just a
# second runner process competing for it. Folded in as a docker step on
# the arm64 runner instead: one fewer runner to keep registered/updated,
# and this box's aarch64 CPUs run armv7 natively (no QEMU), so
# --platform linux/arm/v7 here is real hardware execution, not emulation.
# Toolchain is installed fresh via apt each run instead of matching
# whatever image the old dedicated runner happened to have -- versions may
# drift from before; re-pin here if that ever matters.
build-test-on-self-hosted-arm32-docker:
if: github.repository == 'Samsung/escargot'
runs-on: [self-hosted, linux, arm64, test]
strategy:
matrix:
compiler: [gcc, clang]
timeout-minutes: 60
steps:
- uses: Wandalen/wretry.action@v3
with:
action: actions/checkout@v5
attempt_limit: 3
attempt_delay: 10000
# Build needs GCutil; the run-tests.py suites here (new-es/v8/spidermonkey/
# chakracore -> vendortest, test262 -> test262) are the only ones used.
# Persistent self-hosted runner, so this is an incremental fetch either way.
- name: Init required submodules
run: |
for i in 1 2 3; do
git submodule update --init -- third_party/GCutil test/vendortest test/test262 && break
echo "submodule update failed (attempt $i/3), retrying in 10s..." >&2
sleep 10
done
- name: Build + Test (arm32 via docker, native on this arm64 host)
run: |
docker run --rm --platform linux/arm/v7 \
-v "${{ github.workspace }}:/work" -w /work \
arm32v7/ubuntu:24.04 \
bash -c '
set -e
# Container runs as root (needed for apt-get), and writes into
# the bind-mounted host workspace in more places than just
# ./out -- e.g. importing SpiderMonkey'"'"'s lib/ modules leaves
# root-owned __pycache__ under the checked-out submodule too.
# Any of that left root-owned poisons every later job on this
# same self-hosted runner (its non-root checkout step cannot
# clean up root-owned files from a prior run and fails
# outright). chown the whole workspace back to the host dir'"'"'s
# real owner on exit, success or failure.
OWNER=$(stat -c "%u:%g" /work)
trap "chown -R $OWNER /work 2>/dev/null || true" EXIT
apt-get update
apt-get install -y --no-install-recommends ca-certificates git cmake ninja-build pkg-config libicu-dev python3 python3-chardet locales gcc g++ clang
# v8'"'"'s and spidermonkey'"'"'s test runners both force LANG/LC_ALL=en_US.UTF-8
# for their child escargot processes (see tools/test/v8/v8.run-tests.py and
# SpiderMonkey/lib/tests.py'"'"'s get_environment_overlay) -- generate it, or
# those two suites fail across the board while the locale-independent ones
# (new-es, chakracore, test262 with intl402 skipped) pass fine.
locale-gen en_US.UTF-8
if [ "${{ matrix.compiler }}" = "clang" ]; then CC=clang; CXX=clang++; else CC=gcc; CXX=g++; fi
cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H. -Bout \
-DCMAKE_C_COMPILER=$CC -DCMAKE_CXX_COMPILER=$CXX \
-DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_PROCESSOR=arm32 \
-DCMAKE_BUILD_TYPE=Release -DESCARGOT_THREADING=ON -DESCARGOT_TEMPORAL=OFF -DESCARGOT_TCO=ON \
-DESCARGOT_TEST=ON -DESCARGOT_SHADOWREALM=ON -DENABLE_SHELL=ON -GNinja
cmake --build ./out/
# \p{} regex classes are built from the runtime ICU (see
# YarrUnicodeProperties.cpp), so test262 property-escapes / property-of-strings
# / rgi-emoji follow the runner ICU'"'"'s Unicode version, which does not match
# test262'"'"'s generated expectations here. Pinning a matching ICU inside this
# container proved unreliable (the runtime binder still loads the system
# ICU), so skip that class -- same as the Windows job.
# identifiers/{part,start}-unicode-<version> follow the runner ICU'"'"'s Unicode
# version as well, because IdentifierStart / IdentifierPart are decided by
# ICU'"'"'s ID_Start / ID_Continue (see Lexer.cpp). The version independent
# identifier tests (zwj-zwnj, other_id_start, ...) still run.
# v8'"'"'s perfdata cache (test/vendortest/v8/out/testrunner_data) is a
# Berkeley DB file when it was last written by a python2/bsddb-era
# run -- /work is this same self-hosted runner'"'"'s persistent
# checkout (bind-mounted, not container-local), so that stale file
# survives across runs and python3'"'"'s dbm can'"'"'t open it ("db type
# could not be determined"). It'"'"'s a disposable cache, so just drop
# it; v8'"'"'s own test runner regenerates it as needed.
rm -rf test/vendortest/v8/out/testrunner_data
GC_FREE_SPACE_DIVISOR=1 python3 tools/run-tests.py --engine="$(pwd)/out/escargot" --test262-extra-arg="--skip intl402 --skip sm --skip Temporal --skip property-escapes --skip property-of-strings --skip rgi-emoji --skip identifiers/part-unicode- --skip identifiers/start-unicode-" new-es v8 spidermonkey chakracore test262 || {
# DIAGNOSTIC: run-tests.py'"'"'s own run_v8() captures the v8 test
# runner'"'"'s stdout into a variable and only checks it for a marker
# string, printing nothing on failure -- re-run the same already
# copied-over v8 test runner directly (no capture) so its real
# output actually reaches this log.
echo "=== manual v8 mjsunit re-run (uncaptured) ==="
( cd test/vendortest/v8 && GC_FREE_SPACE_DIVISOR=1 python3 tools/run-tests.py \
--timeout=120 --quickcheck --no-presubmit --no-variants \
--arch-and-mode=x64.release --shell /work/out/escargot --escargot \
--report -p verbose --no-sorting --no-network mjsunit ) 2>&1 | tail -n 200
echo "=== spidermonkey x86_64.log.txt (tail) ==="
tail -n 200 tools/test/spidermonkey/x86_64.log.txt 2>/dev/null || true
echo "=== spidermonkey x86_64.gen.txt (failures) ==="
cat tools/test/spidermonkey/x86_64.gen.txt 2>/dev/null || true
exit 1
}
'
- name: Fix workspace ownership (always runs, even if the job above is cancelled)
# The chown-on-EXIT trap inside the container above only fires on a
# graceful container exit. A cancelled job hard-kills the container
# before its trap runs, leaving root-owned files that break the next
# job's checkout on this runner (confirmed by hitting this for real).
# Run this as its own step so it executes independently of how the
# build step above ended.
if: always()
run: |
docker run --rm --platform linux/arm/v7 \
-v "${{ github.workspace }}:/work" -w /work \
arm32v7/ubuntu:24.04 \
chown -R "$(id -u):$(id -g)" /work 2>/dev/null || true
build-test-on-self-hosted-arm64-linux:
if: github.repository == 'Samsung/escargot'
runs-on: [self-hosted, linux, arm64, test]
strategy:
matrix:
compiler: [ {cxx: g++-11, cc: gcc-11}, {cxx: clang++, cc: clang} ]
timeout-minutes: 60
steps:
- uses: Wandalen/wretry.action@v3
with:
action: actions/checkout@v5
attempt_limit: 3
attempt_delay: 10000
# Build needs GCutil; Test runs test262/chakracore/spidermonkey/v8/new-es
# -- test262 -> test/test262, the rest -> test/vendortest. Persistent
# self-hosted runner, so this is an incremental fetch either way.
- name: Init required submodules
run: |
for i in 1 2 3; do
git submodule update --init -- third_party/GCutil test/vendortest test/test262 && break
echo "submodule update failed (attempt $i/3), retrying in 10s..." >&2
sleep 10
done
- name: Build
run: |
LDFLAGS=" -L/usr/icu78-64/lib/ -Wl,-rpath=/usr/icu78-64/lib/" PKG_CONFIG_PATH="/usr/icu78-64/lib/pkgconfig/" cmake -DCMAKE_C_COMPILER=${{ matrix.compiler.cc }} -DCMAKE_CXX_COMPILER=${{ matrix.compiler.cxx }} -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H./ -Bout -DCMAKE_BUILD_TYPE=Release -DESCARGOT_THREADING=ON -DESCARGOT_TEMPORAL=ON -DESCARGOT_TCO=ON -DESCARGOT_TEST=ON -DESCARGOT_SHADOWREALM=ON -DENABLE_SHELL=ON -GNinja
cmake --build ./out/
- name: Test
run: |
export LD_LIBRARY_PATH=/usr/icu78-64/lib/
# v8's perfdata cache (test/vendortest/v8/out/testrunner_data) is a
# Berkeley DB file when it was last written by a python2/bsddb-era
# run -- this is a persistent self-hosted checkout, so that stale
# file survives across runs and python3's dbm can't open it
# ("db type could not be determined"). It's a disposable cache, so
# just drop it; v8's own test runner regenerates it as needed.
rm -rf test/vendortest/v8/out/testrunner_data
GC_FREE_SPACE_DIVISOR=1 $RUNNER --engine="${{ github.workspace }}/out/escargot" --test262-extra-arg="--skip intl402 --skip sm" test262 chakracore spidermonkey v8 new-es
build-test-on-riscv64-release:
runs-on: ubuntu-latest
steps:
- uses: Wandalen/wretry.action@v3
with:
action: actions/checkout@v5
attempt_limit: 3
attempt_delay: 10000
# Build needs GCutil; the riscv64 container run only exercises new-es/
# intl/sunspider-js, all under vendortest.
- name: Init required submodules
run: |
for i in 1 2 3; do
git submodule update --init -- third_party/GCutil test/vendortest && break
echo "submodule update failed (attempt $i/3), retrying in 10s..." >&2
sleep 10
done
- name: Install cross-compile toolchain
run: |
sudo apt-get update
sudo apt-get install -y cmake ninja-build pkg-config python3 \
gcc-riscv64-linux-gnu g++-riscv64-linux-gnu
- name: Cross-compile for riscv64
env:
CC: riscv64-linux-gnu-gcc
CXX: riscv64-linux-gnu-g++
run: |
cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H. -Bout/riscv64 \
-DCMAKE_SYSTEM_NAME=Linux \
-DCMAKE_SYSTEM_PROCESSOR=riscv64 \
-DESCARGOT_TEMPORAL=ON \
-DESCARGOT_TCO=ON \
-DESCARGOT_TEST=ON \
-DESCARGOT_SHADOWREALM=ON \
-DENABLE_SHELL=ON \
-GNinja
ninja -Cout/riscv64
- name: Run tests in riscv64 container
uses: uraimo/run-on-arch-action@v3
with:
arch: riscv64
distro: ubuntu24.04
githubToken: ${{ github.token }}
install: |
apt-get update
apt-get install -y python3 libicu74
run: |
python3 ./tools/run-tests.py --engine="./out/riscv64/escargot" new-es intl sunspider-js
build-test-debugger:
runs-on: ubuntu-latest
steps:
- uses: Wandalen/wretry.action@v3
with:
action: actions/checkout@v5
attempt_limit: 3
attempt_delay: 10000
# Build needs GCutil only; debugger-server-source/debugger-client-source
# read from tools/debugger, not a submodule.
- name: Init required submodules
run: |
for i in 1 2 3; do
git submodule update --init -- third_party/GCutil && break
echo "submodule update failed (attempt $i/3), retrying in 10s..." >&2
sleep 10
done
- name: Install Packages
run: |
sudo apt-get update
sudo apt-get install -y ninja-build
- name: Build
env:
BUILD_OPTIONS: -DCMAKE_BUILD_TYPE=Debug -DESCARGOT_DEBUGGER=1 -DESCARGOT_TEMPORAL=ON -DESCARGOT_TCO=ON -DESCARGOT_TEST=ON -DESCARGOT_SHADOWREALM=ON -DENABLE_SHELL=ON -GNinja
run: |
cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H. -Bout/debugger $BUILD_OPTIONS
ninja -Cout/debugger
- name: Debugger Test
run: |
$RUNNER --arch=x86_64 --engine="$GITHUB_WORKSPACE/out/debugger/escargot" debugger-server-source
$RUNNER --arch=x86_64 --engine="$GITHUB_WORKSPACE/out/debugger/escargot" debugger-client-source
build-test-api:
runs-on: ubuntu-latest
steps:
- uses: Wandalen/wretry.action@v3
with:
action: actions/checkout@v5
attempt_limit: 3
attempt_delay: 10000
# -DESCARGOT_BUILD_CCTEST=ON pulls in googletest; cctest's own source is
# in-tree (test/cctest/*.cpp), no other submodule is touched.
- name: Init required submodules
run: |
for i in 1 2 3; do
git submodule update --init -- third_party/GCutil third_party/googletest && break
echo "submodule update failed (attempt $i/3), retrying in 10s..." >&2
sleep 10
done
- name: Install Packages
run: |
# for i386 ICU (x86 cctest needs 32-bit ICU at runtime via dlopen)
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install -y ninja-build gcc-multilib g++-multilib
sudo apt-get install -y libicu-dev libicu-dev:i386
- name: Build x86/x64
env:
BUILD_OPTIONS_X86: -DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_PROCESSOR=x86 -DCMAKE_BUILD_TYPE=Debug -DESCARGOT_THREADING=ON -DESCARGOT_DEBUGGER=1 -DESCARGOT_USE_EXTENDED_API=ON -DESCARGOT_TEST=ON -DESCARGOT_BUILD_CCTEST=ON -GNinja
BUILD_OPTIONS_X64: -DCMAKE_BUILD_TYPE=Debug -DESCARGOT_THREADING=1 -DESCARGOT_DEBUGGER=1 -DESCARGOT_USE_EXTENDED_API=ON -DESCARGOT_TEST=ON -DESCARGOT_BUILD_CCTEST=ON -GNinja
run: |
cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H. -Bout/cctest/x86 $BUILD_OPTIONS_X86
ninja -Cout/cctest/x86
cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H. -Bout/cctest/x64 $BUILD_OPTIONS_X64
ninja -Cout/cctest/x64
- name: Run Test
run: |
$RUNNER --arch=x86 --engine="$GITHUB_WORKSPACE/out/cctest/x86/cctest" cctest
$RUNNER --arch=x86_64 --engine="$GITHUB_WORKSPACE/out/cctest/x64/cctest" cctest
# Separate from build-test-api: N-API support is an early PoC
# gated behind ESCARGOT_NAPI, and test/napi-tc is a sparse checkout of the
# nodejs/node monorepo (submodule.test/napi-tc.update=none in .gitmodules
# keeps every OTHER job's `git submodule update --init` from fetching it in full).
build-test-napi:
runs-on: ubuntu-latest
steps:
- uses: Wandalen/wretry.action@v3
with:
action: actions/checkout@v5
attempt_limit: 3
attempt_delay: 10000
# -DESCARGOT_BUILD_CCTEST=ON pulls in googletest; test/napi-tc itself is
# handled entirely by the sparse-checkout step below (update=none in
# .gitmodules), not by this generic submodule init.
- name: Init required submodules
run: |
for i in 1 2 3; do
git submodule update --init -- third_party/GCutil third_party/googletest && break
echo "submodule update failed (attempt $i/3), retrying in 10s..." >&2
sleep 10
done
- name: Sparse checkout napi test corpus
run: |
NAPI_TC_SHA=$(git ls-tree HEAD test/napi-tc | awk '{print $3}')
if [ -z "$NAPI_TC_SHA" ]; then
echo "::error::test/napi-tc gitlink not found in HEAD tree." >&2
echo "::error::Ensure the submodule gitlink is committed (git add test/napi-tc && git commit)." >&2
exit 1
fi
rm -rf test/napi-tc
git clone --filter=blob:none --no-checkout https://github.com/nodejs/node.git test/napi-tc
cd test/napi-tc
git sparse-checkout init --no-cone
git sparse-checkout set test/js-native-api test/node-api test/common src/js_native_api.h src/node_api.h src/js_native_api_types.h src/node_api_types.h
git checkout "$NAPI_TC_SHA"
- name: Install Packages
run: |
sudo apt-get update
sudo apt-get install -y ninja-build libuv1-dev libicu-dev
- name: Build
env:
BUILD_OPTIONS: -DCMAKE_BUILD_TYPE=Debug -DESCARGOT_THREADING=1 -DESCARGOT_DEBUGGER=1 -DESCARGOT_USE_EXTENDED_API=ON -DESCARGOT_TEST=ON -DESCARGOT_BUILD_CCTEST=ON -DESCARGOT_NAPI=ON -GNinja
run: |
cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H. -Bout/cctest/napi $BUILD_OPTIONS
ninja -Cout/cctest/napi
- name: Run Test
run: |
$RUNNER --arch=x86_64 --engine="$GITHUB_WORKSPACE/out/cctest/napi/cctest" cctest
build-test-codecache:
runs-on: ubuntu-latest
steps:
- uses: Wandalen/wretry.action@v3
with:
action: actions/checkout@v5
attempt_limit: 3
attempt_delay: 10000
# sunspider-js/new-es/octane-loading -> vendortest+octane;
# web-tooling-benchmark -> its own submodule.
- name: Init required submodules
run: |
for i in 1 2 3; do
git submodule update --init -- third_party/GCutil test/vendortest test/octane test/web-tooling-benchmark && break
echo "submodule update failed (attempt $i/3), retrying in 10s..." >&2
sleep 10
done
- name: Install Packages
run: |
# for i386 ICU
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install -y ninja-build gcc-multilib g++-multilib
sudo apt-get install -y libicu-dev:i386 # install i386 ICU
- name: Build x86
env:
BUILD_OPTIONS: -DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_PROCESSOR=x86 -DCMAKE_BUILD_TYPE=Debug -DESCARGOT_CODE_CACHE=ON -DESCARGOT_TEMPORAL=ON -DESCARGOT_TCO=ON -DESCARGOT_TEST=ON -DESCARGOT_SHADOWREALM=ON -DENABLE_SHELL=ON -GNinja
run: |
cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H. -Bout/codecache/x86 $BUILD_OPTIONS
ninja -Cout/codecache/x86
- name: Build x64
env:
BUILD_OPTIONS: -DCMAKE_BUILD_TYPE=Debug -DESCARGOT_CODE_CACHE=ON -DESCARGOT_TEMPORAL=ON -DESCARGOT_TCO=ON -DESCARGOT_TEST=ON -DESCARGOT_SHADOWREALM=ON -DENABLE_SHELL=ON -GNinja
run: |
cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H. -Bout/codecache/x64 $BUILD_OPTIONS
ninja -Cout/codecache/x64
- name: Build x64 Release Mode
env:
BUILD_OPTIONS: -DCMAKE_BUILD_TYPE=Release -DESCARGOT_CODE_CACHE=ON -DESCARGOT_TEMPORAL=ON -DESCARGOT_TCO=ON -DESCARGOT_TEST=ON -DESCARGOT_SHADOWREALM=ON -DENABLE_SHELL=ON -GNinja
run: |
cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H. -Bout/codecache/release/x64 $BUILD_OPTIONS
ninja -Cout/codecache/release/x64
- name: Run x86 test
run: |
$RUNNER --arch=x86 --engine="$GITHUB_WORKSPACE/out/codecache/x86/escargot" sunspider-js
$RUNNER --arch=x86 --engine="$GITHUB_WORKSPACE/out/codecache/x86/escargot" sunspider-js
$RUNNER --arch=x86 --engine="$GITHUB_WORKSPACE/out/codecache/x86/escargot" new-es
$RUNNER --arch=x86 --engine="$GITHUB_WORKSPACE/out/codecache/x86/escargot" new-es
$RUNNER --arch=x86 --engine="$GITHUB_WORKSPACE/out/codecache/x86/escargot" octane-loading
$RUNNER --arch=x86 --engine="$GITHUB_WORKSPACE/out/codecache/x86/escargot" octane-loading
rm -rf $HOME/Escargot-cache/
- name: Run x64 test
run: |
$RUNNER --arch=x86_64 --engine="$GITHUB_WORKSPACE/out/codecache/x64/escargot" sunspider-js
$RUNNER --arch=x86_64 --engine="$GITHUB_WORKSPACE/out/codecache/x64/escargot" sunspider-js
$RUNNER --arch=x86_64 --engine="$GITHUB_WORKSPACE/out/codecache/x64/escargot" new-es
$RUNNER --arch=x86_64 --engine="$GITHUB_WORKSPACE/out/codecache/x64/escargot" new-es
$RUNNER --arch=x86_64 --engine="$GITHUB_WORKSPACE/out/codecache/x64/escargot" octane-loading
$RUNNER --arch=x86_64 --engine="$GITHUB_WORKSPACE/out/codecache/x64/escargot" octane-loading
rm -rf $HOME/Escargot-cache/
- name: Run x64 release test
run: |
$RUNNER --arch=x86_64 --engine="$GITHUB_WORKSPACE/out/codecache/release/x64/escargot" web-tooling-benchmark
rm -rf $HOME/Escargot-cache/
- name: Handle error cases
run: |
$RUNNER --arch=x86_64 --engine="$GITHUB_WORKSPACE/out/codecache/x64/escargot" sunspider-js
rm $HOME/Escargot-cache/2728638815_17149
$RUNNER --arch=x86_64 --engine="$GITHUB_WORKSPACE/out/codecache/x64/escargot" sunspider-js
ls -1q $HOME/Escargot-cache/ | wc -l
$RUNNER --arch=x86_64 --engine="$GITHUB_WORKSPACE/out/codecache/x64/escargot" sunspider-js
rm $HOME/Escargot-cache/cache_list
$RUNNER --arch=x86_64 --engine="$GITHUB_WORKSPACE/out/codecache/x64/escargot" sunspider-js
- if: ${{ failure() }}
uses: mxschmitt/action-tmate@v3
timeout-minutes: 15
build-test-wasmjs:
runs-on: ubuntu-latest
steps:
- uses: Wandalen/wretry.action@v3
with:
action: actions/checkout@v5
attempt_limit: 3
attempt_delay: 10000
# -DESCARGOT_WASM=ON pulls in Walrus + GCutil; wasm-js resolves under
# test/vendortest/wasm-js (see tools/run-tests.py's WASM_TEST_ROOT).
- name: Init required submodules
run: |
for i in 1 2 3; do
git submodule update --init --recursive -- third_party/GCutil third_party/walrus test/vendortest && break
echo "submodule update failed (attempt $i/3), retrying in 10s..." >&2
sleep 10
done
- name: Install Packages
run: |
sudo apt-get update
sudo apt-get install -y ninja-build gcc-multilib g++-multilib make g++ pkg-config automake libtool git build-essential checkinstall libncurses-dev libssl-dev libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev libffi-dev
- name: Cache ICU release-78.1 (m32)
id: cache-icu-m32
uses: actions/cache@v5
with:
path: icu32
key: icu-linux-m32-release-78.1
- name: Build ICU(32)
if: steps.cache-icu-m32.outputs.cache-hit != 'true'
run: |
git clone --depth 1 --single-branch -b release-78.1 https://github.com/unicode-org/icu.git $GITHUB_WORKSPACE/icu-build/
cd $GITHUB_WORKSPACE/icu-build/icu4c/source
LDFLAGS="-m32 -Wl,-rpath=$GITHUB_WORKSPACE/icu32/lib/" CFLAGS="-m32" CXXFLAGS="-m32" ./runConfigureICU Linux/gcc --prefix="$GITHUB_WORKSPACE/icu32/"
make -j8
make install
- name: Cache ICU release-78.1 (x64)
id: cache-icu-x64
uses: actions/cache@v5
with:
path: icu64
key: icu-linux-x64-release-78.1
- name: Build ICU(64)
if: steps.cache-icu-x64.outputs.cache-hit != 'true'
run: |
git clone --depth 1 --single-branch -b release-78.1 https://github.com/unicode-org/icu.git $GITHUB_WORKSPACE/icu64-build/
cd $GITHUB_WORKSPACE/icu64-build/icu4c/source
LDFLAGS="-Wl,-rpath=$GITHUB_WORKSPACE/icu64/lib/" ./runConfigureICU Linux/gcc --prefix="$GITHUB_WORKSPACE/icu64/"
make -j8
make install
- name: Build x86
env:
BUILD_OPTIONS: -DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_PROCESSOR=x86 -DCMAKE_BUILD_TYPE=Debug -DESCARGOT_WASM=ON -DESCARGOT_TEMPORAL=ON -DESCARGOT_TCO=ON -DESCARGOT_TEST=ON -DESCARGOT_SHADOWREALM=ON -DENABLE_SHELL=ON -GNinja
run: |
cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H. -Bout/wasm/x86 $BUILD_OPTIONS
ninja -Cout/wasm/x86
- name: Build x64
env:
BUILD_OPTIONS: -DCMAKE_BUILD_TYPE=Debug -DESCARGOT_WASM=ON -DESCARGOT_TEMPORAL=ON -DESCARGOT_TCO=ON -DESCARGOT_TEST=ON -DESCARGOT_SHADOWREALM=ON -DENABLE_SHELL=ON -GNinja
run: |
cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H. -Bout/wasm/x64 $BUILD_OPTIONS
ninja -Cout/wasm/x64
- name: Run x86 test
run: |
export LD_LIBRARY_PATH=$GITHUB_WORKSPACE/icu32/lib
$RUNNER --arch=x86 --engine="$GITHUB_WORKSPACE/out/wasm/x86/escargot" wasm-js
- name: Run x64 test
run: |
export LD_LIBRARY_PATH=$GITHUB_WORKSPACE/icu64/lib
$RUNNER --arch=x86_64 --engine="$GITHUB_WORKSPACE/out/wasm/x64/escargot" wasm-js
- if: ${{ failure() }}
uses: mxschmitt/action-tmate@v3
# These two RTOS/QEMU jobs are heavier (cross-compile + full boot test)
# than the rest of this workflow, so -- same as every other job here --
# they still only need to actually run when something that can affect
# them changes. Since they now live in this single workflow (so they show
# up on the same Actions run page as everything else) rather than their
# own path-triggered workflow files, that per-job skip is done via this
# shared `changes` job + each RTOS job's own `if:`, instead of the
# top-level `on: push: paths:` this repo's workflows otherwise use.
changes:
runs-on: ubuntu-24.04
outputs:
freertos: ${{ steps.filter.outputs.freertos }}
nuttx: ${{ steps.filter.outputs.nuttx }}
steps:
- uses: Wandalen/wretry.action@v3
with:
action: actions/checkout@v5
attempt_limit: 3
attempt_delay: 10000
- uses: dorny/paths-filter@v3
id: filter
with:
filters: |
freertos:
- 'src/**'
- 'third_party/GCutil/**'
- 'samples/rtos/**'
- 'CMakeLists.txt'
- 'build/config.cmake'
- 'build/escargot.cmake'
- 'build/target.cmake'
- '.github/workflows/es-actions.yml'
nuttx:
- 'src/**'
- 'third_party/GCutil/**'
- 'samples/rtos/nuttx/**'
- 'CMakeLists.txt'
- 'build/config.cmake'
- 'build/escargot.cmake'
- 'build/target.cmake'
- '.github/workflows/es-actions.yml'
build-boot-test-freertos-qemu:
needs: changes
if: needs.changes.outputs.freertos == 'true'
runs-on: ubuntu-24.04
permissions:
contents: read
pull-requests: write
steps:
- uses: Wandalen/wretry.action@v3
with:
action: actions/checkout@v5
attempt_limit: 3
attempt_delay: 10000
# The sample's CMakeLists add_subdirectory()s FreeRTOS-Kernel plus the
# top-level CMakeLists (GCutil) -- see build-boot-test-freertos-qemu's
# cross-compile step below. The boot test itself also reads its 26
# SunSpider 1.0.2 cases out of test/vendortest via semihosting.
- name: Init required submodules
run: |
for i in 1 2 3; do
git submodule update --init -- third_party/GCutil samples/rtos/freertos/FreeRTOS-Kernel test/vendortest && break
echo "submodule update failed (attempt $i/3), retrying in 10s..." >&2
sleep 10
done
- name: Install cross-compile toolchain and QEMU
run: |
sudo apt-get update
sudo apt-get install -y cmake ninja-build python3 \
gcc-arm-none-eabi qemu-system-arm
- name: Cross-compile FreeRTOS sample for Cortex-M55
run: |
# The sample's own CMakeLists.txt add_subdirectory()s the main repo's
# top-level CMakeLists.txt (ESCARGOT_HOST=baremetal) to build the
# engine itself, so a single configure+build here is enough --
# Unicode/Yarr table generation (build/escargot.cmake) runs as part
# of that same cross-compile configure, no separate native/host pass
# needed.
cmake -DCMAKE_TOOLCHAIN_FILE=toolchain-cm55.cmake \
-Hsamples/rtos/freertos -Bsamples/rtos/freertos/build -GNinja
ninja -Csamples/rtos/freertos/build
- name: Report binary size
run: |
elf=samples/rtos/freertos/build/escargot-rtos.elf
{
echo "### FreeRTOS (Cortex-M55) binary size"
echo ''
echo '```'
arm-none-eabi-size "$elf"
echo '```'
# .text already includes .rodata for this bare-metal image, so
# flash footprint == text + data, and RAM footprint == data + bss.
arm-none-eabi-size "$elf" | awk 'NR==2 {
printf "- **Flash (text+data): %d bytes (%.1f KiB)**\n", $1 + $2, ($1 + $2) / 1024.0;
printf "- RAM (data+bss): %d bytes (%.1f KiB)\n", $2 + $3, ($2 + $3) / 1024.0;
}'
} >> "$GITHUB_STEP_SUMMARY"
# Stash flash/RAM bytes for the baseline-diff + PR comment step below,
# which runs after the boot test (it also needs the GC heap figure
# out of qemu-output.log).
arm-none-eabi-size "$elf" | awk 'NR==2 {
printf "FLASH_BYTES=%d\nRAM_BYTES=%d\n", $1 + $2, $2 + $3;
}' >> "$GITHUB_ENV"
- name: Boot-test under QEMU (mps3-an547 / Cortex-M55)
run: |
timeout 60 qemu-system-arm \
-machine mps3-an547 \
-cpu cortex-m55 \
-semihosting \
-semihosting-config enable=on,target=native \
-kernel samples/rtos/freertos/build/escargot-rtos.elf \
-nographic \
-serial null > qemu-output.log 2>&1 || true
cat qemu-output.log
echo "--- Verifying pass markers ---"
# 1+2 sanity check
grep -Eq '\[ok\][[:space:]]+1\+2[[:space:]]+=>[[:space:]]+3' qemu-output.log
# 15 exception-suite cases (12 expected [ok], 3 expected top-level
# [THROW]) + 26 SunSpider 1.0.2 cases (all [ok]) + the 1+2 sanity
# check above == 42 total marker lines.
marker_count=$(grep -c '\[ok\]\|\[THROW\]' qemu-output.log)
test "$marker_count" -ge $((1 + 15 + 26))
# No fatal conditions (parse error / abort / terminate / kill hook hit)
! grep -q '\[PARSE_ERR\]\|\[ABORT\]\|\[TERMINATE\]\|\[KILL\]' qemu-output.log
# JS task ran to completion
grep -q '\[js\] done' qemu-output.log
echo "FreeRTOS/QEMU sample: boot + exception-suite + SunSpider 1.0.2 all passed ($marker_count marker lines)."
- name: Compare size/memory against recorded baseline
run: |
# "hello world" memory proxy: GC heap size right after
# Globals::initialize()+Context::create(), before any real script
# runs -- see print_gc_stats("init") in samples/rtos/freertos/src/main.cpp.
heap_init_kib=$(grep -m1 '^\[gc\] init' qemu-output.log | sed -E 's/.*h=([0-9]+)K.*/\1/')
base_flash=$(jq -r '.flash_bytes' samples/rtos/freertos/ci-baseline.json)
base_ram=$(jq -r '.ram_bytes' samples/rtos/freertos/ci-baseline.json)
base_heap=$(jq -r '.heap_init_kib' samples/rtos/freertos/ci-baseline.json)
base_date=$(jq -r '.recorded_date' samples/rtos/freertos/ci-baseline.json)
row() {
# args: label, current, current_unit, baseline, unit
local label="$1" cur="$2" unit="$3" base="$4"
awk -v label="$label" -v cur="$cur" -v base="$base" -v unit="$unit" 'BEGIN {
d = cur - base;
pct = (base != 0) ? (d / base * 100.0) : 0.0;
sign = (d >= 0) ? "+" : "";
printf "| %s | %d %s | %d %s | %s%d %s (%s%.2f%%) |\n", label, cur, unit, base, unit, sign, d, unit, sign, pct;
}'
}
{
echo "<!-- escargot-rtos-freertos-ci-metrics -->"
echo "### FreeRTOS (Cortex-M55) size & memory report"
echo ""
echo "| Metric | Current | Baseline ($base_date) | Delta |"
echo "|---|---|---|---|"
row "Flash (text+data)" "$FLASH_BYTES" "B" "$base_flash"
row "RAM (data+bss)" "$RAM_BYTES" "B" "$base_ram"
row "GC heap after init (hello world)" "$heap_init_kib" "KiB" "$base_heap"
echo ""
echo "_Baseline is only updated manually (\`samples/rtos/freertos/ci-baseline.json\`) when a size/memory increase is deliberately accepted -- CI never rewrites it._"
} | tee rtos-metrics-comment.md >> "$GITHUB_STEP_SUMMARY"
- name: Post/update PR comment with size & memory report
if: github.event_name == 'pull_request'
uses: actions/github-script@v8
with:
script: |
const fs = require('fs');
const body = fs.readFileSync('rtos-metrics-comment.md', 'utf8');
const marker = '<!-- escargot-rtos-freertos-ci-metrics -->';
const sameRepo = context.payload.pull_request.head.repo &&
context.payload.pull_request.head.repo.full_name === `${context.repo.owner}/${context.repo.repo}`;
if (!sameRepo) {
core.notice('Skipping PR comment: PR is from a fork, GITHUB_TOKEN is read-only there. See the job summary instead.');
return;
}
try {
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
per_page: 100,
});
const existing = comments.find(c => c.body && c.body.includes(marker));
if (existing) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existing.id,
body,
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
body,
});
}
} catch (e) {
core.warning(`Could not post/update PR comment: ${e}`);
}
build-boot-test-nuttx-qemu:
needs: changes
if: needs.changes.outputs.nuttx == 'true'
runs-on: ubuntu-24.04
env:
# Pinned upstream commits this sample is verified against. NuttX itself
# needed one small local patch on top of its base commit (see
# samples/rtos/nuttx/patches/) -- apache/nuttx-apps' pinned commit needs
# no patch, just the escargot app dropped into interpreters/.
NUTTX_BASE_COMMIT: 375462322eeb6d2da57e6dff84c747a56bfa2eef
NUTTX_APPS_COMMIT: e751331ecb7ea28073bff41600d2e9c9ba90aa1a
steps:
- uses: Wandalen/wretry.action@v3
with:
action: actions/checkout@v5
with: |
path: escargot
attempt_limit: 3
attempt_delay: 10000
# escargot-lib-cmake's add_subdirectory(${ESCARGOT_ROOT} ...) builds
# GCutil (BDWGC) as part of the same configure -- see that CMakeLists'
# own comment. No other submodule is touched by this sample.
- name: Init required submodules
run: |
for i in 1 2 3; do
git -C escargot submodule update --init -- third_party/GCutil && break
echo "submodule update failed (attempt $i/3), retrying in 10s..." >&2
sleep 10
done
- name: Install cross-compile toolchain, QEMU, and NuttX build deps
run: |
sudo apt-get update
sudo apt-get install -y cmake ninja-build python3 bison flex \
kconfig-frontends gcc-arm-none-eabi qemu-system-arm
# NUTTX_BASE_COMMIT/NUTTX_APPS_COMMIT are pinned, so the cloned+patched
# NuttX kernel + apps source tree AND its full build output (object
# files) are byte-for-byte reproducible run to run -- they do NOT
# depend on Escargot's own source (the thing this job actually needs
# to re-verify on every relevant PR). Cache both directories keyed on
# the pinned commits + the patch file's contents, so this only
# invalidates when one of *those* changes (a new NuttX/apps pin, or an
# edited patch) -- never just because src/** changed. On a cache hit,
# the clone + full NuttX kernel build below are skipped entirely;
# only the Escargot engine library and the app itself get rebuilt and
# relinked against the cached tree.
- name: Cache NuttX kernel + apps checkout and build
id: cache-nuttx
uses: actions/cache@v5
with:
path: |
nuttx
apps
key: nuttx-${{ env.NUTTX_BASE_COMMIT }}-apps-${{ env.NUTTX_APPS_COMMIT }}-patch-${{ hashFiles('escargot/samples/rtos/nuttx/patches/*.patch') }}
- name: Checkout NuttX kernel + apps at pinned commits, apply patch
if: steps.cache-nuttx.outputs.cache-hit != 'true'
run: |
mkdir nuttx && cd nuttx
git init -q
git remote add origin https://github.com/apache/nuttx.git
git fetch --depth 1 origin $NUTTX_BASE_COMMIT
git checkout -q FETCH_HEAD
git apply ../escargot/samples/rtos/nuttx/patches/0001-mps3-an547-fix-OS-heap-linker-layout-collision.patch
cd ..
mkdir apps && cd apps
git init -q
git remote add origin https://github.com/apache/nuttx-apps.git
git fetch --depth 1 origin $NUTTX_APPS_COMMIT
git checkout -q FETCH_HEAD
- name: Drop the escargot NSH app into apps/interpreters/
run: |
# Always runs, cache hit or not -- this is Escargot's own sample
# source (already checked out fresh above), not part of the
# cached NuttX/apps tree, and must overwrite whatever a cache hit
# restored here so a change to these files is always picked up.
mkdir -p apps/interpreters/escargot
cp escargot/samples/rtos/nuttx/interpreters-escargot/Kconfig \
escargot/samples/rtos/nuttx/interpreters-escargot/Make.defs \
escargot/samples/rtos/nuttx/interpreters-escargot/Makefile \
escargot/samples/rtos/nuttx/interpreters-escargot/embedded_tests.h \
escargot/samples/rtos/nuttx/interpreters-escargot/escargot_main.cxx \
escargot/samples/rtos/nuttx/interpreters-escargot/escargot_platform.cxx \
apps/interpreters/escargot/
- name: Configure NuttX (mps3-an547:nsh + escargot-specific options)
if: steps.cache-nuttx.outputs.cache-hit != 'true'
run: |
cd nuttx
./tools/configure.sh mps3-an547:nsh
kconfig-tweak --enable CONFIG_LIBCXXTOOLCHAIN
kconfig-tweak --enable CONFIG_LIBSUPCXX_TOOLCHAIN
kconfig-tweak --enable CONFIG_CXX_EXCEPTION
kconfig-tweak --enable CONFIG_CXX_RTTI
kconfig-tweak --enable CONFIG_LIBC_LOCALTIME
kconfig-tweak --enable CONFIG_LIBC_LOCALE
kconfig-tweak --enable CONFIG_ARCH_SETJMP_H
kconfig-tweak --set-val CONFIG_ARCH_INTERRUPTSTACK 8192
kconfig-tweak --enable CONFIG_INTERPRETERS_ESCARGOT
kconfig-tweak --set-val CONFIG_INTERPRETERS_ESCARGOT_STACKSIZE 4194304
# Neither of these two is escargot-specific -- both work around a
# genuine, pre-existing incompatibility between this exact pinned
# nuttx/nuttx-apps commit pair found while verifying this job (not
# anything to do with Escargot): nshlib's nsh_script.c references
# an `O_RDOK` that doesn't exist in this nuttx commit's fcntl.h,
# and testing/ostest's robust.c references a `pthread_mutex_t`
# member this nuttx commit's pthread.h doesn't have. Disabling
# NSH scripting and ostest (neither needed for this sample) avoids
# both -- compiling the escargot NSH command itself is unaffected.
kconfig-tweak --enable CONFIG_NSH_DISABLESCRIPT
kconfig-tweak --disable CONFIG_TESTING_OSTEST
make olddefconfig
# First pass: generates include/nuttx/config.h (needed to compile
# the engine below) as a side effect, but the escargot app's own
# context:: rule fails here because ESCARGOT_PREBUILT doesn't
# exist yet -- expected, see the second `make context` pass below.
make context || true
test -f include/nuttx/config.h
- name: Build libescargot.a/libgc-lib.a for NuttX
run: |
# escargot-lib-cmake's own CMakeLists.txt add_subdirectory()s the
# main repo's top-level CMakeLists.txt (ESCARGOT_HOST=baremetal) to
# build the engine itself, so a single configure+build here is
# enough -- Unicode/Yarr table generation (build/escargot.cmake)
# runs as part of that same cross-compile configure, no separate
# native/host pass needed.
mkdir escargot-lib-build && cd escargot-lib-build
cmake ${{ github.workspace }}/escargot/samples/rtos/nuttx/escargot-lib-cmake \
-DNUTTX_ROOT=${{ github.workspace }}/nuttx
make -j$(nproc)
- name: Build NuttX kernel + escargot app
env:
ESCARGOT_ROOT: ${{ github.workspace }}/escargot
ESCARGOT_PREBUILT: ${{ github.workspace }}/escargot-lib-build
run: |
cd nuttx
make context
make -j$(nproc)
- name: Boot-test under QEMU (mps3-an547 / Cortex-M55)
run: |
(sleep 3; echo "escargot"; sleep 90) | timeout 120 qemu-system-arm \
-M mps3-an547 -cpu cortex-m55 \
-kernel nuttx/nuttx -nographic > nuttx-output.log 2>&1 || true
cat nuttx-output.log
echo "--- Verifying pass markers ---"
# NuttX's own printf pads test names to align columns, so the
# amount of whitespace around "1+2"/"=>" isn't fixed -- match on
# whitespace runs instead of a literal single space (this exact
# rigid match was verified to fail against real, otherwise-passing
# output: "[ok] 1+2 => 3").
grep -Eq '\[ok\][[:space:]]+1\+2[[:space:]]+=>[[:space:]]+3' nuttx-output.log
# 15 exception-suite cases (12 expected [ok], 3 expected top-level
# [THROW]) + 26 SunSpider 1.0.2 cases (all [ok]) + the 1+2 sanity
# check above == 42 total marker lines.
marker_count=$(grep -c '\[ok\]\|\[THROW\]' nuttx-output.log)
test "$marker_count" -ge $((1 + 15 + 26))
grep -q '26/26 passed' nuttx-output.log
grep -q '\[escargot\] done in' nuttx-output.log
echo "NuttX/QEMU sample: boot + exception-suite + SunSpider 1.0.2 all passed ($marker_count marker lines)."
timeout-minutes: 60