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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
606 changes: 0 additions & 606 deletions .circleci/config.yml

This file was deleted.

82 changes: 0 additions & 82 deletions .circleci/download_google_fonts.py

This file was deleted.

21 changes: 0 additions & 21 deletions .circleci/env_image.sh

This file was deleted.

13 changes: 13 additions & 0 deletions .github/actions/run-xvfb/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: 'Run with Xvfb'
description: 'Run a command under Xvfb with a preconfigured screen size'

inputs:
run:
description: 'Command to execute'
required: true

runs:
using: 'composite'
steps:
- run: xvfb-run --auto-servernum --server-args="-screen 0 1280x1024x24" ${{ inputs.run }}
shell: bash
25 changes: 25 additions & 0 deletions .github/actions/setup-chrome/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: 'Setup Chrome'
description: 'Install Chrome and set CHROME_BIN environment variable'

inputs:
chrome-version:
description: 'Chrome version to install'
default: '136.0.7103.113'

runs:
using: 'composite'
steps:
- uses: browser-actions/setup-chrome@4f8e94349a351df0f048634f25fec36c3c91eded # v2
id: setup-chrome
with:
chrome-version: ${{ inputs.chrome-version }}

- name: Set Chrome binary path
run: echo "CHROME_BIN=${{ steps.setup-chrome.outputs.chrome-path }}" >> $GITHUB_ENV
shell: bash

- name: Verify Chrome version
run: |
echo "Chrome path: $CHROME_BIN"
$CHROME_BIN --version
shell: bash
35 changes: 35 additions & 0 deletions .github/actions/setup-image-env/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: 'Setup Image Environment'
description: 'Setup Python, uv, and install Kaleido/plotly with required fonts'

inputs:
python-version:
description: 'Python version to use'
default: '3.12'
uv-version:
description: 'uv version to use'
default: '0.11.2'

runs:
using: 'composite'
steps:
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
with:
python-version: ${{ inputs.python-version }}

- name: Install uv
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
with:
version: ${{ inputs.uv-version }}

- name: Cache apt font packages
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
id: apt-cache
with:
path: ~/.cache/apt-fonts
key: apt-fonts-${{ runner.os }}-${{ hashFiles('.github/scripts/env_image.sh') }}

- name: Install Kaleido, plotly.io and required fonts
run: .github/scripts/env_image.sh
shell: bash
env:
APT_CACHE_HIT: ${{ steps.apt-cache.outputs.cache-hit }}
26 changes: 26 additions & 0 deletions .github/actions/setup-workspace/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: 'Setup Workspace'
description: 'Setup Node.js, install dependencies, and download build artifacts'

inputs:
node-version:
description: 'Node.js version to use'
default: '18'

runs:
using: 'composite'
steps:
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
with:
node-version: ${{ inputs.node-version }}
cache: 'npm'

- name: Install dependencies
run: npm ci
shell: bash
env:
NODE_OPTIONS: '--max-old-space-size=4096'

- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: build-output
path: .
File renamed without changes.
36 changes: 36 additions & 0 deletions .github/scripts/env_image.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/bin/sh
set -e

APT_PACKAGES="fonts-liberation2 fonts-open-sans fonts-noto-cjk fonts-noto-color-emoji fontconfig"
APT_CACHE_DIR="${HOME}/.cache/apt-fonts"

