From 040d976665d4e31bdf72f132bedb2e24ec3ca827 Mon Sep 17 00:00:00 2001 From: cvanelteren Date: Fri, 12 Dec 2025 17:59:20 +1000 Subject: [PATCH 01/11] replace images with hashes --- .github/workflows/build-ultraplot.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-ultraplot.yml b/.github/workflows/build-ultraplot.yml index 7d6f1660..8ff091b5 100644 --- a/.github/workflows/build-ultraplot.yml +++ b/.github/workflows/build-ultraplot.yml @@ -78,7 +78,7 @@ jobs: git checkout ${{ github.event.pull_request.base.sha }} python -c "import ultraplot as plt; plt.config.Configurator()._save_yaml('ultraplot.yml')" pytest -W ignore \ - --mpl-generate-path=./baseline/ \ + --mpl-generate-hash-library=./baseline/baseline_hashes.json\ --mpl-default-style="./ultraplot.yml"\ ultraplot/tests git checkout ${{ github.sha }} # Return to PR branch @@ -89,7 +89,7 @@ jobs: python -c "import ultraplot as plt; plt.config.Configurator()._save_yaml('ultraplot.yml')" pytest -W ignore \ --mpl \ - --mpl-baseline-path=./baseline/ \ + --mpl-hash-library=./baseline/baseline_hashes.json\ --mpl-results-path=./results/ \ --mpl-generate-summary=html \ --mpl-default-style="./ultraplot.yml" \ From c4f2b9c27f35068819b6824418ae4ad24f4e9636 Mon Sep 17 00:00:00 2001 From: cvanelteren Date: Fri, 12 Dec 2025 18:19:22 +1000 Subject: [PATCH 02/11] hashes need baselines --- .github/workflows/build-ultraplot.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-ultraplot.yml b/.github/workflows/build-ultraplot.yml index 8ff091b5..77fa3874 100644 --- a/.github/workflows/build-ultraplot.yml +++ b/.github/workflows/build-ultraplot.yml @@ -78,6 +78,7 @@ jobs: git checkout ${{ github.event.pull_request.base.sha }} python -c "import ultraplot as plt; plt.config.Configurator()._save_yaml('ultraplot.yml')" pytest -W ignore \ + --mpl-generate-path=./baseline/ \ --mpl-generate-hash-library=./baseline/baseline_hashes.json\ --mpl-default-style="./ultraplot.yml"\ ultraplot/tests From ac60058f136bdee9a77846bf04742cb1da597322 Mon Sep 17 00:00:00 2001 From: cvanelteren Date: Fri, 12 Dec 2025 20:24:26 +1000 Subject: [PATCH 03/11] use github cache --- .github/workflows/build-ultraplot.yml | 40 ++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-ultraplot.yml b/.github/workflows/build-ultraplot.yml index 77fa3874..7574c6bc 100644 --- a/.github/workflows/build-ultraplot.yml +++ b/.github/workflows/build-ultraplot.yml @@ -71,30 +71,56 @@ jobs: cache-environment: true cache-downloads: false + # Cache Baseline Figures (Restore step) + - name: Cache Baseline Figures + id: cache-baseline + uses: actions/cache@v4 + with: + path: ./baseline # The directory to cache + # Key is based on OS, Python/Matplotlib versions, and the base commit SHA + key: ${{ runner.os }}-baseline-${{ inputs.python-version }}-${{ inputs.matplotlib-version }}-${{ github.event.pull_request.base.sha }} + restore-keys: | + ${{ runner.os }}-baseline-${{ inputs.python-version }}-${{ inputs.matplotlib-version }}- + + # Conditional Baseline Generation (Only runs on cache miss) - name: Generate baseline from main + # Skip this step if the cache was found (cache-hit is true) + if: steps.cache-baseline.outputs.cache-hit != 'true' run: | mkdir -p baseline + # Checkout the base branch (e.g., 'main') to generate the official baseline git fetch origin ${{ github.event.pull_request.base.sha }} git checkout ${{ github.event.pull_request.base.sha }} + + # Install the Ultraplot version from the base branch's code + pip install --no-build-isolation --no-deps . + + # Generate the baseline images and hash library python -c "import ultraplot as plt; plt.config.Configurator()._save_yaml('ultraplot.yml')" pytest -W ignore \ --mpl-generate-path=./baseline/ \ --mpl-generate-hash-library=./baseline/baseline_hashes.json\ --mpl-default-style="./ultraplot.yml"\ ultraplot/tests - git checkout ${{ github.sha }} # Return to PR branch + # Return to the PR branch for the rest of the job + git checkout ${{ github.sha }} + + # Image Comparison (Uses cached or newly generated baseline) - name: Image Comparison Ultraplot run: | + # Re-install the Ultraplot version from the current PR branch + pip install --no-build-isolation --no-deps . + mkdir -p results python -c "import ultraplot as plt; plt.config.Configurator()._save_yaml('ultraplot.yml')" pytest -W ignore \ - --mpl \ - --mpl-hash-library=./baseline/baseline_hashes.json\ - --mpl-results-path=./results/ \ - --mpl-generate-summary=html \ - --mpl-default-style="./ultraplot.yml" \ - ultraplot/tests + --mpl \ + --mpl-hash-library=./baseline/baseline_hashes.json\ + --mpl-results-path=./results/ \ + --mpl-generate-summary=html \ + --mpl-default-style="./ultraplot.yml" \ + ultraplot/tests # Return the html output of the comparison even if failed - name: Upload comparison failures From 21855b6071c20abd22c5efefd6541f9c2689ab7a Mon Sep 17 00:00:00 2001 From: cvanelteren Date: Tue, 30 Dec 2025 21:51:36 +1000 Subject: [PATCH 04/11] add pytest-xdist --- .github/workflows/build-ultraplot.yml | 4 ++-- environment.yml | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-ultraplot.yml b/.github/workflows/build-ultraplot.yml index 7574c6bc..cf06e79f 100644 --- a/.github/workflows/build-ultraplot.yml +++ b/.github/workflows/build-ultraplot.yml @@ -97,7 +97,7 @@ jobs: # Generate the baseline images and hash library python -c "import ultraplot as plt; plt.config.Configurator()._save_yaml('ultraplot.yml')" - pytest -W ignore \ + pytest -W ignore -n auto \ --mpl-generate-path=./baseline/ \ --mpl-generate-hash-library=./baseline/baseline_hashes.json\ --mpl-default-style="./ultraplot.yml"\ @@ -114,7 +114,7 @@ jobs: mkdir -p results python -c "import ultraplot as plt; plt.config.Configurator()._save_yaml('ultraplot.yml')" - pytest -W ignore \ + pytest -W ignore -n auto\ --mpl \ --mpl-hash-library=./baseline/baseline_hashes.json\ --mpl-results-path=./results/ \ diff --git a/environment.yml b/environment.yml index 2e9519a3..764a47f3 100644 --- a/environment.yml +++ b/environment.yml @@ -12,6 +12,7 @@ dependencies: - pytest - pytest-mpl - pytest-cov + - pytest-xdist - jupyter - pip - pint From ee32d4ce6b8788f65abad1ef392d20019502e758 Mon Sep 17 00:00:00 2001 From: cvanelteren Date: Tue, 30 Dec 2025 21:52:48 +1000 Subject: [PATCH 05/11] dummy commit --- ultraplot/axes/cartesian.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/ultraplot/axes/cartesian.py b/ultraplot/axes/cartesian.py index 46685b5d..6eb09f80 100644 --- a/ultraplot/axes/cartesian.py +++ b/ultraplot/axes/cartesian.py @@ -5,22 +5,27 @@ import copy import inspect +import matplotlib.axis as maxis import matplotlib.dates as mdates import matplotlib.ticker as mticker import numpy as np - from packaging import version from .. import constructor from .. import scale as pscale from .. import ticker as pticker from ..config import rc -from ..internals import ic # noqa: F401 -from ..internals import _not_none, _pop_rc, _version_mpl, docstring, labels, warnings -from . import plot, shared -import matplotlib.axis as maxis - +from ..internals import ( + _not_none, + _pop_rc, + _version_mpl, + docstring, + ic, # noqa: F401 + labels, + warnings, +) from ..utils import units +from . import plot, shared __all__ = ["CartesianAxes"] From 5ad47fe3adef2e6cfa8e01389df06ea4d4aad1d5 Mon Sep 17 00:00:00 2001 From: cvanelteren Date: Tue, 30 Dec 2025 21:57:09 +1000 Subject: [PATCH 06/11] add xdist to tests --- .github/workflows/build-ultraplot.yml | 2 +- ultraplot/axes/cartesian.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-ultraplot.yml b/.github/workflows/build-ultraplot.yml index cf06e79f..858f383c 100644 --- a/.github/workflows/build-ultraplot.yml +++ b/.github/workflows/build-ultraplot.yml @@ -43,7 +43,7 @@ jobs: - name: Test Ultraplot run: | - pytest --cov=ultraplot --cov-branch --cov-report term-missing --cov-report=xml ultraplot + pytest -n auto --cov=ultraplot --cov-branch --cov-report term-missing --cov-report=xml ultraplot - name: Upload coverage reports to Codecov uses: codecov/codecov-action@v5 diff --git a/ultraplot/axes/cartesian.py b/ultraplot/axes/cartesian.py index 6eb09f80..f85f30ca 100644 --- a/ultraplot/axes/cartesian.py +++ b/ultraplot/axes/cartesian.py @@ -1564,6 +1564,7 @@ def get_tightbbox(self, renderer, *args, **kwargs): return super().get_tightbbox(renderer, *args, **kwargs) +# tmp # Apply signature obfuscation after storing previous signature # NOTE: This is needed for __init__, altx, and alty CartesianAxes._format_signatures[CartesianAxes] = inspect.signature( From 6a3982a9037f024f4c1c0c9f92d28c59d10cb025 Mon Sep 17 00:00:00 2001 From: cvanelteren Date: Tue, 30 Dec 2025 22:22:54 +1000 Subject: [PATCH 07/11] rm threading on test --- .github/workflows/build-ultraplot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-ultraplot.yml b/.github/workflows/build-ultraplot.yml index 858f383c..7d98e6b2 100644 --- a/.github/workflows/build-ultraplot.yml +++ b/.github/workflows/build-ultraplot.yml @@ -97,7 +97,7 @@ jobs: # Generate the baseline images and hash library python -c "import ultraplot as plt; plt.config.Configurator()._save_yaml('ultraplot.yml')" - pytest -W ignore -n auto \ + pytest -W ignore \ --mpl-generate-path=./baseline/ \ --mpl-generate-hash-library=./baseline/baseline_hashes.json\ --mpl-default-style="./ultraplot.yml"\ From 69e92ef6ab9e8de6b19af262e90865cc9764e188 Mon Sep 17 00:00:00 2001 From: cvanelteren Date: Thu, 1 Jan 2026 14:41:37 +1000 Subject: [PATCH 08/11] Fix mpl baseline path in CI --- .github/workflows/build-ultraplot.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-ultraplot.yml b/.github/workflows/build-ultraplot.yml index 7d98e6b2..7cef46d1 100644 --- a/.github/workflows/build-ultraplot.yml +++ b/.github/workflows/build-ultraplot.yml @@ -76,7 +76,7 @@ jobs: id: cache-baseline uses: actions/cache@v4 with: - path: ./baseline # The directory to cache + path: ./ultraplot/tests/baseline # The directory to cache # Key is based on OS, Python/Matplotlib versions, and the base commit SHA key: ${{ runner.os }}-baseline-${{ inputs.python-version }}-${{ inputs.matplotlib-version }}-${{ github.event.pull_request.base.sha }} restore-keys: | @@ -87,7 +87,7 @@ jobs: # Skip this step if the cache was found (cache-hit is true) if: steps.cache-baseline.outputs.cache-hit != 'true' run: | - mkdir -p baseline + mkdir -p ultraplot/tests/baseline # Checkout the base branch (e.g., 'main') to generate the official baseline git fetch origin ${{ github.event.pull_request.base.sha }} git checkout ${{ github.event.pull_request.base.sha }} @@ -98,8 +98,8 @@ jobs: # Generate the baseline images and hash library python -c "import ultraplot as plt; plt.config.Configurator()._save_yaml('ultraplot.yml')" pytest -W ignore \ - --mpl-generate-path=./baseline/ \ - --mpl-generate-hash-library=./baseline/baseline_hashes.json\ + --mpl-generate-path=./ultraplot/tests/baseline/ \ + --mpl-generate-hash-library=./ultraplot/tests/baseline/baseline_hashes.json\ --mpl-default-style="./ultraplot.yml"\ ultraplot/tests @@ -116,7 +116,7 @@ jobs: python -c "import ultraplot as plt; plt.config.Configurator()._save_yaml('ultraplot.yml')" pytest -W ignore -n auto\ --mpl \ - --mpl-hash-library=./baseline/baseline_hashes.json\ + --mpl-hash-library=./ultraplot/tests/baseline/baseline_hashes.json\ --mpl-results-path=./results/ \ --mpl-generate-summary=html \ --mpl-default-style="./ultraplot.yml" \ From f99cdbe795e6e3a3e44fd0921c235c91baa0ee06 Mon Sep 17 00:00:00 2001 From: cvanelteren Date: Thu, 1 Jan 2026 14:58:36 +1000 Subject: [PATCH 09/11] add xdist --- .github/workflows/build-ultraplot.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-ultraplot.yml b/.github/workflows/build-ultraplot.yml index 7cef46d1..effcf690 100644 --- a/.github/workflows/build-ultraplot.yml +++ b/.github/workflows/build-ultraplot.yml @@ -97,7 +97,7 @@ jobs: # Generate the baseline images and hash library python -c "import ultraplot as plt; plt.config.Configurator()._save_yaml('ultraplot.yml')" - pytest -W ignore \ + pytest -n auto -W ignore \ --mpl-generate-path=./ultraplot/tests/baseline/ \ --mpl-generate-hash-library=./ultraplot/tests/baseline/baseline_hashes.json\ --mpl-default-style="./ultraplot.yml"\ @@ -114,7 +114,7 @@ jobs: mkdir -p results python -c "import ultraplot as plt; plt.config.Configurator()._save_yaml('ultraplot.yml')" - pytest -W ignore -n auto\ + pytest -n auto -W ignore -n auto\ --mpl \ --mpl-hash-library=./ultraplot/tests/baseline/baseline_hashes.json\ --mpl-results-path=./results/ \ From d740ba727a842d37d9620f1d14cf0235a5e4a9f9 Mon Sep 17 00:00:00 2001 From: cvanelteren Date: Thu, 1 Jan 2026 15:31:38 +1000 Subject: [PATCH 10/11] Fix hash library regen and add pytest -x --- .github/workflows/build-ultraplot.yml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-ultraplot.yml b/.github/workflows/build-ultraplot.yml index effcf690..3de2a6d5 100644 --- a/.github/workflows/build-ultraplot.yml +++ b/.github/workflows/build-ultraplot.yml @@ -82,10 +82,19 @@ jobs: restore-keys: | ${{ runner.os }}-baseline-${{ inputs.python-version }}-${{ inputs.matplotlib-version }}- + - name: Check baseline hash library + id: baseline-hash + run: | + if [ -f "./ultraplot/tests/baseline/baseline_hashes.json" ]; then + echo "exists=true" >> "$GITHUB_OUTPUT" + else + echo "exists=false" >> "$GITHUB_OUTPUT" + fi + # Conditional Baseline Generation (Only runs on cache miss) - name: Generate baseline from main # Skip this step if the cache was found (cache-hit is true) - if: steps.cache-baseline.outputs.cache-hit != 'true' + if: steps.cache-baseline.outputs.cache-hit != 'true' || steps.baseline-hash.outputs.exists != 'true' run: | mkdir -p ultraplot/tests/baseline # Checkout the base branch (e.g., 'main') to generate the official baseline @@ -97,7 +106,7 @@ jobs: # Generate the baseline images and hash library python -c "import ultraplot as plt; plt.config.Configurator()._save_yaml('ultraplot.yml')" - pytest -n auto -W ignore \ + pytest -x -n auto -W ignore \ --mpl-generate-path=./ultraplot/tests/baseline/ \ --mpl-generate-hash-library=./ultraplot/tests/baseline/baseline_hashes.json\ --mpl-default-style="./ultraplot.yml"\ @@ -114,7 +123,7 @@ jobs: mkdir -p results python -c "import ultraplot as plt; plt.config.Configurator()._save_yaml('ultraplot.yml')" - pytest -n auto -W ignore -n auto\ + pytest -x -n auto -W ignore -n auto\ --mpl \ --mpl-hash-library=./ultraplot/tests/baseline/baseline_hashes.json\ --mpl-results-path=./results/ \ From 1f1141b8626428b14eba3c04e0f0efcb6f317a2c Mon Sep 17 00:00:00 2001 From: cvanelteren Date: Thu, 1 Jan 2026 15:42:43 +1000 Subject: [PATCH 11/11] Version hash library by Python and Matplotlib --- .github/workflows/build-ultraplot.yml | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/.github/workflows/build-ultraplot.yml b/.github/workflows/build-ultraplot.yml index 3de2a6d5..745e0f7b 100644 --- a/.github/workflows/build-ultraplot.yml +++ b/.github/workflows/build-ultraplot.yml @@ -77,24 +77,15 @@ jobs: uses: actions/cache@v4 with: path: ./ultraplot/tests/baseline # The directory to cache - # Key is based on OS, Python/Matplotlib versions, and the base commit SHA - key: ${{ runner.os }}-baseline-${{ inputs.python-version }}-${{ inputs.matplotlib-version }}-${{ github.event.pull_request.base.sha }} + # Key is based on OS, Python/Matplotlib versions, and the PR number + key: ${{ runner.os }}-baseline-pr-${{ github.event.pull_request.number }}-${{ inputs.python-version }}-${{ inputs.matplotlib-version }} restore-keys: | - ${{ runner.os }}-baseline-${{ inputs.python-version }}-${{ inputs.matplotlib-version }}- - - - name: Check baseline hash library - id: baseline-hash - run: | - if [ -f "./ultraplot/tests/baseline/baseline_hashes.json" ]; then - echo "exists=true" >> "$GITHUB_OUTPUT" - else - echo "exists=false" >> "$GITHUB_OUTPUT" - fi + ${{ runner.os }}-baseline-pr-${{ github.event.pull_request.number }}-${{ inputs.python-version }}-${{ inputs.matplotlib-version }}- # Conditional Baseline Generation (Only runs on cache miss) - name: Generate baseline from main # Skip this step if the cache was found (cache-hit is true) - if: steps.cache-baseline.outputs.cache-hit != 'true' || steps.baseline-hash.outputs.exists != 'true' + if: steps.cache-baseline.outputs.cache-hit != 'true' run: | mkdir -p ultraplot/tests/baseline # Checkout the base branch (e.g., 'main') to generate the official baseline @@ -108,7 +99,6 @@ jobs: python -c "import ultraplot as plt; plt.config.Configurator()._save_yaml('ultraplot.yml')" pytest -x -n auto -W ignore \ --mpl-generate-path=./ultraplot/tests/baseline/ \ - --mpl-generate-hash-library=./ultraplot/tests/baseline/baseline_hashes.json\ --mpl-default-style="./ultraplot.yml"\ ultraplot/tests @@ -125,7 +115,7 @@ jobs: python -c "import ultraplot as plt; plt.config.Configurator()._save_yaml('ultraplot.yml')" pytest -x -n auto -W ignore -n auto\ --mpl \ - --mpl-hash-library=./ultraplot/tests/baseline/baseline_hashes.json\ + --mpl-baseline-path=./ultraplot/tests/baseline \ --mpl-results-path=./results/ \ --mpl-generate-summary=html \ --mpl-default-style="./ultraplot.yml" \