Skip to content
Latchkey

clickhouse-connect chDB backend workflow (chdb-io/chdb)

The clickhouse-connect chDB backend workflow from chdb-io/chdb, explained and optimized by Latchkey.

C

CI health: C - fair

Point runs-on at Latchkey and get caching, run de-duplication, self-healing for flaky steps, and up to 58% lower cost, applied automatically.

Grade your own workflow free or run it on Latchkey →
Source: chdb-io/chdb.github/workflows/clickhouse-connect-backend.ymlLicense Apache-2.0View source

What it does

This is the clickhouse-connect chDB backend workflow from the chdb-io/chdb repository, a real project running GitHub Actions. It is shown here with attribution under its Apache-2.0 license.

Below, Latchkey shows a faster, safer version produced by its optimization engine.

The workflow

workflow (.yml)
name: clickhouse-connect chDB backend

# Verifies chDB as a clickhouse-connect execution backend. This pipeline lives in the chDB
# repo by design (proposal §8.4): clickhouse-connect's own CI never touches chDB; chDB runs
# clickhouse-connect against ChdbBackend here and owns the skip list. Three gates:
#   1. relocated backend suite (the former clickhouse-connect PR #753 tests) - embedded only
#   2. output-parity vs a real ClickHouse server (HTTP backend) - version-aligned
#   3. clickhouse-connect's own suite run against the chDB backend (curated-green file set)

on:
  workflow_dispatch:
  push:
    branches: [main]
    paths:
      - 'chdb/cc_*.py'
      - 'tests/clickhouse_connect/**'
      - 'scripts/cc_upstream_suite/**'
      - '.github/workflows/clickhouse-connect-backend.yml'
  pull_request:
    types: [opened, synchronize, reopened, ready_for_review]
    branches: [main]
    paths:
      - 'chdb/cc_*.py'
      - 'tests/clickhouse_connect/**'
      - 'scripts/cc_upstream_suite/**'
      - '.github/workflows/clickhouse-connect-backend.yml'

jobs:
  backend:
    name: chDB backend (py${{ matrix.python }})
    if: ${{ !github.event.pull_request.draft }}
    runs-on: ubuntu-latest
    timeout-minutes: 30
    strategy:
      fail-fast: false
      matrix:
        # clickhouse-connect 1.0+ requires Python >= 3.10.
        python: ['3.10', '3.12']

    # Real ClickHouse for the parity gate. chDB ships the 26.5 engine line, so pin the
    # server image to the same major.minor to keep the matrix version-aligned.
    services:
      clickhouse:
        image: clickhouse/clickhouse-server:26.5
        # The 26.x image rejects the empty default password (curl returns 401); set explicit
        # credentials and grant the default user access management so the parity tests can
        # create / drop databases as needed.
        env:
          CLICKHOUSE_USER: default
          CLICKHOUSE_PASSWORD: chdbtest
          CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT: 1
        ports:
          - 8123:8123
          - 9000:9000

    steps:
      - uses: actions/checkout@v4

      # Version-subscription phase 1 (pre-merge): check out the chDB-author fork branch of
      # clickhouse-connect that carries the matching pluggable-backend mechanism. We install
      # FROM this checkout (so the C extensions and the registry both come from the same
      # source) AND point the upstream-suite runner at the same checkout via --cc-repo (so
      # the suite tests live alongside the package they exercise instead of being cloned
      # from an unrelated release tag). Phase 2 (merged): switch ref to main. Phase 3
      # (released): drop this step and pin via the regular dependency.
      - name: Check out matching clickhouse-connect source
        uses: actions/checkout@v4
        with:
          repository: ShawnChen-Sirius/clickhouse-connect
          ref: feat/pluggable-backend-registry
          path: cc-source

      - uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python }}

      - name: Install chdb + clickhouse-connect (from fork source, editable + in-place C build)
        run: |
          python -m pip install --upgrade pip
          # Build deps for clickhouse-connect's Cython extensions (matches CC's own CI pattern
          # in .github/workflows/on_push.yml -- `pip install -e . --no-deps` then `python
          # setup.py build_ext --inplace`). tests/helpers.py imports driverc.buffer at module
          # load time without a fallback, so without the C extensions every integration test
          # collection fails.
          python -m pip install 'Cython>=3.1,<4' setuptools wheel
          # Install clickhouse-connect editable from the sibling fork checkout, then compile
          # the Cython extensions in-place. Editable install + in-place build means imports
          # resolve clickhouse_connect to cc-source/clickhouse_connect/ and find the compiled
          # .so files alongside the .py files.
          python -m pip install -e ./cc-source --no-deps
          ( cd cc-source && python setup.py build_ext --inplace )
          # chdb from THIS checkout so the cc_*.py under test + the entry points are exercised.
          python -m pip install .
          python -m pip install certifi urllib3 pandas pyarrow pytest pytest-asyncio pytest-timeout lz4 zstandard
          python -c "import chdb, clickhouse_connect; print('chdb', chdb.__version__)"
          python -c "from clickhouse_connect.driverc.buffer import ResponseBuffer; print('C extensions OK')"
          python -c "import clickhouse_connect.driver.registry as r; assert 'chdb' in r.available_backend_names(), r.available_backend_names(); print('backends', r.available_backend_names())"

      - name: Wait for ClickHouse
        run: |
          for i in $(seq 1 30); do
            if curl -fsS -u default:chdbtest 'http://localhost:8123/?query=SELECT%201' >/dev/null 2>&1; then echo "ClickHouse up"; break; fi
            sleep 2
          done
          curl -fsS -u default:chdbtest 'http://localhost:8123/?query=SELECT%20version()'

      # Gate 1 - embedded backend suite (relocated clickhouse-connect PR #753 tests).
      - name: Backend suite (embedded)
        run: python -m pytest tests/clickhouse_connect/test_cc_backend.py -p no:xdist -q

      # Gate 2 - output parity: same call, chDB vs real server, must match.
      - name: Parity vs real ClickHouse
        env:
          CLICKHOUSE_CONNECT_TEST_HOST: localhost
          CLICKHOUSE_CONNECT_TEST_PORT: '8123'
          CLICKHOUSE_CONNECT_TEST_USER: default
          CLICKHOUSE_CONNECT_TEST_PASSWORD: chdbtest
        run: python -m pytest tests/clickhouse_connect/test_parity.py -p no:xdist -q

      # Gate 3 - clickhouse-connect's own suite against chDB, over the curated-green file set.
      # Expands as divergences in scripts/cc_upstream_suite/expected_divergences.txt are
      # documented (see that directory's README).
      - name: clickhouse-connect upstream suite (chDB backend)
        env:
          CLICKHOUSE_CONNECT_TEST_HOST: localhost
          CLICKHOUSE_CONNECT_TEST_PORT: '8123'
          CLICKHOUSE_CONNECT_TEST_USER: default
          CLICKHOUSE_CONNECT_TEST_PASSWORD: chdbtest
        run: |
          # --cc-repo points the runner at the sibling fork checkout we installed CC from,
          # so the suite source matches the package being exercised (avoids cloning an
          # unrelated upstream release tag whose test helpers may not match the package).
          python scripts/cc_upstream_suite/run_upstream_suite.py \
            --cc-repo cc-source \
            --tests "tests/integration_tests/test_native.py tests/integration_tests/test_numeric.py tests/integration_tests/test_inserts.py"