if [ "$APT_CACHE_HIT" = "true" ] && [ -d "$APT_CACHE_DIR" ]; then
echo "Installing font packages from cache..."
sudo dpkg -i "$APT_CACHE_DIR"/*.deb 2>/dev/null || sudo apt-get install -yf
else
echo "Downloading and installing font packages..."
sudo apt-get update -q
sudo apt-get install -y --no-install-recommends $APT_PACKAGES
# Save debs for future cache
mkdir -p "$APT_CACHE_DIR"
for pkg in $APT_PACKAGES; do
cp /var/cache/apt/archives/${pkg}_*.deb "$APT_CACHE_DIR/" 2>/dev/null || true
done
fi

# Rebuild font cache
sudo fc-cache -f

# Install additional fonts (committed in .github/fonts/)
sudo cp -r .github/fonts/ /usr/share/
sudo fc-cache -f

# Install Kaleido & Plotly
uv pip install --system kaleido==0.2.1 plotly==6.6.0 --no-progress

# Install numpy i.e. to convert arrays to typed arrays
uv pip install --system numpy==2.4.3

# Verify version of python and versions of installed python packages
python --version
uv pip freeze --system
19 changes: 19 additions & 0 deletions .github/scripts/split_files.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env node

// Reads lines from stdin and emits only those where index % SHARD_TOTAL == SHARD_INDEX
// Environment variables SHARD_INDEX and SHARD_TOTAL must be set.

import { readFileSync } from 'fs';

const lines = readFileSync('/dev/stdin', 'utf8').trim().split('\n').filter(Boolean);
const index = parseInt(process.env.SHARD_INDEX);
const total = parseInt(process.env.SHARD_TOTAL);

if (isNaN(index) || isNaN(total) || total <= 0) {
console.error('SHARD_INDEX and SHARD_TOTAL environment variables must be set to valid integers');
process.exit(1);
}

lines.forEach((line, i) => {
if (i % total === index) console.log(line);
});
44 changes: 28 additions & 16 deletions .circleci/test.sh → .github/scripts/test.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
#!/bin/bash

# override CircleCi's default run settings
# GitHub Actions version of .circleci/test.sh
# Replaces `circleci tests split` with split_files.mjs

set +e
set +o pipefail

ROOT=$(dirname $0)/..
ROOT=$(dirname $0)/../..
SPLIT="$ROOT/.github/scripts/split_files.mjs"
EXIT_STATE=0
MAX_AUTO_RETRY=0

Expand Down Expand Up @@ -33,18 +36,21 @@ retry () {
fi
}

# Ensure output directories exist (not present in fresh GHA checkout)
mkdir -p build/test_images

case $1 in

no-gl-jasmine)
SUITE=$(circleci tests glob "$ROOT/test/jasmine/tests/*" | circleci tests split)
SUITE=$(ls -1 $ROOT/test/jasmine/tests/* | sort | node "$SPLIT")
MAX_AUTO_RETRY=2
retry npm run test-jasmine -- $SUITE --skip-tags=gl,noCI,flaky || EXIT_STATE=$?

exit $EXIT_STATE
;;

webgl-jasmine)
SHARDS=($(node $ROOT/tasks/shard_jasmine_tests.js --limit=5 --tag=gl | circleci tests split))
SHARDS=($(node $ROOT/tasks/shard_jasmine_tests.js --limit=5 --tag=gl | node "$SPLIT"))
for s in ${SHARDS[@]}; do
MAX_AUTO_RETRY=2
retry npm run test-jasmine -- "$s" --tags=gl --skip-tags=noCI --doNotFailOnEmptyTestSuite
Expand All @@ -54,7 +60,7 @@ case $1 in
;;

virtual-webgl-jasmine)
SHARDS=($(node $ROOT/tasks/shard_jasmine_tests.js --limit=5 --tag=gl | circleci tests split))
SHARDS=($(node $ROOT/tasks/shard_jasmine_tests.js --limit=5 --tag=gl | node "$SPLIT"))
for s in ${SHARDS[@]}; do
MAX_AUTO_RETRY=2
retry ./node_modules/karma/bin/karma start test/jasmine/karma.conf.js --virtualWebgl --tags=gl --skip-tags=noCI,noVirtualWebgl --doNotFailOnEmptyTestSuite -- "$s"
Expand All @@ -64,7 +70,7 @@ case $1 in
;;

flaky-no-gl-jasmine)
SHARDS=($(node $ROOT/tasks/shard_jasmine_tests.js --limit=1 --tag=flaky | circleci tests split))
SHARDS=($(node $ROOT/tasks/shard_jasmine_tests.js --limit=1 --tag=flaky | node "$SPLIT"))

for s in ${SHARDS[@]}; do
MAX_AUTO_RETRY=5
Expand Down Expand Up @@ -96,40 +102,46 @@ case $1 in
SUITE=$({\
find $ROOT/test/image/mocks/gl* -type f -printf "%f\n"; \
find $ROOT/test/image/mocks/map* -type f -printf "%f\n"; \
} | sed 's/\.json$//1' | circleci tests split)
sudo python3 test/image/make_baseline.py virtual-webgl $SUITE || EXIT_STATE=$?
} | sed 's/\.json$//1' | sort | node "$SPLIT")
python test/image/make_baseline.py virtual-webgl $SUITE || EXIT_STATE=$?
exit $EXIT_STATE
;;

make-baselines-mathjax3)
sudo python3 test/image/make_baseline.py mathjax3 legend_mathjax_title_and_items mathjax parcats_grid_subplots table_latex_multitrace_scatter table_plain_birds table_wrapped_birds ternary-mathjax ternary-mathjax-title-place-subtitle || EXIT_STATE=$?
MATHJAX3_MOCKS=$(jq -r '.compare_mathjax3 | join(" ")' test/image/compare_pixels_collections.json)
python test/image/make_baseline.py mathjax3 $MATHJAX3_MOCKS || EXIT_STATE=$?
exit $EXIT_STATE
;;

make-baselines-b64)
SUITE=$(find $ROOT/test/image/mocks/ -type f -printf "%f\n" | sed 's/\.json$//1' | circleci tests split)
sudo python3 test/image/make_baseline.py b64 $SUITE || EXIT_STATE=$?
SUITE=$(find $ROOT/test/image/mocks/ -type f -printf "%f\n" | sed 's/\.json$//1' | sort | node "$SPLIT")
python test/image/make_baseline.py b64 $SUITE || EXIT_STATE=$?
exit $EXIT_STATE
;;

make-baselines)
SUITE=$(find $ROOT/test/image/mocks/ -type f -printf "%f\n" | sed 's/\.json$//1' | circleci tests split)
sudo python3 test/image/make_baseline.py $SUITE || EXIT_STATE=$?
SUITE=$(find $ROOT/test/image/mocks/ -type f -printf "%f\n" | sed 's/\.json$//1' | sort | node "$SPLIT")
python test/image/make_baseline.py $SUITE || EXIT_STATE=$?
exit $EXIT_STATE
;;

make-exports)
python test/image/make_exports.py || EXIT_STATE=$?
exit $EXIT_STATE
;;

test-image)
node test/image/compare_pixels_test.js || { tar -cvf build/baselines.tar build/test_images/*.png ; exit 1 ; } || EXIT_STATE=$?
node test/image/compare_pixels_test.mjs || EXIT_STATE=$?
exit $EXIT_STATE
;;

test-image-mathjax3)
node test/image/compare_pixels_test.js mathjax3 || { tar -cvf build/baselines.tar build/test_images/*.png ; exit 1 ; } || EXIT_STATE=$?
node test/image/compare_pixels_test.mjs mathjax3 || EXIT_STATE=$?
exit $EXIT_STATE
;;

test-image-virtual-webgl)
node test/image/compare_pixels_test.js virtual-webgl || { tar -cvf build/baselines.tar build/test_images/*.png ; exit 1 ; } || EXIT_STATE=$?
node test/image/compare_pixels_test.mjs virtual-webgl || EXIT_STATE=$?
exit $EXIT_STATE
;;

Expand Down
Loading
Loading