From b209a40c79f0a67fccc95adaf6d76b07a034b121 Mon Sep 17 00:00:00 2001 From: Carson Date: Fri, 6 Mar 2026 09:40:30 -0600 Subject: [PATCH 1/7] ci: build Python wheel once per OS, test across Python versions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split the Python CI workflow into build and test phases. The build job compiles the abi3 wheel once per OS, then test jobs download and install it across Python 3.10-3.13. This avoids redundant Rust compilation — particularly on Windows where builds take ~30 min each. Also removes path filters so Python tests run on all repo changes, since the build overhead is now minimal. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/python.yml | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 58ba9621..34c86985 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -2,24 +2,21 @@ name: Python on: push: - paths: ['ggsql-python/**', '.github/workflows/python.yml'] pull_request: - paths: ['ggsql-python/**', '.github/workflows/python.yml'] jobs: - test: + build: strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python: ['3.10', '3.11', '3.12', '3.13'] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: - python-version: ${{ matrix.python }} + python-version: '3.10' - uses: actions/setup-node@v4 with: @@ -45,10 +42,37 @@ jobs: args: --release sccache: true + - name: Upload wheel + uses: actions/upload-artifact@v4 + with: + name: wheel-${{ matrix.os }} + path: target/wheels/ggsql-*.whl + + test: + needs: build + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + python: ['3.10', '3.11', '3.12', '3.13'] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python }} + + - name: Download wheel + uses: actions/download-artifact@v4 + with: + name: wheel-${{ matrix.os }} + path: dist + - name: Install wheel and test dependencies shell: bash run: | - WHEEL=$(ls target/wheels/ggsql-*.whl) + WHEEL=$(ls dist/ggsql-*.whl) pip install "${WHEEL}[test]" - name: Run tests From d8b29c5fe90958b4de5a479a26914acd9d55678f Mon Sep 17 00:00:00 2001 From: Carson Date: Fri, 6 Mar 2026 09:44:49 -0600 Subject: [PATCH 2/7] ci: use Python 3.11 for wheel build step Co-Authored-By: Claude Opus 4.6 --- .github/workflows/python.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 34c86985..b32d9d54 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: '3.11' - uses: actions/setup-node@v4 with: From 0c2042634f0aa745105b49d0ec6dcf50bfadee9e Mon Sep 17 00:00:00 2001 From: Carson Date: Fri, 6 Mar 2026 09:50:15 -0600 Subject: [PATCH 3/7] Revert "ci: use Python 3.11 for wheel build step" This reverts commit d8b29c5fe90958b4de5a479a26914acd9d55678f. --- .github/workflows/python.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index b32d9d54..34c86985 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/setup-python@v5 with: - python-version: '3.11' + python-version: '3.10' - uses: actions/setup-node@v4 with: From 28ce4032daad949b536d1d6c37d1e40ea2384c17 Mon Sep 17 00:00:00 2001 From: Carson Date: Fri, 6 Mar 2026 11:01:57 -0600 Subject: [PATCH 4/7] ci: set CC_WRAPPER=sccache to cache C/C++ builds on Windows sccache sees zero C/C++ compilations on Windows because the cc crate doesn't auto-detect sccache as a compiler wrapper with MSVC. Setting CC_WRAPPER=sccache explicitly routes cl.exe calls through sccache, enabling caching of DuckDB and other C/C++ dependency builds. The first run will still be slow (all cache misses), but subsequent runs should benefit from ~300 cached C/C++ compilation results. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/python.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 34c86985..5d863c61 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -41,6 +41,10 @@ jobs: command: build args: --release sccache: true + env: + # Ensure the cc crate routes C/C++ compilations (e.g. DuckDB) + # through sccache on all platforms, including Windows/MSVC + CC_WRAPPER: sccache - name: Upload wheel uses: actions/upload-artifact@v4 From 8a43ba7ebd7a4d521bccb8b449ae2f3e31f6e481 Mon Sep 17 00:00:00 2001 From: Carson Date: Fri, 6 Mar 2026 11:33:15 -0600 Subject: [PATCH 5/7] ci: use CC/CXX=sccache cl on Windows to cache DuckDB C++ builds CC_WRAPPER didn't work because the cc crate doesn't check that env var. The real issue: when the cc crate finds MSVC cl.exe via find_msvc_tools, it bypasses the RUSTC_WRAPPER-based sccache fallback that works on Linux. Setting CC/CXX='sccache cl' on Windows makes the cc crate's env_tool parser recognize "sccache" as a known wrapper and "cl" as the compiler. This routes the ~21-minute libduckdb-sys C++ build through sccache. First run will still be slow (cache seeding), but subsequent runs should see C/C++ cache hits and significantly faster Windows builds. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/python.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 5d863c61..5d521606 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -42,9 +42,12 @@ jobs: args: --release sccache: true env: - # Ensure the cc crate routes C/C++ compilations (e.g. DuckDB) - # through sccache on all platforms, including Windows/MSVC - CC_WRAPPER: sccache + # On Windows/MSVC, the cc crate's cl.exe detection bypasses its + # RUSTC_WRAPPER-based sccache fallback. Setting CC/CXX explicitly + # makes the cc crate parse "sccache" as a known wrapper and "cl" + # as the compiler, routing DuckDB C++ builds through sccache. + CC: ${{ runner.os == 'Windows' && 'sccache cl' || '' }} + CXX: ${{ runner.os == 'Windows' && 'sccache cl' || '' }} - name: Upload wheel uses: actions/upload-artifact@v4 From d6b96380484157e83dacaae60369710b12eef58a Mon Sep 17 00:00:00 2001 From: Carson Date: Fri, 6 Mar 2026 13:42:51 -0600 Subject: [PATCH 6/7] ci: use ilammy/msvc-dev-cmd to put cl.exe on PATH for sccache The previous attempt failed because sccache couldn't find bare 'cl' - MSVC tools aren't on PATH by default. ilammy/msvc-dev-cmd runs vcvarsall to set up the MSVC environment, putting cl.exe on PATH so that 'sccache cl' works as a CC/CXX wrapper. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/python.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 5d521606..c5b52337 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -34,6 +34,10 @@ jobs: workspaces: ggsql-python shared-key: ${{ matrix.os }}-python + - name: Set up MSVC (Windows) + if: runner.os == 'Windows' + uses: ilammy/msvc-dev-cmd@v1 + - name: Build wheel uses: PyO3/maturin-action@v1 with: @@ -43,9 +47,10 @@ jobs: sccache: true env: # On Windows/MSVC, the cc crate's cl.exe detection bypasses its - # RUSTC_WRAPPER-based sccache fallback. Setting CC/CXX explicitly - # makes the cc crate parse "sccache" as a known wrapper and "cl" - # as the compiler, routing DuckDB C++ builds through sccache. + # RUSTC_WRAPPER-based sccache fallback. Setting CC/CXX tells the + # cc crate to parse "sccache" as a known wrapper and "cl" as the + # compiler, routing DuckDB C++ builds through sccache. + # ilammy/msvc-dev-cmd puts cl.exe on PATH so sccache can find it. CC: ${{ runner.os == 'Windows' && 'sccache cl' || '' }} CXX: ${{ runner.os == 'Windows' && 'sccache cl' || '' }} From 5fb4994071305e214f853236f7d252b5dd006479 Mon Sep 17 00:00:00 2001 From: Carson Date: Fri, 6 Mar 2026 14:27:33 -0600 Subject: [PATCH 7/7] ci: simplify back to single test job now that sccache caches C++ on Windows Remove the build/test split since sccache should make Windows builds fast enough (~5 min) that compiling per Python version is acceptable. The diff from main is now minimal: remove path filters, add MSVC setup + CC/CXX env vars for sccache C++ caching on Windows. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/python.yml | 34 ++++------------------------------ 1 file changed, 4 insertions(+), 30 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index c5b52337..a52a12c6 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -5,18 +5,19 @@ on: pull_request: jobs: - build: + test: strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] + python: ['3.10', '3.11', '3.12', '3.13'] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: ${{ matrix.python }} - uses: actions/setup-node@v4 with: @@ -54,37 +55,10 @@ jobs: CC: ${{ runner.os == 'Windows' && 'sccache cl' || '' }} CXX: ${{ runner.os == 'Windows' && 'sccache cl' || '' }} - - name: Upload wheel - uses: actions/upload-artifact@v4 - with: - name: wheel-${{ matrix.os }} - path: target/wheels/ggsql-*.whl - - test: - needs: build - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - python: ['3.10', '3.11', '3.12', '3.13'] - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python }} - - - name: Download wheel - uses: actions/download-artifact@v4 - with: - name: wheel-${{ matrix.os }} - path: dist - - name: Install wheel and test dependencies shell: bash run: | - WHEEL=$(ls dist/ggsql-*.whl) + WHEEL=$(ls target/wheels/ggsql-*.whl) pip install "${WHEEL}[test]" - name: Run tests