From 0756bedc8e3027c71bb160e088501916a24b0c08 Mon Sep 17 00:00:00 2001 From: Arun Sharma Date: Sat, 4 Jul 2026 08:13:30 -0700 Subject: [PATCH] CI: add build workflow with platform matrix and prebuilt downloads MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - .github/workflows/ci.yml: matrix-based CI (Linux x86_64 initially) modeled after ladybug/.github/workflows/build-extensions.yml for the build structure and ladybug-rust/.github/workflows/ci.yml for the prebuilt-download pattern. Runs the same extension tests as the 'minimal linux extension test' job in ci-workflow.yml. - Platform matrix: ubuntu-latest is active, with ubuntu-24.04-arm, macos-latest, macos-15-intel, and windows-2022 entries pre-wired and commented out. Each entry is just os / os_name / arch / (container for Linux). DuckDB archive name and ladybug artifact arch are computed from runner.os / runner.arch in a 'Compute platform variables' step instead of cluttering the matrix. - Prebuilt artifacts: a separate 'resolve-run' job (host runner, no container, has gh CLI) queries the GitHub API for the latest successful LadybugDB/ladybug build-and-deploy run and downloads liblbug + CLI artifacts via 'gh run download', then uploads them as a workflow artifact. The container job downloads that artifact via actions/download-artifact and extracts it into the ladybug tree, avoiding the need to install gh in the container. - Sub-repo checkouts: actions/checkout@v4 places the extension repo, dataset, and benchmark directly into ladybug/extension, ladybug/dataset, and ladybug/benchmark respectively — the same layout 'git submodule update --init extension dataset benchmark' would produce, with no symlinks or path gymnastics. - ADBC dependencies: setup-pixi + 'dbc install --level user duckdb' match the minimal-linux-extension-test job in ci-workflow.yml so the ADBC extension can actually link against libadbc-driver-manager and libarrow. - Build steps: make extension-release (BUILD_LBUG=FALSE) for the extension .so files, then make relwithdebinfo + make extension-test-build (BUILD_TESTS=TRUE) for the test runner and ctest targets. Test fixtures (ADBC duckdb + tinysnb) are created before the build, matching the existing CI ordering. - scripts/download-liblbug.sh: upstream downloader for prebuilt liblbug from GitHub releases or workflow artifacts. - scripts/download_lbug.sh: wrapper that invokes the upstream script and writes LBUG_LIBRARY_DIR / LBUG_INCLUDE_DIR env vars. --- .github/workflows/ci.yml | 387 ++++++++++++++++++++++++++++++++++++ scripts/download-liblbug.sh | 139 +++++++++++++ scripts/download_lbug.sh | 76 +++++++ 3 files changed, 602 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100755 scripts/download-liblbug.sh create mode 100644 scripts/download_lbug.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..352274e --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,387 @@ +name: CI + +on: + workflow_dispatch: + pull_request: + branches: + - main + push: + branches: + - main + +permissions: + actions: read + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +env: + EXTENSION_LIST: adbc;azure;delta;duckdb;fts;httpfs;iceberg;json;llm;neo4j;postgres;sqlite;unity_catalog;vector;algo + +jobs: + # ───────────────────────────────────────────────────────────────── + # Resolve the latest successful ladybug build-and-deploy run and + # download prebuilt liblbug + CLI artifacts. Runs on the host + # runner (no container) so gh CLI is available natively. + # ───────────────────────────────────────────────────────────────── + resolve-run: + runs-on: ubuntu-latest + permissions: + actions: write + contents: read + outputs: + run-id: ${{ steps.resolve.outputs.run-id }} + steps: + - name: Resolve latest successful build-and-deploy run + id: resolve + env: + GITHUB_TOKEN: ${{ github.token }} + run: | + RUN_ID="$( + curl -fsSL \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + "https://api.github.com/repos/LadybugDB/ladybug/actions/workflows/build-and-deploy.yml/runs?branch=main&status=success&per_page=1" \ + | python3 -c 'import json,sys; data=json.load(sys.stdin); runs=data.get("workflow_runs") or []; print(runs[0]["id"] if runs else "")' + )" + + if [ -z "$RUN_ID" ]; then + echo "Could not find a successful LadybugDB/ladybug build-and-deploy run." >&2 + exit 1 + fi + + echo "run-id=$RUN_ID" >> "$GITHUB_OUTPUT" + + - name: Download prebuilt liblbug and CLI + env: + GH_TOKEN: ${{ github.token }} + run: | + mkdir -p prebuilt + + # 1) Shared library + headers + gh run download "${{ steps.resolve.outputs.run-id }}" \ + --repo LadybugDB/ladybug \ + --name "liblbug-linux-x86_64" \ + --dir prebuilt + + # 2) CLI binary + gh run download "${{ steps.resolve.outputs.run-id }}" \ + --repo LadybugDB/ladybug \ + --name "lbug_cli-linux-x86_64" \ + --dir prebuilt + + ls -la prebuilt/ + + - name: Upload prebuilt artifacts + uses: actions/upload-artifact@v4 + with: + name: lbug-prebuilts + path: prebuilt/* + retention-days: 1 + + # ───────────────────────────────────────────────────────────────── + # Build all extensions inside the manylinux container (glibc compat) + # and run the extension integration tests. + # ───────────────────────────────────────────────────────────────── + build-and-test: + needs: resolve-run + strategy: + matrix: + include: + # ── Linux ──────────────────────────────────────────────── + - os: ubuntu-latest + os_name: linux + arch: x86_64 + container: quay.io/pypa/manylinux_2_28_x86_64 + # - os: ubuntu-24.04-arm + # os_name: linux + # arch: aarch64 + # container: quay.io/pypa/manylinux_2_28_aarch64 + + # ── macOS ──────────────────────────────────────────────── + # - os: macos-latest + # os_name: osx + # arch: arm64 + # - os: macos-15-intel + # os_name: osx + # arch: x86_64 + + # ── Windows ────────────────────────────────────────────── + # - os: windows-2022 + # os_name: win + # arch: x86_64 + + runs-on: ${{ matrix.os }} + container: ${{ matrix.container }} + + steps: + # ── Source checkouts ────────────────────────────────────────── + - name: Checkout ladybug + uses: actions/checkout@v4 + with: + repository: LadybugDB/ladybug + fetch-depth: 1 + path: ladybug + + # The following three checkouts place the sub-repos directly into + # the ladybug tree at the same paths the in-tree submodules would + # occupy — no symlinks, no path gymnastics. + - name: Checkout extension into ladybug/extension + uses: actions/checkout@v4 + with: + fetch-depth: 1 + path: ladybug/extension + + - name: Checkout dataset into ladybug/dataset + uses: actions/checkout@v4 + with: + repository: LadybugDB/dataset + fetch-depth: 1 + path: ladybug/dataset + + - name: Checkout benchmark into ladybug/benchmark + uses: actions/checkout@v4 + with: + repository: LadybugDB/benchmarks + fetch-depth: 1 + path: ladybug/benchmark + + - name: Mark workspace safe for git (Linux container) + if: runner.os == 'Linux' + run: git config --global --add safe.directory '*' + + # ── Compute platform variables ─────────────────────────── + # Derive DuckDB download params and ladybug artifact arch from + # runner.os / runner.arch instead of cluttering the matrix. + - name: Compute platform variables + run: | + # --- DuckDB archive --- + case "${{ runner.os }}" in + Linux) + echo "DUCKDB_LIB=libduckdb.so" >> "$GITHUB_ENV" + case "${{ runner.arch }}" in + X64) echo "DUCKDB_ARCH=linux-amd64" >> "$GITHUB_ENV" ;; + ARM64) echo "DUCKDB_ARCH=linux-arm64" >> "$GITHUB_ENV" ;; + esac + ;; + macOS) + echo "DUCKDB_LIB=libduckdb.dylib" >> "$GITHUB_ENV" + echo "DUCKDB_ARCH=osx-universal" >> "$GITHUB_ENV" + ;; + Windows) + echo "DUCKDB_LIB=duckdb.dll" >> "$GITHUB_ENV" + case "${{ runner.arch }}" in + X64|AMD64) echo "DUCKDB_ARCH=windows-amd64" >> "$GITHUB_ENV" ;; + ARM64) echo "DUCKDB_ARCH=windows-arm64" >> "$GITHUB_ENV" ;; + esac + ;; + esac + + # --- Ladybug artifact arch (maps runner arch to release names) --- + case "${{ runner.arch }}" in + X64|AMD64) echo "LBUG_ARTIFACT_ARCH=x86_64" >> "$GITHUB_ENV" ;; + ARM64) echo "LBUG_ARTIFACT_ARCH=aarch64" >> "$GITHUB_ENV" ;; + esac + + # --- Upstream run ID for prebuilt artifacts — echoed by resolve job --- + echo "LBUG_PRECOMPILED_RUN_ID=${{ needs.resolve-run.outputs.run-id }}" >> "$GITHUB_ENV" + + - name: Setup ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: extension-ci-${{ runner.os }}-${{ runner.arch }}-${{ github.ref }} + max-size: 2G + create-symlink: true + restore-keys: | + extension-ci-${{ runner.os }}-${{ runner.arch }}-refs/heads/main + extension-ci-${{ runner.os }}-${{ runner.arch }}- + + # ── Build dependencies ──────────────────────────────────────── + - name: Install build dependencies (Linux) + if: runner.os == 'Linux' + run: | + dnf install -y 'dnf-command(config-manager)' + dnf config-manager --set-enabled powertools + dnf install -y cmake ninja-build python3 python3-pip git wget unzip \ + gcc-toolset-13 openssl3 openssl3-devel pkg-config + + - name: Install uv + working-directory: ladybug + run: | + curl -LsSf https://astral.sh/uv/install.sh | sh + echo "$HOME/.local/bin" >> "$GITHUB_PATH" + uv venv + + - name: Install test Python dependencies + working-directory: ladybug + run: | + uv pip install duckdb rangehttpserver requests + + # ── Setup pixi + ADBC runtime ─────────────────────────── + # The ADBC extension requires libadbc-driver-manager and libarrow, + # which the ladybug repo's pixi.toml pins to conda-forge. These + # are needed both to *build* the ADBC extension and to run its + # tests. + - name: Setup pixi + if: runner.os != 'Windows' + uses: prefix-dev/setup-pixi@v0.9.4 + with: + pixi-version: v0.68.1 + working-directory: ladybug + cache: false + activate-environment: true + + - name: Configure ADBC runtime + if: runner.os != 'Windows' + run: | + curl -LsSf https://dbc.columnar.tech/install.sh | sh + echo "$HOME/.local/bin" >> "$GITHUB_PATH" + echo "LD_LIBRARY_PATH=${CONDA_PREFIX}/lib:${LD_LIBRARY_PATH}" >> "$GITHUB_ENV" + "$HOME/.local/bin/dbc" install --level user duckdb || true + + # ── Install DuckDB ──────────────────────────────────────────── + - name: Install DuckDB (Linux) + if: runner.os == 'Linux' + run: | + wget "https://github.com/duckdb/duckdb/releases/latest/download/libduckdb-${{ env.DUCKDB_ARCH }}.zip" + unzip "libduckdb-${{ env.DUCKDB_ARCH }}.zip" -d duckdb + cp duckdb/duckdb.h /usr/local/include/ + cp duckdb/duckdb.hpp /usr/local/include/ + cp duckdb/${{ env.DUCKDB_LIB }} /usr/local/lib/ + ldconfig + # CMake config so find_package(DuckDB) works + mkdir -p /usr/local/lib/cmake/DuckDB + tee /usr/local/lib/cmake/DuckDB/DuckDBConfig.cmake > /dev/null << 'CMEOF' + if(NOT TARGET DuckDB::duckdb) + add_library(DuckDB::duckdb SHARED IMPORTED) + set_target_properties(DuckDB::duckdb PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "/usr/local/include" + IMPORTED_LOCATION "/usr/local/lib/${{ env.DUCKDB_LIB }}" + ) + endif() + set(DuckDB_LIBRARIES DuckDB::duckdb) + set(DuckDB_INCLUDE_DIRS "/usr/local/include") + set(DuckDB_FOUND TRUE) + CMEOF + + # ── Download prebuilt liblbug + CLI from the resolve-run job ── + # The resolve-run job (runs on host runner, has gh CLI) downloaded + # and archived these; we extract them into the ladybug tree. + - name: Download prebuilt artifacts + uses: actions/download-artifact@v4 + with: + name: lbug-prebuilts + path: prebuilt-tmp + + - name: Extract prebuilt liblbug and CLI + run: | + cd prebuilt-tmp + mkdir -p "${{ github.workspace }}/ladybug/src/include" + mkdir -p "${{ github.workspace }}/ladybug/tools/shell" + + # Shared library + headers + tar xzf "liblbug-linux-${{ env.LBUG_ARTIFACT_ARCH }}.tar.gz" -C "${{ github.workspace }}/ladybug/src/include/" + # CLI binary + tar xzf "lbug_cli-linux-${{ env.LBUG_ARTIFACT_ARCH }}.tar.gz" -C "${{ github.workspace }}/ladybug/tools/shell/" + chmod +x "${{ github.workspace }}/ladybug/tools/shell/lbug" + + # ── Test fixtures (before the build, like minimal-linux-extension-test) ── + - name: Create ADBC DuckDB fixture + working-directory: ladybug + run: | + mkdir -p extension/adbc/test + uv run python - <<'PY' + import duckdb + con = duckdb.connect("extension/adbc/test/adbc.duckdb") + con.execute("CREATE OR REPLACE TABLE games(id BIGINT, title VARCHAR, score BIGINT)") + con.execute(""" + INSERT INTO games VALUES + (1, 'Portal', 95), + (2, 'Celeste', 94), + (3, 'Hades', 93) + """) + con.close() + PY + + # ── Build extensions (release) ──────────────────────────────── + - name: Build extensions + working-directory: ladybug + env: + GH_TOKEN: ${{ github.token }} + run: | + source /opt/rh/gcc-toolset-13/enable + export CC=gcc + export CXX=g++ + export EXTRA_CMAKE_FLAGS="\ + -DOPENSSL_ROOT_DIR=/usr/lib64/openssl3 \ + -DOPENSSL_INCLUDE_DIR=/usr/include/openssl3 \ + -DOPENSSL_CRYPTO_LIBRARY=/usr/lib64/openssl3/libcrypto.so \ + -DOPENSSL_SSL_LIBRARY=/usr/lib64/openssl3/libssl.so" + make extension-release + + # ── Build test infrastructure ───────────────────────────────── + - name: Build full test infrastructure (relwithdebinfo) + working-directory: ladybug + env: + GH_TOKEN: ${{ github.token }} + run: | + source /opt/rh/gcc-toolset-13/enable + export CC=gcc + export CXX=g++ + export EXTRA_CMAKE_FLAGS="\ + -DOPENSSL_ROOT_DIR=/usr/lib64/openssl3 \ + -DOPENSSL_INCLUDE_DIR=/usr/include/openssl3 \ + -DOPENSSL_CRYPTO_LIBRARY=/usr/lib64/openssl3/libcrypto.so \ + -DOPENSSL_SSL_LIBRARY=/usr/lib64/openssl3/libssl.so" + make relwithdebinfo + cp build/relwithdebinfo/tools/shell/lbug lbug.prod + + - name: Build extension tests + working-directory: ladybug + env: + GH_TOKEN: ${{ github.token }} + run: | + source /opt/rh/gcc-toolset-13/enable + export CC=gcc + export CXX=g++ + export EXTRA_CMAKE_FLAGS="\ + -DOPENSSL_ROOT_DIR=/usr/lib64/openssl3 \ + -DOPENSSL_INCLUDE_DIR=/usr/include/openssl3 \ + -DOPENSSL_CRYPTO_LIBRARY=/usr/lib64/openssl3/libcrypto.so \ + -DOPENSSL_SSL_LIBRARY=/usr/lib64/openssl3/libssl.so" + make extension-test-build + cp lbug.prod build/relwithdebinfo/tools/shell/lbug + + # ── Test fixtures ───────────────────────────────────────────── + - name: Generate test dataset + working-directory: ladybug + run: uv run python3 scripts/generate-tinysnb.py + + - name: Start extension repo server (for remote-load tests) + working-directory: ladybug + run: | + uv run python3 scripts/setup-extension-repo.py & + sleep 3 + + # ── Run tests ───────────────────────────────────────────────── + - name: Run extension tests + working-directory: ladybug + env: + E2E_TEST_FILES_DIRECTORY: extension + run: | + source /opt/rh/gcc-toolset-13/enable + ctest --test-dir build/relwithdebinfo/extension --output-on-failure -j "$(nproc)" + + # ── Collect & upload artifacts ──────────────────────────────── + - name: Collect built artifacts + working-directory: ladybug + run: python3 scripts/collect-extensions.py + + - name: Upload built artifacts + uses: actions/upload-artifact@v4 + with: + name: lbug-extensions-${{ matrix.os_name }}-${{ matrix.arch }} + path: ladybug/extension-artifacts diff --git a/scripts/download-liblbug.sh b/scripts/download-liblbug.sh new file mode 100755 index 0000000..b108c64 --- /dev/null +++ b/scripts/download-liblbug.sh @@ -0,0 +1,139 @@ +#!/usr/bin/env bash +# Download prebuilt liblbug archives from GitHub releases or workflow artifacts. +set -euo pipefail + +LIB_KIND="${LBUG_LIB_KIND:-shared}" +LINUX_VARIANT="${LBUG_LINUX_VARIANT:-compat}" +REPOSITORY="${LBUG_GITHUB_REPOSITORY:-LadybugDB/ladybug}" +RUN_ID="${LBUG_PRECOMPILED_RUN_ID:-}" +VERSION_OVERRIDE="${LBUG_VERSION:-}" + +if [ "$LIB_KIND" != "shared" ] && [ "$LIB_KIND" != "static" ]; then + echo "Unsupported LBUG_LIB_KIND: $LIB_KIND (expected 'shared' or 'static')" >&2 + exit 1 +fi + +if [ "$LINUX_VARIANT" != "compat" ] && [ "$LINUX_VARIANT" != "perf" ]; then + echo "Unsupported LBUG_LINUX_VARIANT: $LINUX_VARIANT (expected 'compat' or 'perf')" >&2 + exit 1 +fi + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" +TARGET_DIR="${LBUG_TARGET_DIR:-$PROJECT_DIR/lib}" + +OS="$(uname -s)" +ARCH="$(uname -m)" + +case "$OS" in + Darwin) + if [ "$ARCH" = "x86_64" ]; then + ARCHIVE_ARCH="x86_64" + elif [ "$ARCH" = "arm64" ]; then + ARCHIVE_ARCH="arm64" + else + echo "Unsupported macOS architecture: $ARCH" >&2 + exit 1 + fi + if [ "$LIB_KIND" = "static" ]; then + ARCHIVE="liblbug-static-osx-${ARCHIVE_ARCH}.tar.gz" + ARTIFACT_NAME="liblbug-static-osx-${ARCHIVE_ARCH}" + LIB_NAME="liblbug.a" + else + ARCHIVE="liblbug-osx-${ARCHIVE_ARCH}.tar.gz" + ARTIFACT_NAME="liblbug-osx-${ARCHIVE_ARCH}" + LIB_NAME="liblbug.dylib" + fi + ;; + Linux) + if [ "$ARCH" = "x86_64" ]; then + ARCHIVE_ARCH="x86_64" + elif [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then + ARCHIVE_ARCH="aarch64" + else + echo "Unsupported Linux architecture: $ARCH" >&2 + exit 1 + fi + if [ "$LIB_KIND" = "static" ]; then + ARCHIVE="liblbug-static-linux-${ARCHIVE_ARCH}-${LINUX_VARIANT}.tar.gz" + ARTIFACT_NAME="liblbug-static-linux-${ARCHIVE_ARCH}-${LINUX_VARIANT}" + LIB_NAME="liblbug.a" + else + ARCHIVE="liblbug-linux-${ARCHIVE_ARCH}.tar.gz" + ARTIFACT_NAME="liblbug-linux-${ARCHIVE_ARCH}" + LIB_NAME="liblbug.so" + fi + ;; + MINGW*|MSYS*|CYGWIN*) + if [ "$ARCH" = "x86_64" ] || [ "$ARCH" = "AMD64" ]; then + ARCHIVE_ARCH="x86_64" + else + echo "Unsupported Windows architecture: $ARCH" >&2 + exit 1 + fi + if [ "$LIB_KIND" = "static" ]; then + ARCHIVE="liblbug-static-windows-${ARCHIVE_ARCH}.zip" + ARTIFACT_NAME="liblbug-static-windows-${ARCHIVE_ARCH}" + LIB_NAME="lbug.lib" + else + ARCHIVE="liblbug-windows-${ARCHIVE_ARCH}.zip" + ARTIFACT_NAME="liblbug-windows-${ARCHIVE_ARCH}" + LIB_NAME="lbug_shared.dll" + fi + ;; + *) + echo "Unsupported OS: $OS" >&2 + exit 1 + ;; +esac + +if [ -f "$TARGET_DIR/$LIB_NAME" ]; then + echo "liblbug already exists in $TARGET_DIR" + exit 0 +fi + +mkdir -p "$TARGET_DIR" +TMPDIR="$(mktemp -d)" +trap 'rm -rf "$TMPDIR"' EXIT + +fetch_release_archive() { + local version + if [ -n "$VERSION_OVERRIDE" ]; then + version="$VERSION_OVERRIDE" + else + version="$(curl -sS "https://api.github.com/repos/${REPOSITORY}/releases/latest" | grep -o '"tag_name": "v\([^"]*\)"' | cut -d'"' -f4 | cut -c2-)" + fi + local download_url="https://github.com/${REPOSITORY}/releases/download/v${version}/${ARCHIVE}" + curl -fSL "$download_url" -o "$TMPDIR/$ARCHIVE" + echo "release:v${version}" +} + +fetch_run_artifact() { + if ! command -v gh >/dev/null 2>&1; then + echo "gh CLI is required when LBUG_PRECOMPILED_RUN_ID is set" >&2 + exit 1 + fi + gh run download "$RUN_ID" --repo "$REPOSITORY" --name "$ARTIFACT_NAME" --dir "$TMPDIR/artifact" >/dev/null + local extracted_archive + extracted_archive="$(find "$TMPDIR/artifact" -type f -name "$ARCHIVE" | head -n1)" + if [ -z "$extracted_archive" ]; then + echo "Artifact ${ARTIFACT_NAME} does not contain ${ARCHIVE}" >&2 + exit 1 + fi + mv "$extracted_archive" "$TMPDIR/$ARCHIVE" + echo "run:${RUN_ID}/${ARTIFACT_NAME}" +} + +if [ -n "$RUN_ID" ]; then + SOURCE_DESC="$(fetch_run_artifact)" +else + SOURCE_DESC="$(fetch_release_archive)" +fi + +if [ "${ARCHIVE##*.}" = "zip" ]; then + unzip -o "$TMPDIR/$ARCHIVE" -d "$TARGET_DIR" +else + tar xzf "$TMPDIR/$ARCHIVE" -C "$TARGET_DIR" +fi + +echo "Installed ${ARCHIVE} from ${SOURCE_DESC} to $TARGET_DIR" diff --git a/scripts/download_lbug.sh b/scripts/download_lbug.sh new file mode 100644 index 0000000..3987b69 --- /dev/null +++ b/scripts/download_lbug.sh @@ -0,0 +1,76 @@ +#!/bin/sh +# Download prebuilt liblbug (shared library + headers) into a local cache, +# plus the CLI binary for running extension tests. +# +# Usage: +# scripts/download_lbug.sh # default: shared lib + headers +# LBUG_LIB_KIND=static ./download_lbug.sh # static lib instead +# +# Environment variables respected: +# LBUG_LIB_KIND shared (default) or static +# LBUG_PRECOMPILED_RUN_ID Pin to a specific workflow run +# LBUG_VERSION Pin to a specific release version +# LBUG_TARGET_DIR Output directory (default: .cache/lbug-prebuilt) +# LBUG_GITHUB_REPOSITORY Org/repo (default: LadybugDB/ladybug) + +set -eu + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" + +ENV_FILE="${1:-$PROJECT_DIR/.cache/lbug-prebuilt.env}" +CACHE_LIB_DIR="${LBUG_TARGET_DIR:-$PROJECT_DIR/.cache/lbug-prebuilt/lib}" +LIB_KIND="${LBUG_LIB_KIND:-shared}" +UPSTREAM_SCRIPT="$SCRIPT_DIR/download-liblbug.sh" +UPSTREAM_URL="https://raw.githubusercontent.com/LadybugDB/ladybug/refs/heads/main/scripts/download-liblbug.sh" + +if [ ! -f "$UPSTREAM_SCRIPT" ]; then + echo "Fetching $UPSTREAM_URL ..." + curl -fsSL "$UPSTREAM_URL" -o "$UPSTREAM_SCRIPT" + chmod +x "$UPSTREAM_SCRIPT" +fi + +LBUG_TARGET_DIR="$CACHE_LIB_DIR" LBUG_LIB_KIND="$LIB_KIND" bash "$UPSTREAM_SCRIPT" + +OS="$(uname -s)" +case "$OS" in + Darwin) + if [ "$LIB_KIND" = "shared" ]; then + LIB_PATH="$CACHE_LIB_DIR/liblbug.dylib" + else + LIB_PATH="$CACHE_LIB_DIR/liblbug.a" + fi + ;; + Linux) + if [ "$LIB_KIND" = "shared" ]; then + LIB_PATH="$CACHE_LIB_DIR/liblbug.so" + else + LIB_PATH="$CACHE_LIB_DIR/liblbug.a" + fi + ;; + MINGW*|MSYS*|CYGWIN*) + if [ "$LIB_KIND" = "shared" ]; then + LIB_PATH="$CACHE_LIB_DIR/lbug_shared.dll" + else + LIB_PATH="$CACHE_LIB_DIR/lbug.lib" + fi + ;; + *) + echo "Unsupported OS: $OS" >&2 + exit 1 + ;; +esac + +if [ ! -f "$LIB_PATH" ]; then + echo "Expected precompiled library not found at $LIB_PATH" >&2 + exit 1 +fi + +mkdir -p "$(dirname "$ENV_FILE")" +cat > "$ENV_FILE" <