The same workflow, on Latchkey

Estimated ~20% faster on cache hits, plus fewer wasted runs and a safer supply chain. Added and changed lines are highlighted.

name: clickhouse-connect chDB backend
 
# Verifies chDB as a clickhouse-connect execution backend. This pipeline lives in the chDB
# repo by design (proposal §8.4): clickhouse-connect's own CI never touches chDB; chDB runs
# clickhouse-connect against ChdbBackend here and owns the skip list. Three gates:
#   1. relocated backend suite (the former clickhouse-connect PR #753 tests) - embedded only
#   2. output-parity vs a real ClickHouse server (HTTP backend) - version-aligned
#   3. clickhouse-connect's own suite run against the chDB backend (curated-green file set)
 
on:
  workflow_dispatch:
  push:
    branches: [main]
    paths:
      - 'chdb/cc_*.py'
      - 'tests/clickhouse_connect/**'
      - 'scripts/cc_upstream_suite/**'
      - '.github/workflows/clickhouse-connect-backend.yml'
  pull_request:
    types: [opened, synchronize, reopened, ready_for_review]
    branches: [main]
    paths:
      - 'chdb/cc_*.py'
      - 'tests/clickhouse_connect/**'
      - 'scripts/cc_upstream_suite/**'
      - '.github/workflows/clickhouse-connect-backend.yml'
 
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
 
