Deploy docs to humemai-docs #102
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
| name: Test Python Examples | |
| on: | |
| # Run on push to bindings/python/ directory | |
| push: | |
| paths: | |
| - 'bindings/python/**' | |
| - '.github/workflows/test-python-examples.yml' | |
| # Run on pull request affecting bindings/python/ | |
| pull_request: | |
| paths: | |
| - 'bindings/python/**' | |
| - '.github/workflows/test-python-examples.yml' | |
| # Run after release workflow completes | |
| workflow_run: | |
| workflows: ["Release"] | |
| types: [completed] | |
| # Allow being called by other workflows (e.g., release workflow) | |
| workflow_call: | |
| # Allow manual trigger | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| jobs: | |
| # First job: Download ArcadeDB JARs (platform-agnostic) | |
| download-jars: | |
| name: Download ArcadeDB JARs | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 | |
| - name: Download JARs from ArcadeDB Docker image | |
| shell: bash | |
| run: | | |
| cd bindings/python | |
| # Detect ArcadeDB version from pom.xml (Docker format: X.Y.Z-SNAPSHOT) | |
| ARCADEDB_TAG=$(python3 extract_version.py --format=docker) | |
| echo "๐ ArcadeDB version: $ARCADEDB_TAG" | |
| # Download JARs from official Docker image | |
| echo "๐ฆ Downloading JARs from arcadedata/arcadedb:$ARCADEDB_TAG..." | |
| # Create output directory | |
| mkdir -p src/arcadedb_embedded/jars | |
| # Create a temporary container and copy JARs from it | |
| CONTAINER_ID=$(docker create arcadedata/arcadedb:$ARCADEDB_TAG) | |
| docker cp $CONTAINER_ID:/home/arcadedb/lib/. src/arcadedb_embedded/jars/ | |
| docker rm $CONTAINER_ID | |
| echo "โ Downloaded $(ls -1 src/arcadedb_embedded/jars/*.jar | wc -l) JARs" | |
| - name: Remove excluded JARs | |
| shell: bash | |
| run: | | |
| cd bindings/python | |
| JARS_DIR="src/arcadedb_embedded/jars" | |
| EXCLUSIONS_FILE="jar_exclusions.txt" | |
| if [[ -f "$EXCLUSIONS_FILE" ]]; then | |
| echo "๐๏ธ Removing excluded JARs from jar_exclusions.txt..." | |
| EXCLUSION_COUNT=0 | |
| while IFS= read -r pattern || [[ -n "$pattern" ]]; do | |
| # Skip empty lines and comments | |
| if [[ -n "$pattern" ]] && [[ ! "$pattern" =~ ^# ]]; then | |
| echo " Processing pattern: $pattern" | |
| # Remove matching JARs | |
| for jar in "$JARS_DIR"/$pattern; do | |
| if [[ -f "$jar" ]]; then | |
| rm -f "$jar" | |
| echo " - Removed: $(basename "$jar")" | |
| EXCLUSION_COUNT=$((EXCLUSION_COUNT + 1)) | |
| fi | |
| done | |
| fi | |
| done < "$EXCLUSIONS_FILE" | |
| JAR_COUNT_AFTER=$(ls -1 "$JARS_DIR"/*.jar 2>/dev/null | wc -l) | |
| echo "โ Removed $EXCLUSION_COUNT JAR(s), $JAR_COUNT_AFTER remaining" | |
| else | |
| echo "โ ๏ธ No jar_exclusions.txt found, skipping exclusions" | |
| fi | |
| - name: Upload filtered JARs as artifact | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | |
| with: | |
| name: arcadedb-jars-examples | |
| path: bindings/python/src/arcadedb_embedded/jars/*.jar | |
| retention-days: 1 | |
| # Second job: Test examples on each platform | |
| test-examples: | |
| name: Test Python Examples (${{ matrix.platform }}, Python ${{ matrix.python-version }}) | |
| runs-on: ${{ matrix.runs-on }} | |
| needs: download-jars | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python-version: ['3.10', '3.11', '3.12', '3.13', '3.14'] | |
| # Temporarily limit to three platforms (skip macOS x86_64, all Windows) | |
| # platform: ['linux/amd64', 'linux/arm64', 'darwin/amd64', 'darwin/arm64', 'windows/amd64', 'windows/arm64'] | |
| platform: ['linux/amd64', 'linux/arm64', 'darwin/arm64'] | |
| include: | |
| - platform: linux/amd64 | |
| runs-on: ubuntu-24.04 | |
| - platform: linux/arm64 | |
| runs-on: ubuntu-24.04-arm | |
| - platform: darwin/arm64 | |
| runs-on: macos-15 | |
| # - platform: darwin/amd64 | |
| # runs-on: macos-15-intel | |
| # - platform: windows/amd64 | |
| # runs-on: windows-2025 | |
| # - platform: windows/arm64 | |
| # runs-on: windows-11-arm | |
| # macOS x86_64 and all Windows temporarily disabled | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 | |
| - name: Download JARs artifact | |
| uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 | |
| with: | |
| name: arcadedb-jars-examples | |
| path: bindings/python/src/arcadedb_embedded/jars | |
| - name: Set up Java (for native builds on macOS/Windows) | |
| if: matrix.platform != 'linux/amd64' && matrix.platform != 'linux/arm64' | |
| uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5.1.0 | |
| with: | |
| distribution: 'temurin' | |
| java-version: '25' | |
| - name: Set up Docker Buildx (Linux only) | |
| if: matrix.platform == 'linux/amd64' || matrix.platform == 'linux/arm64' | |
| uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 | |
| - name: Set up Python | |
| uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Install Python build dependencies | |
| shell: bash | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install build wheel setuptools | |
| # Windows currently disabled, 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-embedded (${{ matrix.platform }}) | |
| shell: bash | |
| run: | | |
| cd bindings/python | |
| echo "๐จ Building arcadedb-embedded for ${{ matrix.platform }} with Python ${{ matrix.python-version }}..." | |
| ./build.sh ${{ matrix.platform }} ${{ matrix.python-version }} | |
| # Note: Java is NOT required - arcadedb-embedded has bundled JRE! | |
| - name: Install ArcadeDB Python bindings | |
| shell: bash | |
| run: | | |
| cd bindings/python | |
| pip install dist/*embed*.whl | |
| - name: Install example dependencies | |
| shell: bash | |
| run: | | |
| # Install dependencies needed by examples | |
| # PyTorch is required by sentence-transformers, even on macOS | |
| # For Python 3.13+, wheels might only be on PyTorch official index | |
| if [[ "$OSTYPE" == "darwin"* ]]; then | |
| # macOS: Install CPU-only PyTorch (supports MPS acceleration) | |
| pip install torch --index-url https://download.pytorch.org/whl/cpu | |
| pip install "numpy<2.0" requests sentence-transformers | |
| else | |
| # Linux & Windows: Install CPU-only PyTorch to save space (avoid CUDA) | |
| pip install torch --index-url https://download.pytorch.org/whl/cpu | |
| pip install numpy requests sentence-transformers | |
| fi | |
| - name: Download datasets | |
| shell: bash | |
| run: | | |
| pip install tqdm py7zr lxml | |
| cd bindings/python/examples | |
| echo "๐ฅ Downloading MovieLens Small dataset..." | |
| python3 download_data.py movielens-small | |
| echo "๐ฅ Downloading Stack Overflow Small dataset..." | |
| python3 download_data.py stackoverflow-small | |
| - 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 | |
| # Windows currently disabled, no env override needed | |
| # - 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 | |
| - name: Run all examples | |
| id: run_examples | |
| shell: bash | |
| env: | |
| # Increase JVM heap for large CSV imports (example 04) | |
| ARCADEDB_JVM_ARGS: "-Xmx8g -Xms8g" | |
| run: | | |
| cd bindings/python/examples | |
| echo "๐ Running Python Examples..." | |
| echo "" | |
| # Initialize counters | |
| total=0 | |
| passed=0 | |
| failed=0 | |
| skipped=0 | |
| # Create results file | |
| results_file="example-results.txt" | |
| > $results_file | |
| # Find all Python example files (exclude download_data.py and 08_server_mode_rest_api.py) | |
| examples=$(ls [0-9]*.py 2>/dev/null | grep -v "08_server_mode_rest_api.py" | sort) | |
| if [ -z "$examples" ]; then | |
| echo "โ No example files found!" | |
| exit 1 | |
| fi | |
| # Detect timeout command (macOS uses gtimeout, Linux uses timeout) | |
| if command -v gtimeout &> /dev/null; then | |
| TIMEOUT_CMD="gtimeout" | |
| else | |
| TIMEOUT_CMD="timeout" | |
| fi | |
| # Run each example | |
| for example in $examples; do | |
| total=$((total + 1)) | |
| # Set example-specific parameters and timeout | |
| case "$example" in | |
| "04_csv_import_documents.py") | |
| example_args="--dataset movielens-small --export" | |
| example_name="$example (movielens-small dataset with export)" | |
| timeout_duration=900 # 15 minutes | |
| ;; | |
| "05_csv_import_graph.py") | |
| example_args="--dataset movielens-small --method java --import-jsonl ./exports/movielens_small_db.jsonl.tgz --export" | |
| example_name="$example (movielens-small dataset, embedded java method, import/export)" | |
| timeout_duration=900 # 15 minutes | |
| ;; | |
| "06_vector_search_recommendations.py") | |
| example_args="--import-jsonl ./exports/movielens_graph_small_db.jsonl.tgz" | |
| example_name="$example (vector search, import from JSONL)" | |
| timeout_duration=900 # 15 minutes | |
| ;; | |
| "07_stackoverflow_multimodel.py") | |
| example_args="--dataset stackoverflow-small" | |
| example_name="$example (stackoverflow-small dataset)" | |
| timeout_duration=1800 # 30 minutes | |
| ;; | |
| *) | |
| example_args="" | |
| example_name="$example" | |
| timeout_duration=900 # 15 minutes default | |
| ;; | |
| esac | |
| log_file="${example%.py}.log" | |
| echo "----------------------------------------" | |
| echo "๐ Running: $example_name" | |
| echo "----------------------------------------" | |
| # Run the example with appropriate parameters | |
| if $TIMEOUT_CMD $timeout_duration python "$example" $example_args > "$log_file" 2>&1; then | |
| echo "โ PASSED: $example_name" | tee -a $results_file | |
| passed=$((passed + 1)) | |
| else | |
| exit_code=$? | |
| if [ $exit_code -eq 124 ]; then | |
| echo "โฑ๏ธ TIMEOUT: $example_name (exceeded $((timeout_duration/60)) minutes)" | tee -a $results_file | |
| failed=$((failed + 1)) | |
| else | |
| echo "โ FAILED: $example_name (exit code: $exit_code)" | tee -a $results_file | |
| failed=$((failed + 1)) | |
| fi | |
| # Show last 20 lines of error log | |
| echo "Last 20 lines of output:" | |
| tail -n 20 "$log_file" | |
| fi | |
| echo "" | |
| done | |
| # Print summary | |
| echo "========================================" | |
| echo "๐ EXAMPLE TEST SUMMARY" | |
| echo "========================================" | |
| echo "Total: $total" | |
| echo "Passed: $passed โ " | |
| echo "Failed: $failed โ" | |
| echo "Skipped: $skipped โญ๏ธ" | |
| echo "========================================" | |
| echo "" | |
| # Output to GitHub Actions | |
| echo "total=$total" >> $GITHUB_OUTPUT | |
| echo "passed=$passed" >> $GITHUB_OUTPUT | |
| echo "failed=$failed" >> $GITHUB_OUTPUT | |
| echo "skipped=$skipped" >> $GITHUB_OUTPUT | |
| # Show detailed results | |
| echo "Detailed Results:" | |
| cat $results_file | |
| # Exit with error if any failed | |
| if [ $failed -gt 0 ]; then | |
| echo "โ Some examples failed!" | |
| exit 1 | |
| else | |
| echo "โ All examples passed!" | |
| fi | |
| - name: Generate test summary | |
| if: always() | |
| shell: bash | |
| run: | | |
| cd bindings/python/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 "- **01_simple_document_store.py** - Document CRUD operations with comprehensive data types" >> $GITHUB_STEP_SUMMARY | |
| echo "- **02_social_network_graph.py** - Graph modeling with vertices, edges, and traversal" >> $GITHUB_STEP_SUMMARY | |
| echo "- **03_vector_search.py** - Vector embeddings and semantic similarity search" >> $GITHUB_STEP_SUMMARY | |
| echo "- **04_csv_import_documents.py** - CSV import with automatic dataset download and type inference" >> $GITHUB_STEP_SUMMARY | |
| echo " - Tested with \`--dataset movielens-small --parallel 4 --batch-size 5000 --export\`" >> $GITHUB_STEP_SUMMARY | |
| echo "- **05_csv_import_graph.py** - Graph creation from document store with benchmarking" >> $GITHUB_STEP_SUMMARY | |
| echo " - Tested with \`--dataset movielens-small --parallel 1 --no-async --export --import-jsonl\`" >> $GITHUB_STEP_SUMMARY | |
| echo "- **06_vector_search_recommendations.py** - JVector vector indexing for movie recommendations" >> $GITHUB_STEP_SUMMARY | |
| echo " - Tested with \`--import-jsonl exports/movielens_graph_small_db.jsonl.tgz\`" >> $GITHUB_STEP_SUMMARY | |
| echo "- **07_stackoverflow_multimodel.py** - Multi-model graph/document/vector example with StackOverflow data" >> $GITHUB_STEP_SUMMARY | |
| echo " - Tested with \`--dataset stackoverflow-small\`" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| - name: Upload example logs | |
| if: always() | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.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: | | |
| bindings/python/examples/*.log | |
| bindings/python/examples/example-results.txt | |
| retention-days: 7 | |
| - name: Upload example databases | |
| if: failure() | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.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: bindings/python/examples/my_test_databases/ | |
| retention-days: 3 | |
| # Summary job that checks all platforms | |
| test-examples-summary: | |
| name: Examples Test Summary | |
| needs: test-examples | |
| runs-on: ubuntu-latest | |
| if: always() | |
| steps: | |
| - name: Check test results | |
| shell: bash | |
| run: | | |
| echo "## ๐ฏ Overall Examples Test Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| if [ "${{ 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 6 platforms." >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "**Platforms tested**: linux/amd64, linux/arm64, darwin/amd64, darwin/arm64, windows/amd64, windows/arm64" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "โน๏ธ **Note**: Some platform/Python combinations are excluded from testing:" >> $GITHUB_STEP_SUMMARY | |
| echo "- Windows ARM64 + Python 3.10, 3.14 (no GitHub-hosted runners available)" >> $GITHUB_STEP_SUMMARY | |
| echo "- macOS x86_64 + Python 3.13, 3.14 (no suitable dependencies available)" >> $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 |