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
4 changes: 2 additions & 2 deletions .agents/project.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,6 @@
4. Verifies the published image and runs the e2e suite against it.

The library, the CLI and the image always share one version.
- The image (`Dockerfile`) has two stages. The builder, `python:3.14-slim-bookworm` with uv, installs from `uv.lock` with the `cli` extra. The runtime is `gcr.io/distroless/cc-debian12:nonroot` (no shell, UID 65532), with `python -m pg_partsmith.cli` as the entrypoint. `.dockerignore` is an allow-list, so the build sees a new file only once it is listed there. CI builds the image on both architectures, fails it above 160 MB, and runs the e2e suite and a Trivy scan on it. Base images are written out in `FROM` lines rather than build arguments, so Dependabot can bump them.
- Tests: markers `unit`, `integration`, `e2e` and `database_clock` (`--strict-markers`). `tests/conftest.py` marks `tests/unit/` and `tests/integration/` by directory. The e2e modules mark themselves and skip without `PG_PARTSMITH_E2E_IMAGE`. Integration tests start `postgres:17-alpine` (`PG_PARTSMITH_TEST_PG_IMAGE` picks another) and skip without Docker. Warnings are errors. CI runs the unit tests on Python 3.11 to 3.14 on Linux, on 3.11 and 3.14 on Windows and macOS, on 3.14 on arm64, and with `TZ` at UTC+14 and UTC-12. One job installs every direct dependency at its lowest declared version on 3.11: raise a bound rather than work around an old version (CONTRIBUTING.md).
- The image (`Dockerfile`) has two stages. The builder, `python:3.15-slim-bookworm` with uv, installs from `uv.lock` with the `cli` extra. The runtime is `gcr.io/distroless/cc-debian12:nonroot` (no shell, UID 65532), with `python -m pg_partsmith.cli` as the entrypoint. `.dockerignore` is an allow-list, so the build sees a new file only once it is listed there. CI builds the image on both architectures, fails it above 160 MB, and runs the e2e suite and a Trivy scan on it. Base images are written out in `FROM` lines rather than build arguments, so Dependabot can bump them.
- Tests: markers `unit`, `integration`, `e2e` and `database_clock` (`--strict-markers`). `tests/conftest.py` marks `tests/unit/` and `tests/integration/` by directory. The e2e modules mark themselves and skip without `PG_PARTSMITH_E2E_IMAGE`. Integration tests start `postgres:17-alpine` (`PG_PARTSMITH_TEST_PG_IMAGE` picks another) and skip without Docker. Warnings are errors. CI runs the unit tests on Python 3.11 to 3.15 on Linux, on 3.11 and 3.15 on Windows and macOS, on 3.15 on arm64, and with `TZ` at UTC+14 and UTC-12. One job installs every direct dependency at its lowest declared version on 3.11: raise a bound rather than work around an old version (CONTRIBUTING.md).
- Code style (CONTRIBUTING.md): type hints on every function, tests included; lines up to 120 characters; double quotes; comments only for a non-obvious why. Docstrings are Google style, on the public API only; mkdocstrings renders the API reference from them. CONTRIBUTING.md says one line at most, but most public methods carry `Args:`, `Returns:` and `Raises:` sections, so follow the surrounding code. CONTRIBUTING.md also gives the steps for adding a period strategy, a boundary codec or a lock manager.
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,15 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest]
python-version: ["3.11", "3.12", "3.13", "3.14"]
python-version: ["3.11", "3.12", "3.13", "3.14", "3.15"]
# The other platforms at both ends of the range: the CLI runs
# subprocesses and handles signals differently on each of them.
include:
- { os: windows-latest, python-version: "3.11" }
- { os: windows-latest, python-version: "3.14" }
- { os: windows-latest, python-version: "3.15" }
- { os: macos-latest, python-version: "3.11" }
- { os: macos-latest, python-version: "3.14" }
- { os: ubuntu-24.04-arm, python-version: "3.14" }
- { os: macos-latest, python-version: "3.15" }
- { os: ubuntu-24.04-arm, python-version: "3.15" }
steps:
- uses: actions/checkout@v7
- uses: astral-sh/setup-uv@v7
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
# Dependabot reads FROM lines, and a rebuild on a base-image fix is what it is for.
FROM ghcr.io/astral-sh/uv:0.13.1 AS uv

FROM python:3.14-slim-bookworm AS builder
FROM python:3.15-slim-bookworm AS builder

# binutils for strip; nothing else is installed into the image being built.
RUN apt-get update -qq \
Expand Down
2 changes: 1 addition & 1 deletion docs/agents.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ A configuration is a **scheme** — the shape of the tree, level by level — an
by `validate`. No sandbox is claimed. Hooks never fire during `plan`. See
`guide/hooks-in-config.md`.
* The same CLI ships as `ghcr.io/bedrock-python/pg-partsmith:<version>` with the command
as its entrypoint: distroless, Python 3.14, no shell, no pip, UID 65532, signed, with an
as its entrypoint: distroless, Python 3.15, no shell, no pip, UID 65532, signed, with an
SBOM and provenance; tags are the exact version, a moving minor and `latest` for the newest release. See
`guide/container.md` for the image and `guide/running.md` for every harness: plain
Docker, Compose (`docker compose run`, `service_completed_successfully`, a cron
Expand Down
4 changes: 2 additions & 2 deletions docs/guide/container.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Two stages, and only the second one ships.

The runtime base is [distroless](https://github.com/GoogleContainerTools/distroless)
`cc-debian12`: glibc, OpenSSL, CA certificates, a timezone database, and nothing else.
**No shell, no package manager, no pip.** Onto that go a Python 3.14 interpreter with a
**No shell, no package manager, no pip.** Onto that go a Python 3.15 interpreter with a
pruned standard library (no IDE, no Tk, no test suite, no REPL modules), one virtualenv
installed from `uv.lock` — the versions the test suite ran against, never whatever the
index served on build day — and exactly the five shared libraries the extension modules
Expand All @@ -42,7 +42,7 @@ Because there is no shell, the two things a wrapper used to do are flags:
textfile), and `apply --ok-if-locked` makes a held lock exit `0` (an init container). A
command hook inside this image is a binary, or a Python file run as
`["/opt/venv/bin/python", "/opt/hooks/export.py"]` — not a shell script. A team that
needs bash in the image builds one line of its own: `FROM python:3.14-slim` and
needs bash in the image builds one line of its own: `FROM python:3.15-slim` and
`pip install "pg-partsmith[cli]"`.

## Inputs
Expand Down
4 changes: 2 additions & 2 deletions docs/guide/running.md
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ hooks:
Either way, `apply` needs `--allow-hooks`, and the document declaring hooks is refused
without it — see [Commands around the lifecycle](hooks-in-config.md). The bash scripts
under `examples/hooks/` are for a host that has bash; a team that wants them in the image
builds its own from `python:3.14-slim` with `pip install "pg-partsmith[cli]"`.
builds its own from `python:3.15-slim` with `pip install "pg-partsmith[cli]"`.

## CI

Expand All @@ -475,7 +475,7 @@ works, every table it describes is partitioned the way it claims.
```yaml
# GitLab CI
validate-partitions:
image: python:3.14-slim
image: python:3.15-slim
before_script:
- pip install --quiet "pg-partsmith[cli]"
script:
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ classifiers = [
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Programming Language :: Python :: 3.15",
"Topic :: Database",
"Topic :: Software Development :: Libraries :: Python Modules",
"Typing :: Typed",
Expand Down
Loading
Loading