Skip to content

Merge pull request #242 from thanos/v0.7.2/GenStage-optional #81

Merge pull request #242 from thanos/v0.7.2/GenStage-optional

Merge pull request #242 from thanos/v0.7.2/GenStage-optional #81

Workflow file for this run

name: Integration Tests
# Run against live database services.
# Triggered manually or on pushes/PRs to main.
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
jobs:
# ── PostgreSQL 14 (focused run — expand matrix once this is green) ───────────
postgresql:
name: ADBC / PostgreSQL ${{ matrix.pg }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
pg: ["14", "15", "16"]
services:
postgres:
image: postgres:${{ matrix.pg }}
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
PG_HOST: localhost
PG_PORT: 5432
PG_USER: postgres
PG_PASSWORD: postgres
PG_DATABASE: postgres
EX_ARROW_BUILD: "1"
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
steps:
- uses: actions/checkout@v6.0.3
- name: Set up Elixir
uses: erlef/setup-beam@v1.24.0
with:
elixir-version: "1.20"
otp-version: "29"
- name: Install Rust
uses: dtolnay/rust-toolchain@v1
with:
toolchain: stable
- name: Restore Mix dependencies cache
uses: actions/cache@v5.0.5
with:
path: deps
key: mix-deps-integration-pg-29-1.20-${{ hashFiles('mix.lock') }}
restore-keys: |
mix-deps-integration-pg-29-1.20-
- name: Restore Mix build cache
uses: actions/cache@v5.0.5
with:
path: _build
key: mix-build-integration-pg-29-1.20-${{ hashFiles('mix.lock', 'lib/**/*.ex', 'native/ex_arrow_native/**') }}
restore-keys: |
mix-build-integration-pg-29-1.20-
- name: Restore Cargo registry cache
uses: actions/cache@v5.0.5
with:
path: |
~/.cargo/registry
~/.cargo/git
key: cargo-registry-${{ hashFiles('native/ex_arrow_native/Cargo.lock') }}
restore-keys: |
cargo-registry-
- name: Restore Rust target cache
uses: actions/cache@v5.0.5
with:
path: native/ex_arrow_native/target
key: rust-target-integration-pg-${{ hashFiles('native/ex_arrow_native/Cargo.lock', 'native/ex_arrow_native/src/**') }}
restore-keys: |
rust-target-integration-pg-
- name: Restore pip cache
uses: actions/cache@v5.0.5
with:
path: ~/.cache/pip
key: pip-adbc-postgresql-${{ runner.os }}
restore-keys: |
pip-adbc-postgresql-
- name: Install dependencies
run: mix deps.get
- name: Compile
run: mix compile --warnings-as-errors
# Install the official Apache ADBC PostgreSQL driver via pip.
# The wheel ships a precompiled libadbc_driver_postgresql.so — no
# system-wide install required. The pip cache means this is a no-op
# on subsequent runs.
- name: Install ADBC PostgreSQL driver
run: |
pip3 install --quiet "adbc-driver-postgresql"
DRIVER_PATH=$(python3 -c "import adbc_driver_postgresql, pathlib; p=pathlib.Path(adbc_driver_postgresql.__file__).parent; c=sorted(p.glob('*.so*'))+sorted(p.glob('lib/*.so*')); print(c[0]) if c else exit('no .so found in adbc-driver-postgresql')")
echo "Found PG ADBC driver: $DRIVER_PATH"
echo "PG_ADBC_DRIVER=$DRIVER_PATH" >> "$GITHUB_ENV"
- name: Run PostgreSQL integration tests
run: mix test --include adbc_integration test/ex_arrow/adbc_integration_test.exs
# ── DuckDB ────────────────────────────────────────────────────────────────────
duckdb:
name: ADBC / DuckDB ${{ matrix.duckdb }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
duckdb: ["1.1.3", "1.2.0"]
env:
EX_ARROW_BUILD: "1"
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
steps:
- uses: actions/checkout@v6.0.3
- name: Set up Elixir
uses: erlef/setup-beam@v1.24.0
with:
elixir-version: "1.20"
otp-version: "29"
- name: Install Rust
uses: dtolnay/rust-toolchain@v1
with:
toolchain: stable
- name: Restore Mix dependencies cache
uses: actions/cache@v5.0.5
with:
path: deps
key: mix-deps-integration-duckdb-29-1.20-${{ hashFiles('mix.lock') }}
restore-keys: |
mix-deps-integration-duckdb-29-1.20-
- name: Restore Mix build cache
uses: actions/cache@v5.0.5
with:
path: _build
key: mix-build-integration-duckdb-29-1.20-${{ hashFiles('mix.lock', 'lib/**/*.ex', 'native/ex_arrow_native/**') }}
restore-keys: |
mix-build-integration-duckdb-29-1.20-
- name: Restore Cargo registry cache
uses: actions/cache@v5.0.5
with:
path: |
~/.cargo/registry
~/.cargo/git
key: cargo-registry-${{ hashFiles('native/ex_arrow_native/Cargo.lock') }}
restore-keys: |
cargo-registry-
- name: Restore Rust target cache
uses: actions/cache@v5.0.5
with:
path: native/ex_arrow_native/target
key: rust-target-integration-duckdb-${{ hashFiles('native/ex_arrow_native/Cargo.lock', 'native/ex_arrow_native/src/**') }}
restore-keys: |
rust-target-integration-duckdb-
- name: Restore DuckDB binary cache
id: duckdb-cache
uses: actions/cache@v5.0.5
with:
path: /opt/duckdb/${{ matrix.duckdb }}
key: duckdb-${{ matrix.duckdb }}-linux-amd64
- name: Download DuckDB ADBC driver
if: steps.duckdb-cache.outputs.cache-hit != 'true'
run: |
DUCKDB_VERSION="${{ matrix.duckdb }}"
DOWNLOAD_URL="https://github.com/duckdb/duckdb/releases/download/v${DUCKDB_VERSION}/libduckdb-linux-amd64.zip"
echo "Downloading DuckDB v${DUCKDB_VERSION} from: $DOWNLOAD_URL"
mkdir -p /opt/duckdb/${DUCKDB_VERSION}
curl -fsSL "$DOWNLOAD_URL" -o /tmp/duckdb.zip
file /tmp/duckdb.zip
unzip -o /tmp/duckdb.zip -d /opt/duckdb/${DUCKDB_VERSION}
- name: Set DuckDB driver path
run: |
DRIVER_PATH=$(find /opt/duckdb/${{ matrix.duckdb }} -name "libduckdb.so" | head -1)
if [ -z "$DRIVER_PATH" ]; then
echo "::error::Could not find libduckdb.so"
ls -la /opt/duckdb/${{ matrix.duckdb }}/
exit 1
fi
echo "DUCKDB_DRIVER=$DRIVER_PATH" >> "$GITHUB_ENV"
echo "Found DuckDB ADBC driver at: $DRIVER_PATH"
- name: Install dependencies
run: mix deps.get
- name: Compile
run: mix compile --warnings-as-errors
- name: Inspect DuckDB driver symbols
run: |
echo "Driver: $DUCKDB_DRIVER"
ls -lh "$DUCKDB_DRIVER"
echo "--- ADBC entry points in libduckdb.so ---"
nm -D "$DUCKDB_DRIVER" 2>/dev/null | grep -iE "adbc|AdbcDriver" || echo "(no ADBC symbols found)"
echo "--- ctypes symbol check ---"
python3 -c "import ctypes; lib=ctypes.CDLL('$DUCKDB_DRIVER'); [print(s+': '+('found' if hasattr(lib,s) else 'NOT FOUND')) for s in ('AdbcDriverInit','duckdb_adbc_init')]" || echo "ctypes load failed"
- name: Verify DuckDB driver loads
run: |
mix run -e '
driver = System.fetch_env!("DUCKDB_DRIVER")
IO.puts("Driver path: #{driver}")
case ExArrow.ADBC.Database.open([driver_path: driver, entrypoint: "duckdb_adbc_init", path: ":memory:"]) do
{:ok, _db} ->
IO.puts("DuckDB driver loaded OK")
{:error, msg} ->
IO.puts("DuckDB driver FAILED: #{msg}")
System.halt(1)
end
'
- name: Run DuckDB integration tests
run: mix test --include adbc_integration test/ex_arrow/adbc_integration_test.exs