Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
ecd0c87
explicitly import importlib.util; remove erroneous print
Oct 28, 2025
50c802b
Fix ADBC driver path resolution when `importlib.util` was not implici…
evertlammerts Oct 28, 2025
e825f82
bumped submodule
evertlammerts Oct 31, 2025
ec3264b
add targeted test workflow
evertlammerts Oct 30, 2025
d8d7832
add targeted test workflow (#145)
evertlammerts Oct 31, 2025
fdef1fc
Remove xfail annotations on adbc tests
evertlammerts Oct 31, 2025
135f09c
Remove xfail annotations on adbc tests (#147)
evertlammerts Oct 31, 2025
0304a87
fix config dict value typehint
evertlammerts Oct 31, 2025
66abe60
fix config dict value typehint (#151)
evertlammerts Oct 31, 2025
e991b2a
Add df data and tz type columns back into the same loc after type con…
evertlammerts Oct 31, 2025
fd1c34f
Add df data and tz type columns back into the same loc after type con…
evertlammerts Oct 31, 2025
83aa04a
Enable pyarrow with python 3.14
evertlammerts Oct 31, 2025
6e95472
Enable pyarrow with python 3.14 (#152)
evertlammerts Nov 1, 2025
4838232
use macos-15-intel now that macos-13 is closing down
evertlammerts Nov 1, 2025
07c1414
release s3 upload fix
evertlammerts Nov 1, 2025
c04f9b8
spark imports
evertlammerts Nov 4, 2025
353566b
spark imports (#157)
evertlammerts Nov 4, 2025
02ceac1
Bumped submodule
evertlammerts Nov 5, 2025
c14473e
Fix failing test due to changed error msg
evertlammerts Nov 5, 2025
538c10a
Fix failing test due to changed error msg (#158)
evertlammerts Nov 5, 2025
e35a2ce
mypy shouldn't check experimental.spark
evertlammerts Nov 5, 2025
17a0cad
remove experimental import because of the transitive dependencies tha…
evertlammerts Nov 5, 2025
f5618a3
Bumped submodule
evertlammerts Nov 7, 2025
f3b8c8a
Bumped submodule
evertlammerts Nov 7, 2025
95a9968
Fix InsertRelation on attached database
evertlammerts Nov 1, 2025
10e0ef3
Add explicit polars overloads
J-Meyers Nov 9, 2025
20bfd52
review feedback
evertlammerts Nov 6, 2025
7ccc8e9
Add explicit .pl(lazy=True) overload (#172)
evertlammerts Nov 10, 2025
13827e7
Fix InsertRelation on attached database (#155)
evertlammerts Nov 10, 2025
70380a1
Submodule at 68d7555 for 1.4.2 release
evertlammerts Nov 11, 2025
30e53c4
Fix project metadata
evertlammerts Nov 12, 2025
5442569
Fix project metadata (#174)
evertlammerts Nov 12, 2025
4746ac8
Create a PR to bump submodule if nightly is stale
evertlammerts Nov 5, 2025
8b104c0
Create a PR to bump submodule if nightly is stale (#159)
evertlammerts Nov 19, 2025
96762c1
Bump submodule
duckdblabs-bot Nov 19, 2025
b7973e8
[duckdb-labs bot] Bump DuckDB submodule (#185)
evertlammerts Nov 19, 2025
8f1aa4b
Bump submodule
duckdblabs-bot Nov 20, 2025
51d7260
[duckdb-labs bot] Bump DuckDB submodule (#186)
evertlammerts Nov 20, 2025
c7ed4f6
Bump submodule
duckdblabs-bot Nov 21, 2025
1dcc1c5
[duckdb-labs bot] Bump DuckDB submodule (#188)
evertlammerts Nov 21, 2025
4460b32
don't fail if the submodule is at the same commit as the input
evertlammerts Nov 24, 2025
c542c18
Bump submodule
duckdblabs-bot Nov 26, 2025
b9f4571
[duckdb-labs bot] Bump DuckDB submodule (#191)
evertlammerts Nov 26, 2025
d1a4643
Bump submodule
duckdblabs-bot Nov 29, 2025
f6b01c8
[duckdb-labs bot] Bump DuckDB submodule (#197)
evertlammerts Nov 29, 2025
9ec8614
Bump submodule
duckdblabs-bot Nov 30, 2025
f053a52
[duckdb-labs bot] Bump DuckDB submodule (#198)
evertlammerts Nov 30, 2025
f39e010
Bump submodule
duckdblabs-bot Dec 2, 2025
8944767
[duckdb-labs bot] Bump DuckDB submodule (#202)
evertlammerts Dec 2, 2025
8ab292c
Add filename_pattern to to_parquet Python API
matthew-bayer Dec 1, 2025
5cb2afb
Fix linting and test
evertlammerts Dec 2, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/packaging_wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
- { os: ubuntu-24.04-arm, arch: aarch64, cibw_system: manylinux }
- { os: macos-15, arch: arm64, cibw_system: macosx }
- { os: macos-15, arch: universal2, cibw_system: macosx }
- { os: macos-13, arch: x86_64, cibw_system: macosx }
- { os: macos-15-intel, arch: x86_64, cibw_system: macosx }
minimal:
- ${{ inputs.minimal }}
exclude:
Expand Down
73 changes: 50 additions & 23 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ on:
options:
- test
- prod
nightly-stale-after-days:
type: string
description: After how many days should nightlies be considered stale
required: true
default: 3
store-s3:
type: boolean
description: Also store test packages in S3 (always true for prod)
Expand All @@ -41,6 +46,17 @@ jobs:
duckdb-sha: ${{ inputs.duckdb-sha }}
set-version: ${{ inputs.stable-version }}

submodule_pr:
name: Create or update PR to bump submodule to given SHA
needs: build_sdist
uses: ./.github/workflows/submodule_auto_pr.yml
with:
duckdb-python-sha: ${{ inputs.duckdb-python-sha }}
duckdb-sha: ${{ inputs.duckdb-sha }}
secrets:
# reusable workflows and secrets are not great: https://github.com/actions/runner/issues/3206
DUCKDBLABS_BOT_TOKEN: ${{ secrets.DUCKDBLABS_BOT_TOKEN }}

workflow_state:
name: Set state for the release workflow
needs: build_sdist
Expand All @@ -51,23 +67,36 @@ jobs:
runs-on: ubuntu-latest
steps:
- id: index_check
name: Check ${{ needs.build_sdist.outputs.package-version }} on PyPI
name: Check version on PyPI
run: |
set -eu
# Check PyPI whether the release we're building is already present
set -ex
pypi_hostname=${{ inputs.pypi-index == 'test' && 'test.' || '' }}pypi.org
pkg_version=${{ needs.build_sdist.outputs.package-version }}
url=https://${pypi_hostname}/pypi/duckdb/${pkg_version}/json
http_status=$( curl -s -o /dev/null -w "%{http_code}" $url || echo $? )
if [[ $http_status == "200" ]]; then
echo "::warning::Package version ${pkg_version} is already present on ${pypi_hostname}"
pypi_state=VERSION_FOUND
elif [[ $http_status == 000* ]]; then
echo "::error::Error checking PyPI at ${url}: curl exit code ${http_status#'000'}"
pypi_state=UNKNOWN
else
echo "::notice::Package version ${pkg_version} not found on ${pypi_hostname} (http status: ${http_status})"
# install duckdb
curl https://install.duckdb.org | sh
# query pypi
result=$(cat <<EOF | ${HOME}/.duckdb/cli/latest/duckdb | xargs
---- Output lines
.mode line
---- Query that fetches the given version's age, if the version already exists
SELECT
today() - (file.value->>'upload_time_iso_8601')::DATE AS age,
FROM read_json('https://${pypi_hostname}/pypi/duckdb/json') AS jd
CROSS JOIN json_each(jd.releases) AS rel(key, value)
CROSS JOIN unnest(FROM_JSON(rel.value, '["JSON"]')) AS file(value)
WHERE rel.key='${{ needs.build_sdist.outputs.package-version }}'
LIMIT 1;
EOF
)
if [ -z "$result" ]; then
pypi_state=VERSION_NOT_FOUND
else
pypi_state=VERSION_FOUND
fi
if [[ -z "${{ inputs.stable-version }}" ]]; then
age=${result#age = }
if [ "${age}" -ge "${{ inputs.nightly-stale-after-days }}" ]; then
echo "::warning title=Stale nightly for ${{ github.ref_name }}::Nightly is ${age} days old (max=${{ inputs.nightly-stale-after-days }})"
fi
fi
echo "pypi_state=${pypi_state}" >> $GITHUB_OUTPUT

Expand Down Expand Up @@ -96,7 +125,7 @@ jobs:
echo "::notice::S3 upload disabled in inputs, not generating S3 URL"
exit 0
fi
if [[ VERSION_FOUND == "${{ steps.index_check.outputs.pypi_state }}" ]]; then
if [[ VERSION_NOT_FOUND != "${{ steps.index_check.outputs.pypi_state }}" ]]; then
echo "::warning::S3 upload disabled because package version already uploaded to PyPI"
exit 0
fi
Expand All @@ -110,7 +139,7 @@ jobs:
build_wheels:
name: Build and test releases
needs: workflow_state
if: ${{ needs.workflow_state.outputs.pypi_state != 'VERSION_FOUND' }}
if: ${{ needs.workflow_state.outputs.pypi_state == 'VERSION_NOT_FOUND' }}
uses: ./.github/workflows/packaging_wheels.yml
with:
minimal: false
Expand All @@ -132,14 +161,12 @@ jobs:
path: artifacts/
merge-multiple: true

- name: Authenticate with AWS
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: 'us-east-2'
aws-access-key-id: ${{ secrets.S3_DUCKDB_STAGING_ID }}
aws-secret-access-key: ${{ secrets.S3_DUCKDB_STAGING_KEY }}

- name: Upload Artifacts
env:
AWS_ENDPOINT_URL: ${{ secrets.S3_DUCKDB_STAGING_ENDPOINT }}
AWS_ACCESS_KEY_ID: ${{ secrets.S3_DUCKDB_STAGING_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_DUCKDB_STAGING_KEY }}

run: |
aws s3 cp artifacts ${{ needs.workflow_state.outputs.s3_url }} --recursive

Expand Down
130 changes: 130 additions & 0 deletions .github/workflows/submodule_auto_pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
name: Submodule Auto PR
on:
workflow_call:
inputs:
duckdb-python-sha:
type: string
description: The commit to build against (defaults to latest commit of current ref)
required: false
duckdb-sha:
type: string
description: The DuckDB submodule commit or ref to build against
required: true
auto-land:
type: boolean
description: Immediately merge the PR (placeholder - doesn't work)
default: false
secrets:
DUCKDBLABS_BOT_TOKEN:
description: Github token of the DuckDBLabs bot
required: true

defaults:
run:
shell: bash

jobs:
create_pr:
name: Create PR to bump duckdb submodule to given SHA
runs-on: ubuntu-latest
steps:
- name: Checkout DuckDB Python
uses: actions/checkout@v4
with:
ref: ${{ inputs.duckdb-python-sha }}
fetch-depth: 0
submodules: true

- name: Checkout or Create Needed Branch
run: |
git fetch --all
head_sha=${{ inputs.duckdb-python-sha }}
branch_name="vendoring-${{ github.ref_name }}"
if [[ `git rev-parse --verify ${branch_name} 2>/dev/null` ]]; then
# branch exists
git checkout ${branch_name}
else
# new branch
git checkout -b ${branch_name}
fi
[[ ${head_sha} ]] && git reset --hard ${head_sha} || true

- name: Checkout DuckDB at Given SHA
run: |
cd external/duckdb
git fetch origin
git checkout ${{ inputs.duckdb-sha }}

- name: Determine GH PR Command
id: gh_pr_command
env:
GH_TOKEN: ${{ secrets.DUCKDBLABS_BOT_TOKEN }}
run: |
pr_url=$( gh pr list --head vendoring-${{ github.ref_name }} --state open --json url --jq '.[].url' )
if [[ $pr_url ]]; then
echo "::notice::Found existing pr, will edit (${pr_url})"
gh_command="edit ${pr_url}"
else
echo "::notice::No existing PR, will create new"
gh_command="create --head vendoring-${{ github.ref_name }} --base ${{ github.ref_name }}"
fi
echo "subcommand=${gh_command}" >> $GITHUB_OUTPUT

- name: Set Git User
run: |
git config --global user.email "github_bot@duckdblabs.com"
git config --global user.name "DuckDB Labs GitHub Bot"

- name: Create PR to Bump DuckDB Submodule
env:
GH_TOKEN: ${{ secrets.DUCKDBLABS_BOT_TOKEN }}
run: |
# No need to do anything if the submodule is already at the given sha
[[ `git status --porcelain -- external/duckdb` == "" ]] && exit 0
# We have changes. Commit and push
git add external/duckdb
git commit -m "Bump submodule"
git push --force origin vendoring-${{ github.ref_name }}
# create PR msg
echo "Bump duckdb submodule:" > body.txt
echo "- Target branch: ${{ github.ref_name }}" >> body.txt
echo "- Date: $( date +"%Y-%m-%d %H:%M:%S" )" >> body.txt
echo "- DuckDB SHA: ${{ inputs.duckdb-sha }}" >> body.txt
echo "- Trigger: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" >> body.txt
subcommand="${{ steps.gh_pr_command.outputs.subcommand }}"
gh pr ${subcommand} \
--title "[duckdb-labs bot] Bump DuckDB submodule" \
--body-file body.txt > output.txt 2>&1
success=$?
# Show summary
url=$( [[ $success ]] && gh pr view vendoring-${{ github.ref_name }} --json url --jq .url || true )
echo "## Submodule PR Summary" >> $GITHUB_STEP_SUMMARY
if [[ $success ]]; then
prefix=$( [[ $subcommand == edit* ]] && echo "Created" || echo "Updated" )
echo "### ${prefix} PR: [${url}](${url})" >> $GITHUB_STEP_SUMMARY
else
echo "### Failed to create PR" >> $GITHUB_STEP_SUMMARY
fi
echo '```' >> $GITHUB_STEP_SUMMARY
cat output.txt >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
[[ $success ]] || exit 1

- name: Automerge PR
if: ${{ inputs.auto-land }}
env:
GH_TOKEN: ${{ secrets.DUCKDBLABS_BOT_TOKEN }}
run: |
# PLACEHOLDER: DUCKDBLABS_BOT_TOKEN DOES NOT HAVE PERMISSIONS TO MERGE PRS
set -ex
gh pr merge vendoring-${{ github.ref_name }} --rebase > output.txt
success=$?
# Show summary
if [[ $success ]]; then
echo "### PR merged" >> $GITHUB_STEP_SUMMARY
else
echo "### Failed to auto-merge PR" >> $GITHUB_STEP_SUMMARY
fi
echo '```' >> $GITHUB_STEP_SUMMARY
cat output.txt >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
86 changes: 86 additions & 0 deletions .github/workflows/targeted_test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
name: Targeted Platform Testing

on:
workflow_dispatch:
inputs:
platform:
description: 'Platform to test on'
required: true
type: choice
options:
- 'windows-2025'
- 'ubuntu-24.04'
- 'ubuntu-24.04-arm'
- 'macos-15'
- 'macos-15-intel'
python_version:
description: 'Python version to test'
required: true
type: choice
options:
- '3.9'
- '3.10'
- '3.11'
- '3.12'
- '3.13'
- '3.14'
testsuite:
description: 'Test suite to run (ignored if custom_test_path is provided)'
required: false
type: choice
options:
- 'fast'
- 'all'
default: 'fast'
custom_test_path:
description: 'Custom test path (must be in tests/ directory, overrides testsuite)'
required: false
type: string

jobs:
test:
name: 'Test with Python ${{ inputs.python_version }} on ${{ inputs.platform }}'
runs-on: ${{ inputs.platform }}

steps:
- name: Checkout DuckDB Python
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: true

- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: "0.9.0"
enable-cache: false
python-version: ${{ inputs.python_version }}

- name: Set and validate test path
id: test_path
shell: bash
run: |
if [[ -n "${{ inputs.custom_test_path }}" ]]; then
# test path was passed in
tests_base="$( pwd -P )/tests"
test_path="${{ inputs.custom_test_path }}"

# Ensure the given test path exists
[[ -e "$test_path" ]] || { echo "${test_path} does not exist"; exit 1; }

# Resolve custom test path to absolute path
test_path_abs=$(cd "$test_path" 2>/dev/null && pwd -P || ( cd "$(dirname "$test_path")" && printf '%s/%s' "$(pwd -P)" "$(basename "$test_path")" ) )

# Make sure test_path_abs is inside tests_base
[[ "$test_path_abs" == "$tests_base" || "$test_path_abs" == "$tests_base"/* ]] || { echo "${test_path_abs} is not part of ${tests_base}?"; exit 1; }

echo "test_path=$test_path_abs" >> $GITHUB_OUTPUT
else
# use a testsuite
echo "test_path=$GITHUB_WORKSPACE/${{ inputs.testsuite == 'fast' && 'tests/fast' || 'tests' }}" >> $GITHUB_OUTPUT
fi

- name: Run tests
shell: bash
run: |
uv run pytest -vv ${{ steps.test_path.outputs.test_path }}
19 changes: 0 additions & 19 deletions CHANGELOG.md

This file was deleted.

Loading
Loading