Repository navigation
Vertex.new_edge: resolve both ends by record id on the JVM build #378
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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 |