clickhouse-connect chDB backend workflow (chdb-io/chdb)
The clickhouse-connect chDB backend workflow from chdb-io/chdb, explained and optimized by Latchkey.
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.
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
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
- Run on Latchkey managed runners with one line (
runs-on), which apply the fixes below automatically and self-heal transient failures. This example useslatchkey-small; pick the runner size that fits the job. - Cancel superseded runs when a branch or PR gets a newer push.
- Cache dependency installs on the setup step so they are served from cache.
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:
- Dependency installs
- Network fetches
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.