jobs:
  backend:
    name: chDB backend (py${{ matrix.python }})
    if: ${{ !github.event.pull_request.draft }}
    runs-on: latchkey-small
    timeout-minutes: 30
    strategy:
      fail-fast: false
      matrix:
        # clickhouse-connect 1.0+ requires Python >= 3.10.
        python: ['3.10', '3.12']
 
    # Real ClickHouse for the parity gate. chDB ships the 26.5 engine line, so pin the
    # server image to the same major.minor to keep the matrix version-aligned.
    services:
      clickhouse:
        image: clickhouse/clickhouse-server:26.5
        # The 26.x image rejects the empty default password (curl returns 401); set explicit
        # credentials and grant the default user access management so the parity tests can
        # create / drop databases as needed.
        env:
          CLICKHOUSE_USER: default
          CLICKHOUSE_PASSWORD: chdbtest
          CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT: 1
        ports:
          - 8123:8123
          - 9000:9000
 
    steps:
      - uses: actions/checkout@v4
 
      # Version-subscription phase 1 (pre-merge): check out the chDB-author fork branch of
      # clickhouse-connect that carries the matching pluggable-backend mechanism. We install
      # FROM this checkout (so the C extensions and the registry both come from the same
      # source) AND point the upstream-suite runner at the same checkout via --cc-repo (so
      # the suite tests live alongside the package they exercise instead of being cloned
      # from an unrelated release tag). Phase 2 (merged): switch ref to main. Phase 3
      # (released): drop this step and pin via the regular dependency.
      - name: Check out matching clickhouse-connect source
        uses: actions/checkout@v4
        with:
          repository: ShawnChen-Sirius/clickhouse-connect
          ref: feat/pluggable-backend-registry
          path: cc-source
 
      - uses: actions/setup-python@v5
        with:
          cache: 'pip'
          python-version: ${{ matrix.python }}
 
      - name: Install chdb + clickhouse-connect (from fork source, editable + in-place C build)
        run: |
          python -m pip install --upgrade pip
          # Build deps for clickhouse-connect's Cython extensions (matches CC's own CI pattern
          # in .github/workflows/on_push.yml -- `pip install -e . --no-deps` then `python
          # setup.py build_ext --inplace`). tests/helpers.py imports driverc.buffer at module
          # load time without a fallback, so without the C extensions every integration test
          # collection fails.
          python -m pip install 'Cython>=3.1,<4' setuptools wheel
          # Install clickhouse-connect editable from the sibling fork checkout, then compile
          # the Cython extensions in-place. Editable install + in-place build means imports
          # resolve clickhouse_connect to cc-source/clickhouse_connect/ and find the compiled
          # .so files alongside the .py files.
          python -m pip install -e ./cc-source --no-deps
          ( cd cc-source && python setup.py build_ext --inplace )
          # chdb from THIS checkout so the cc_*.py under test + the entry points are exercised.
          python -m pip install .
          python -m pip install certifi urllib3 pandas pyarrow pytest pytest-asyncio pytest-timeout lz4 zstandard
          python -c "import chdb, clickhouse_connect; print('chdb', chdb.__version__)"
          python -c "from clickhouse_connect.driverc.buffer import ResponseBuffer; print('C extensions OK')"
          python -c "import clickhouse_connect.driver.registry as r; assert 'chdb' in r.available_backend_names(), r.available_backend_names(); print('backends', r.available_backend_names())"
 
      - name: Wait for ClickHouse
        run: |
          for i in $(seq 1 30); do
            if curl -fsS -u default:chdbtest 'http://localhost:8123/?query=SELECT%201' >/dev/null 2>&1; then echo "ClickHouse up"; break; fi
            sleep 2
          done
          curl -fsS -u default:chdbtest 'http://localhost:8123/?query=SELECT%20version()'
 
      # Gate 1 - embedded backend suite (relocated clickhouse-connect PR #753 tests).
      - name: Backend suite (embedded)
        run: python -m pytest tests/clickhouse_connect/test_cc_backend.py -p no:xdist -q
 
      # Gate 2 - output parity: same call, chDB vs real server, must match.
      - name: Parity vs real ClickHouse
        env:
          CLICKHOUSE_CONNECT_TEST_HOST: localhost
          CLICKHOUSE_CONNECT_TEST_PORT: '8123'
          CLICKHOUSE_CONNECT_TEST_USER: default
          CLICKHOUSE_CONNECT_TEST_PASSWORD: chdbtest
        run: python -m pytest tests/clickhouse_connect/test_parity.py -p no:xdist -q
 
      # Gate 3 - clickhouse-connect's own suite against chDB, over the curated-green file set.
      # Expands as divergences in scripts/cc_upstream_suite/expected_divergences.txt are
      # documented (see that directory's README).
      - name: clickhouse-connect upstream suite (chDB backend)
        env:
          CLICKHOUSE_CONNECT_TEST_HOST: localhost
          CLICKHOUSE_CONNECT_TEST_PORT: '8123'
          CLICKHOUSE_CONNECT_TEST_USER: default
          CLICKHOUSE_CONNECT_TEST_PASSWORD: chdbtest
        run: |
          # --cc-repo points the runner at the sibling fork checkout we installed CC from,
          # so the suite source matches the package being exercised (avoids cloning an
          # unrelated upstream release tag whose test helpers may not match the package).
          python scripts/cc_upstream_suite/run_upstream_suite.py \
            --cc-repo cc-source \
            --tests "tests/integration_tests/test_native.py tests/integration_tests/test_numeric.py tests/integration_tests/test_inserts.py"
 

What changed

What Latchkey heals here

This workflow has steps that commonly fail on transient issues (network, registries, flaky browsers). On Latchkey managed runners they are detected, retried, and self-healed instead of failing your build:

This workflow runs 1 job (2 with the matrix expanded) per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.

Actions used in this workflow