Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
55 changes: 43 additions & 12 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,20 @@ on:
- 'v*-beta*'
release:
types: [published]
# Build and test, but never publish, when packaging changes, so a broken
# release pipeline is caught in review rather than at release time.
pull_request:
paths:
- '.github/workflows/publish.yml'
- 'accel.c'
- 'setup.py'
- 'setup.cfg'
- 'pyproject.toml'
- 'MANIFEST.in'
# Runner images and cibuildwheel's toolchains are retired out from under the
# workflow with no change to this repo, so build and test weekly as well.
schedule:
- cron: '0 6 * * 1'
workflow_dispatch:
inputs:
publish_pypi:
Expand All @@ -36,7 +50,14 @@ on:
jobs:

setup-database:
runs-on: ubuntu-latest
# Pull requests from forks get no secrets, so they cannot deploy the test
# cluster.
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
Comment thread
kesmit13 marked this conversation as resolved.
Resolved
# Pinned, not ubuntu-latest: that label is moving to Ubuntu 26.04, and
# this job, publish and shutdown-database run on the image's own Python
# rather than one from setup-python, so the move would change it under
# them. The weekly scheduled run flags this image's retirement.
runs-on: ubuntu-24.04

steps:
- uses: actions/checkout@v7
Expand Down Expand Up @@ -69,6 +90,10 @@ jobs:

build-and-test:
needs: setup-database
# setup-database is skipped only for a fork's pull request, which has no
# secrets. Those runs still build every wheel and check that its extension
# loads; only the cluster tests are left out.
if: ${{ !cancelled() && (needs.setup-database.result == 'success' || needs.setup-database.result == 'skipped') }}

name: Build and test wheels on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
Expand All @@ -77,7 +102,7 @@ jobs:
matrix:
os:
- ubuntu-24.04
- macos-14
- macos-15
- windows-2022

steps:
Expand Down Expand Up @@ -127,23 +152,24 @@ jobs:
# only reruns the tests there, so the oldest and newest supported
# interpreters both load the extension.
CIBW_BUILD: "cp39-* cp315-*"
CIBW_SKIP: "pp* *-musllinux* *-manylinux_i686"
CIBW_SKIP: "*-musllinux* *-manylinux_i686"
# cibuildwheel v3+ builds on manylinux_2_28 (glibc 2.28) by default.
# Pin manylinux2014 (glibc 2.17) so CentOS/RHEL 7, Amazon Linux 2 and
# Ubuntu 18.04 still get the C extension instead of falling back to
# the pure-Python wheel without any warning.
CIBW_MANYLINUX_X86_64_IMAGE: manylinux2014
CIBW_MANYLINUX_AARCH64_IMAGE: manylinux2014
CIBW_TEST_COMMAND: "pytest -v --pyargs singlestoredb.tests.test_basics"
# xdist because pyproject.toml's addopts sets -n/--dist, and PYTHONPATH
# points --pyargs at the workspace, so that pyproject is the inifile
# here. Without the plugin pytest exits on the unknown arguments.
CIBW_TEST_REQUIRES: "pytest pytest-xdist"
CIBW_TEST_COMMAND: ${{ needs.setup-database.result == 'success' && 'pytest -v --pyargs singlestoredb.tests.test_basics' || 'python -c "import _singlestoredb_accel, singlestoredb"' }}
CIBW_TEST_REQUIRES: "pytest"
# CLUSTER_PASSWORD has to survive both the userinfo half of the URL
# and the single-quoted shell word cibuildwheel evaluates, so keep the
# secret alphanumeric: no ':', '@', '/', '%' or quote characters.
CIBW_ENVIRONMENT: "SINGLESTOREDB_URL='mysql://admin:${{ secrets.CLUSTER_PASSWORD }}@${{ needs.setup-database.outputs.cluster-host }}:3306/${{ needs.setup-database.outputs.cluster-database }}?pure_python=0'"
PYTHONPATH: ${{ github.workspace }}
# No PYTHONPATH here: it would put the checkout ahead of the installed
# wheel, so the tests would import the checkout's singlestoredb and the
# extension that `pip install -e` built in place for the host Python,
# not the wheel under test. On Windows the 64-bit host's extension
# then fails to load in the 32-bit test interpreter.

# - name: Build conda
# if: ${{ matrix.os != 'windows-latest' }}
Expand Down Expand Up @@ -186,8 +212,10 @@ jobs:

publish:
needs: build-and-test
if: ${{ github.event_name != 'pull_request' && github.event_name != 'schedule' }}

runs-on: ubuntu-latest
# Pinned for the same reason as setup-database.
runs-on: ubuntu-24.04

permissions:
id-token: write # Required for OIDC trusted publishing and actions/attest
Expand Down Expand Up @@ -258,8 +286,11 @@ jobs:

shutdown-database:
needs: [setup-database, build-and-test]
if: ${{ always() }}
runs-on: ubuntu-latest
# Not when setup-database was skipped (a fork's pull request): there is
# no cluster, and the empty ID would fail the shutdown step.
if: ${{ always() && needs.setup-database.result != 'skipped' }}
# Pinned for the same reason as setup-database.
runs-on: ubuntu-24.04

steps:
- uses: actions/checkout@v7
Expand Down
11 changes: 7 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
[build-system]
requires = ["build", "setuptools>=61.0", "wheel"]
requires = ["build", "setuptools>=77.0"]
build-backend = "setuptools.build_meta"

[project]
name = "singlestoredb"
version = "1.18.2"
description = "Interface to the SingleStoreDB database and workspace management APIs"
readme = {file = "README.md", content-type = "text/markdown"}
license = {text = "Apache-2.0"}
license = "Apache-2.0"
license-files = ["LICENSE"]
authors = [
{name = "SingleStore", email = "support@singlestore.com"}
]
Expand Down Expand Up @@ -69,7 +70,7 @@ docs = [
]
build = [
"build",
"setuptools>=61.0",
"setuptools>=77.0",
"wheel",
]
dev = [
Expand All @@ -86,7 +87,9 @@ singlestoredb = "singlestoredb.pytest"
include-package-data = true

[tool.setuptools.packages.find]
exclude = ["docs*", "resources*", "examples*", "licenses*"]
# build* because discovery includes namespace packages, so an earlier build's
# build/lib/ tree would otherwise be packaged as a package of its own.
exclude = ["build*", "docs*", "resources*", "examples*", "licenses*"]

[tool.setuptools.package-data]
"*" = ["*.typed", "*.sql", "*.csv", "*.ipynb"]
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from setuptools import Extension
from setuptools import setup
from wheel.bdist_wheel import bdist_wheel
from setuptools.command.bdist_wheel import bdist_wheel


py_limited_api = '0x03080000'
Expand Down
3 changes: 3 additions & 0 deletions singlestoredb/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,9 @@ def pytest_sessionfinish(session: pytest.Session, exitstatus: int) -> None:
pass


# An xdist hook. Optional so the suite still starts where xdist is not
# installed, as when the release build tests the wheel's own copy of it.
@pytest.hookimpl(optionalhook=True)
def pytest_testnodedown(node: Any, error: Any) -> None:
"""
Report, on the controller, what a worker could not terminate.
Expand Down
Loading