Skip to content

Vertex.new_edge: resolve both ends by record id on the JVM build #378

Vertex.new_edge: resolve both ends by record id on the JVM build

Vertex.new_edge: resolve both ends by record id on the JVM build #378

# Runs examples/ against the `arcadedb-jvm` wheel. The wheel is py3-none-<platform tag> (setup.py): the `build` job builds it once for each
# platform, and the `test-examples` job installs that one file into each Python and runs the examples. Nothing is built per Python.
name: Test Python Examples
on:
push:
branches: [main]
paths-ignore:
# Changes that cannot alter what these jobs build or run. README.md and
# tests/README.md are deliberately NOT here: the wheel build copies README.md
# (scripts/Dockerfile.build, pyproject `readme`) and test_no_monorepo_wording.py
# reads both. docs/** is safe to skip while tests/conftest.py collect-ignores
# test_docs_examples.py (it needs docs/index.md); if that Markdown site comes
# back, take docs/** out of this list. Schedule, dispatch and workflow_call
# ignore these filters and always run everything.
- "docs/**"
- "**/*.adoc"
- "CLAUDE.md"
- "examples/README.md"
- "LICENSE*"
# the native build has its own workflows; nothing under native/ is in the JVM wheel
- "native/**"
- ".github/workflows/test-native.yml"
- ".github/workflows/release-native.yml"
- "scripts/native_examples_skip.txt"
pull_request:
# ready_for_review: draft PRs skip the platform matrices (see the job conditions),
# so marking one ready is what starts them.
types: [opened, synchronize, reopened, ready_for_review]
paths-ignore:
# Same list as under push.
- "docs/**"
- "**/*.adoc"
- "CLAUDE.md"
- "examples/README.md"
- "LICENSE*"
# the native build has its own workflows; nothing under native/ is in the JVM wheel
- "native/**"
- ".github/workflows/test-native.yml"
- ".github/workflows/release-native.yml"
- "scripts/native_examples_skip.txt"
# A new upstream snapshot is published as arcadedata/arcadedb:latest without
# any change here, so build and test against it every night as well. The tag
# moves (ARCADEDB_IMAGE_TAG defaults to latest), so a night with no commit
# here still tests a new engine; that is why there is no skip-if-main-unchanged
# guard. One nightly per workflow, staggered an hour apart.
schedule:
- cron: "0 4 * * *"
# Allow being called by other workflows (release-jvm.yml)
workflow_call:
inputs:
arcadedb-tag:
description: "arcadedata/arcadedb image tag to take the jars from (e.g. 26.10.2); default latest"
required: false
type: string
default: "latest"
examples:
description: "Glob pattern(s) for examples to run (space-separated, relative to examples)."
required: false
type: string
default: "0[1-9]_*.py 1[0-9]_*.py 2[0-9]_*.py"
build-version:
description: "Override package version (PEP 440) for build.sh"
required: false
type: string
# Allow manual trigger
workflow_dispatch:
inputs:
arcadedb-tag:
description: "arcadedata/arcadedb image tag to take the jars from (e.g. 26.10.2); default latest"
required: false
default: "latest"
examples:
description: "Glob pattern(s) for examples to run (space-separated, relative to examples)."
required: false
default: "0[1-9]_*.py 1[0-9]_*.py 2[0-9]_*.py"
# SUPERSEDE, do not race (same rule in test-jvm.yml).
#
# A force-push to a PR branch left the OLD run going alongside the new one: on
# #6889 both 118b347ce and 75293c7a2 ran at once, and the stale one reported a
# failure that the newer commit had already fixed. Anyone reading the PR sees a
# red check against work that is done. The stale run also holds macOS/Windows
# runners the organisation shares with ArcadeData/arcadedb.
#
# cancel-in-progress is scoped to pull_request ONLY. On a push to a long-lived
# branch a superseded run is often the one you still want -- it is the record
# for that commit -- so those are left to finish, and they get a group of their
# own (run_id) so a queued push or nightly run is not replaced by a newer one
# either. The group names the workflow literally: github.workflow is the
# CALLER's name in a workflow_call, which would put this workflow and its
# sibling in one group.
concurrency:
group: test-python-examples-${{ github.event.pull_request.number || github.run_id }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
env:
# The image download-jars takes the jars from. Unset (push, pull_request, schedule)
# means latest; a release build passes its tag.
ARCADEDB_IMAGE_TAG: ${{ inputs.arcadedb-tag || 'latest' }}
EXAMPLES: ${{ inputs.examples || '0[1-9]_*.py 1[0-9]_*.py 2[0-9]_*.py' }}
# Note: Example 21 runs in CI at reduced scale; its arguments and 15-minute
# limit are set in the per-example case in scripts/run_examples.sh, which the
# "Download datasets" and "Run all examples" steps call. test-native.yml calls
# the same script on the native wheel.
permissions:
contents: read
jobs:
# First job: Download ArcadeDB JARs (platform-agnostic)
download-jars:
name: Download ArcadeDB JARs
runs-on: ubuntu-24.04
# Draft PRs skip the whole workflow; marking the PR ready starts it.
if: github.event_name != 'pull_request' || github.event.pull_request.draft == false
outputs:
arcadedb-tag: ${{ steps.jars.outputs.arcadedb-tag }}
matrix: ${{ steps.matrix.outputs.matrix }}
wheel-matrix: ${{ steps.matrix.outputs.wheel-matrix }}
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
# The platform x Python legs of this run (scripts/select_matrix.py): a small matrix on
# pull requests, the full one on every other event. The organisation shares one runner
# cap with ArcadeData/arcadedb, so a pull request does not run every combination.
# The wheel matrix is the platforms of those legs, one build each: the wheel is
# py3-none-<platform>, the same file for every Python.
# Done first, so a failure here costs no Docker pull.
- name: Select the test matrix
id: matrix
shell: bash
env:
EVENT_NAME: ${{ github.event_name }}
run: |
matrix="$(python3 scripts/select_matrix.py examples --event "$EVENT_NAME")"
wheel_matrix="$(python3 scripts/select_matrix.py examples --event "$EVENT_NAME" --wheels)"
echo "$matrix"
echo "$wheel_matrix"
echo "matrix=$matrix" >> "$GITHUB_OUTPUT"
echo "wheel-matrix=$wheel_matrix" >> "$GITHUB_OUTPUT"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
- name: Download JARs from ArcadeDB Docker image
id: jars
shell: bash
run: |
# Download JARs from the official Docker image: ARCADEDB_IMAGE_TAG,
# `latest` (upstream's current snapshot) unless the caller pinned a tag. Every build job, Linux included, builds
# from these jars (the artifact below), not from its own pull: upstream
# re-pushes the snapshot tag on every deploy, so a pull per job could put
# two different engine builds under one version in a single run.
echo "📦 Downloading JARs from arcadedata/arcadedb:${ARCADEDB_IMAGE_TAG}..."
# Create output directory
mkdir -p src/arcadedb/jars
# Create a temporary container and copy JARs from it
CONTAINER_ID=$(docker create "arcadedata/arcadedb:${ARCADEDB_IMAGE_TAG}")
docker cp $CONTAINER_ID:/home/arcadedb/lib/. src/arcadedb/jars/
docker rm $CONTAINER_ID
echo "✅ Downloaded $(ls -1 src/arcadedb/jars/*.jar | wc -l) JARs"
ARCADEDB_TAG=$(python3 scripts/extract_version.py src/arcadedb/jars --format=docker)
echo "📌 ArcadeDB version: $ARCADEDB_TAG"
# The build jobs pull arcadedata/arcadedb:<jar version> as their base image,
# so a pinned tag must name that version exactly (26.10.2, not an alias).
if [ "$ARCADEDB_IMAGE_TAG" != "latest" ] && [ "$ARCADEDB_IMAGE_TAG" != "$ARCADEDB_TAG" ]; then
echo "❌ arcadedb-tag '$ARCADEDB_IMAGE_TAG' holds engine $ARCADEDB_TAG; pass the exact version tag"
exit 1
fi
echo "arcadedb-tag=$ARCADEDB_TAG" >> "$GITHUB_OUTPUT"
# Unfiltered on purpose: build-native.sh applies scripts/jar_exclusions.txt
# to whatever lands in the jars directory, so the list lives in one place.
- name: Upload JARs as artifact
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: arcadedb-jars-examples
path: src/arcadedb/jars/*.jar
retention-days: 1
# Second job: build the wheel of each platform, once. The wheel is py3-none-<platform tag> (setup.py), so the file built here is
# the one every Python of the test-examples job below installs: nothing is built per Python. build.sh takes a Python only for the
# Linux container that builds and smoke-tests the wheel; any of them gives the same file. It also checks the size, the licences
# and the tag of the wheel, as in test-jvm.yml.
build:
name: Build wheel for examples (${{ matrix.platform }})
runs-on: ${{ matrix.runs-on }}
needs: download-jars
if: github.event_name != 'pull_request' || github.event.pull_request.draft == false
env:
BUILD_VERSION: ${{ inputs.build-version }}
strategy:
fail-fast: false
# One leg per platform of the test matrix, from the "Select the test matrix" step of download-jars
# (scripts/select_matrix.py --wheels): {"include": [{"platform": ..., "runs-on": ...}, ...]}.
matrix: ${{ fromJSON(needs.download-jars.outputs.wheel-matrix) }}
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Download JARs artifact
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: arcadedb-jars-examples
path: src/arcadedb/jars
- name: Set up Java (for native builds on macOS/Windows)
if: matrix.platform != 'linux/amd64' && matrix.platform != 'linux/arm64'
uses: actions/setup-java@b843ebf9b913146b38da2eaa7aeddf76074ae1ad # v6.1.0
with:
distribution: 'corretto'
java-version: '25'
- name: Set up Docker Buildx (Linux only)
if: matrix.platform == 'linux/amd64' || matrix.platform == 'linux/arm64'
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
- name: Set up Python
uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0
with:
python-version: "3.12"
- name: Setup UV package manager
shell: bash
run: |
# Retry transient network failures (a connection reset failed a whole examples job on #8897); the
# script is downloaded first so a retried transfer is never piped half-written into sh.
installer="$(mktemp)"
curl -LsSf --retry 5 --retry-all-errors --retry-delay 5 -o "$installer" https://astral.sh/uv/0.12.0/install.sh
sh "$installer"
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
export PATH="$HOME/.local/bin:$PATH"
uv --version
- name: Set UTF-8 encoding (Windows only)
if: matrix.platform == 'windows/amd64' || matrix.platform == 'windows/arm64'
shell: bash
run: |
echo "PYTHONIOENCODING=utf-8" >> $GITHUB_ENV
echo "PYTHONUTF8=1" >> $GITHUB_ENV
# Windows currently enabled, no symlink needed
# - name: Create python3 symlink (Windows only)
# if: matrix.platform == 'windows/amd64' || matrix.platform == 'windows/arm64'
# shell: bash
# run: |
# PYTHON_DIR=$(dirname "$(which python)")
# ln -s "$PYTHON_DIR/python.exe" "$PYTHON_DIR/python3.exe" || true
# python3 --version
- name: Build arcadedb (${{ matrix.platform }})
shell: bash
env:
# The engine version download-jars read from the ARCADEDB_IMAGE_TAG jars;
# the Docker build takes its base image by this tag, the jars from the artifact
ARCADEDB_TAG: ${{ needs.download-jars.outputs.arcadedb-tag }}
run: |
echo "🔨 Building arcadedb-jvm for ${{ matrix.platform }}..."
# The jars download-jars fetched, on every platform, so all wheels of this
# run carry the same engine build (and build.sh checks the integration jar)
./scripts/build.sh ${{ matrix.platform }} 3.12 src/arcadedb/jars
# build.sh already ran this (and the size check); it is repeated here as in test-jvm.yml, so the tag shows in this job's log and
# summary and a change to build.sh cannot drop it unnoticed. The wheel must be py3-none-<platform>, the file every Python installs.
- name: Check the wheel tag
shell: bash
run: |
python scripts/verify_wheel_tag.py dist/*.whl
{
echo "## 📦 Wheel: arcadedb-jvm (${{ matrix.platform }})"
echo
for w in dist/*.whl; do
echo "- \`$(basename "$w")\`, $(du -m "$w" | cut -f1) MB"
done
} >> "$GITHUB_STEP_SUMMARY"
# One wheel per platform, for the test-examples legs of that platform. Named examples-wheel-<platform>, not wheel-<platform>:
# a release runs this workflow and test-jvm.yml in one run, and release-jvm.yml publishes every wheel-* artifact.
- name: Upload wheel artifact
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: examples-wheel-${{ matrix.platform == 'linux/amd64' && 'linux-amd64' || matrix.platform == 'linux/arm64' && 'linux-arm64' || matrix.platform == 'darwin/amd64' && 'darwin-amd64' || matrix.platform == 'darwin/arm64' && 'darwin-arm64' || matrix.platform == 'windows/amd64' && 'windows-amd64' || 'windows-arm64' }}
path: dist/*.whl
if-no-files-found: error
retention-days: 1
# Third job: install the wheel of the platform into each Python and run the examples. Nothing is built here: the wheel is
# the file the build job made (py3-none-<platform tag>), so each Python runs the examples against the same file that is published.
test-examples:
name: Test Python Examples (${{ matrix.platform }}, Python ${{ matrix.python-version }})
runs-on: ${{ matrix.runs-on }}
needs: [download-jars, build]
if: github.event_name != 'pull_request' || github.event.pull_request.draft == false
env:
# Pin the Hugging Face cache inside the workspace so it is cacheable with
# one path on every platform (the default differs per OS). The examples
# embed with sentence-transformers, and the full matrix is 16 jobs, so
# uncached that is 16 independent model downloads per release and 16
# chances for a transient hub outage to fail a release. It has happened.
HF_HOME: ${{ github.workspace }}/.hf-cache
strategy:
fail-fast: false
# Chosen by the "Select the test matrix" step of download-jars from the event that
# started the run (scripts/select_matrix.py holds the platform and Python lists):
# small on pull requests, the full 4 platforms x 4 Pythons on every other event.
# Every leg carries platform, runs-on and python-version, so the job names stay
# "Test Python Examples (<platform>, Python <version>)".
matrix: ${{ fromJSON(needs.download-jars.outputs.matrix) }}
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Set up Python
uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0
with:
python-version: ${{ matrix.python-version }}
- name: Setup UV package manager
shell: bash
run: |
# Retry transient network failures (a connection reset failed a whole examples job on #8897); the
# script is downloaded first so a retried transfer is never piped half-written into sh.
installer="$(mktemp)"
curl -LsSf --retry 5 --retry-all-errors --retry-delay 5 -o "$installer" https://astral.sh/uv/0.12.0/install.sh
sh "$installer"
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
export PATH="$HOME/.local/bin:$PATH"
uv --version
# The wheel of this platform, built once by the build job and the same file for every Python.
- name: Download the wheel of ${{ matrix.platform }}
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: examples-wheel-${{ matrix.platform == 'linux/amd64' && 'linux-amd64' || matrix.platform == 'linux/arm64' && 'linux-arm64' || matrix.platform == 'darwin/amd64' && 'darwin-amd64' || matrix.platform == 'darwin/arm64' && 'darwin-arm64' || matrix.platform == 'windows/amd64' && 'windows-amd64' || 'windows-arm64' }}
path: test-install
# Note: Java is NOT required - arcadedb has bundled JRE!
# The wheel and the example dependencies live in a uv project of their own (examples-env/, not the repo's pyproject.toml,
# which is a package definition and not a uv project), synced with `uv sync`. Nothing is installed into the runner's Python.
# torch comes from the CPU-only PyTorch index (explicit: only torch is looked up there), which saves the CUDA download.
# PyTorch is required by sentence-transformers, even on macOS.
# numpy is not capped: the old macOS `numpy<2.0` was for Intel Macs, where PyTorch stops at 2.2 (built against
# NumPy 1.x). That leg (darwin/amd64) is disabled; re-enabling it needs the cap back for that platform only.
# On Apple Silicon the cap breaks pyarrow, which requires NumPy 2 (example 27).
- name: Install ArcadeDB Python bindings and example dependencies
shell: bash
env:
PYVER: ${{ matrix.python-version }}
run: |
wheels=(test-install/arcadedb_jvm-*.whl)
[ "${#wheels[@]}" -eq 1 ] || { echo "expected one wheel in test-install, found ${#wheels[@]}" >&2; exit 1; }
mkdir -p examples-env
cat > examples-env/pyproject.toml <<TOML
[project]
name = "examples-env"
version = "0"
requires-python = ">=3.11"
dependencies = [
"arcadedb-jvm",
"torch",
"numpy",
"requests",
"sentence-transformers",
"pandas",
"polars",
"pyarrow",
"tqdm",
"py7zr",
"lxml",
]
[tool.uv.sources]
arcadedb-jvm = { path = "../${wheels[0]}" }
torch = { index = "pytorch-cpu" }
[[tool.uv.index]]
name = "pytorch-cpu"
url = "https://download.pytorch.org/whl/cpu"
explicit = true
TOML
uv sync --project examples-env --python "$PYVER"
# The examples run with this interpreter directly, so a timeout kills the example itself and not a `uv run` wrapper.
ex_py="$(uv run --project examples-env --no-sync python -c 'import sys; print(sys.executable)')"
echo "EX_PY=$ex_py" >> "$GITHUB_ENV"
"$ex_py" -c "import arcadedb; print('arcadedb', arcadedb.__version__)"
# Restored before the dataset step, which is what triggers the model
# download. Keyed on the model name so bumping the model invalidates it.
- name: Cache Hugging Face model
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ${{ github.workspace }}/.hf-cache
key: hf-all-MiniLM-L6-v2-${{ runner.os }}-${{ runner.arch }}
restore-keys: |
hf-all-MiniLM-L6-v2-${{ runner.os }}-
# Pre-warm with bounded retries, separately from the dataset step, so a
# transient hub failure is retried here rather than surfacing mid-example
# as an OSError that reads like a bindings bug. Retrying is appropriate
# for this step specifically: it exercises third-party I/O, not our code.
# Deliberately NOT fail-fast: if the hub is truly down the dataset step
# below still runs and fails with its own message, so this cannot turn a
# real breakage into a silent skip.
- name: Pre-warm embedding model
shell: bash
continue-on-error: true
run: |
for attempt in 1 2 3; do
if "$EX_PY" -c "from sentence_transformers import SentenceTransformer; SentenceTransformer('all-MiniLM-L6-v2'); print('model ready')"; then
echo "✅ model cached on attempt $attempt"
exit 0
fi
echo "⚠️ model fetch failed (attempt $attempt/3)"
[ "$attempt" -lt 3 ] && sleep $((attempt * 20))
done
echo "::warning::could not pre-warm the embedding model after 3 attempts; the dataset step will retry"
- name: Download datasets
shell: bash
run: |
bash scripts/run_examples.sh datasets
- name: Install timeout command (macOS only)
if: matrix.platform == 'darwin/amd64' || matrix.platform == 'darwin/arm64'
shell: bash
run: |
# macOS doesn't have timeout command by default, use coreutils
brew install coreutils
- name: Set UTF-8 encoding (Windows only)
if: matrix.platform == 'windows/amd64' || matrix.platform == 'windows/arm64'
shell: bash
run: |
echo "PYTHONIOENCODING=utf-8" >> $GITHUB_ENV
echo "PYTHONUTF8=1" >> $GITHUB_ENV
- name: Run all examples
id: run_examples
shell: bash
run: |
bash scripts/run_examples.sh run
- name: Generate test summary
if: always()
shell: bash
run: |
cd examples
echo "## 🎮 Python Examples Test Results (${{ matrix.platform }})" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
total="${{ steps.run_examples.outputs.total || '0' }}"
passed="${{ steps.run_examples.outputs.passed || '0' }}"
failed="${{ steps.run_examples.outputs.failed || '0' }}"
if [ "${{ steps.run_examples.outcome }}" = "success" ]; then
echo "✅ **Status**: ALL EXAMPLES PASSED ($passed/$total)" >> $GITHUB_STEP_SUMMARY
else
echo "❌ **Status**: SOME EXAMPLES FAILED ($passed/$total passed)" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Metric | Count |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------:|" >> $GITHUB_STEP_SUMMARY
echo "| 📝 Total | $total |" >> $GITHUB_STEP_SUMMARY
echo "| ✅ Passed | $passed |" >> $GITHUB_STEP_SUMMARY
echo "| ❌ Failed | $failed |" >> $GITHUB_STEP_SUMMARY
echo "| ⏭️ Skipped | ${{ steps.run_examples.outputs.skipped || '0' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# Add detailed results if available
if [ -f example-results.txt ]; then
echo "### Detailed Results" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
cat example-results.txt >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Examples Tested" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Pattern(s)**: $EXAMPLES" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [ -f examples-ran.txt ]; then
while IFS= read -r example; do
[ -n "$example" ] && echo "- **$example**" >> $GITHUB_STEP_SUMMARY
done < examples-ran.txt
fi
echo "" >> $GITHUB_STEP_SUMMARY
- name: Upload example logs
if: always()
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: example-logs-${{ matrix.platform == 'linux/amd64' && 'linux-amd64' || matrix.platform == 'linux/arm64' && 'linux-arm64' || matrix.platform == 'darwin/amd64' && 'darwin-amd64' || matrix.platform == 'darwin/arm64' && 'darwin-arm64' || matrix.platform == 'windows/amd64' && 'windows-amd64' || 'windows-arm64' }}-py${{ matrix.python-version }}
path: |
examples/*.log
examples/example-results.txt
retention-days: 7
- name: Upload example databases
if: failure()
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: example-databases-${{ matrix.platform == 'linux/amd64' && 'linux-amd64' || matrix.platform == 'linux/arm64' && 'linux-arm64' || matrix.platform == 'darwin/amd64' && 'darwin-amd64' || matrix.platform == 'darwin/arm64' && 'darwin-arm64' || matrix.platform == 'windows/amd64' && 'windows-amd64' || 'windows-arm64' }}-py${{ matrix.python-version }}
path: examples/my_test_databases/
retention-days: 3
# Summary job that checks all platforms
test-examples-summary:
name: Examples Test Summary
needs: [build, test-examples]
runs-on: ubuntu-latest
# Skipped (not red) when the matrix was skipped for a draft PR.
if: always() && (github.event_name != 'pull_request' || github.event.pull_request.draft == false)
steps:
- name: Check test results
shell: bash
run: |
echo "## 🎯 Overall Examples Test Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [ "${{ needs.build.result }}" = "success" ] && [ "${{ needs.test-examples.result }}" = "success" ]; then
echo "✅ **All platforms passed example testing!**" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "All examples ran successfully across all enabled platforms, against one wheel built for each platform." >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Platforms tested**: linux/amd64, linux/arm64, darwin/arm64, windows/amd64" >> $GITHUB_STEP_SUMMARY
else
echo "❌ **Some platforms failed example testing**" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Please check the individual platform jobs for details." >> $GITHUB_STEP_SUMMARY
exit 1
fi