continuo-python-runtime 0.4.0__tar.gz → 0.4.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/.github/workflows/ci.yml +5 -5
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/.github/workflows/dco.yml +1 -1
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/.github/workflows/images.yml +53 -20
- continuo_python_runtime-0.4.1/.github/workflows/publish-pypi.yml +99 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/.github/workflows/release.yml +1 -1
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/.github/workflows/security.yml +2 -2
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/CONTRIBUTING.md +2 -2
- continuo_python_runtime-0.4.1/Dockerfile.postgres +56 -0
- continuo_python_runtime-0.4.1/Dockerfile.trino +56 -0
- continuo_python_runtime-0.4.0/README.md → continuo_python_runtime-0.4.1/PKG-INFO +78 -25
- continuo_python_runtime-0.4.0/PKG-INFO → continuo_python_runtime-0.4.1/README.md +58 -45
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/adapters/postgres/README.md +1 -1
- {continuo_python_runtime-0.4.0/adapters/postgres/continuo_python_runtime_postgres → continuo_python_runtime-0.4.1/adapters/postgres/continuo_postgres_adapter}/adapter.py +1 -1
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/adapters/postgres/pyproject.toml +13 -9
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/adapters/postgres/tests/test_adapter_postgres_validation.py +1 -1
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/adapters/postgres/tests/test_adapter_runtime_postgres.py +2 -2
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/adapters/postgres/tests/test_integration_postgres_validation.py +1 -1
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/adapters/postgres/tests/test_integration_runtime_postgres.py +1 -1
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/adapters/trino/README.md +2 -2
- {continuo_python_runtime-0.4.0/adapters/trino/continuo_python_runtime_trino → continuo_python_runtime-0.4.1/adapters/trino/continuo_trino_adapter}/adapter.py +1 -1
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/adapters/trino/pyproject.toml +12 -8
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/adapters/trino/tests/test_adapter_runtime_trino.py +2 -2
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/adapters/trino/tests/test_adapter_trino_validation.py +1 -1
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/adapters/trino/tests/test_integration_runtime_trino.py +2 -2
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/adapters/trino/tests/test_integration_trino_validation.py +1 -1
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/contract/pyproject.toml +2 -2
- continuo_python_runtime-0.4.1/image-requirements-postgres.txt +2 -0
- continuo_python_runtime-0.4.1/image-requirements-trino.txt +2 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/pyproject.toml +17 -8
- continuo_python_runtime-0.4.1/scripts/check_version_bumps.py +65 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/template/Dockerfile +1 -1
- continuo_python_runtime-0.4.1/template/Dockerfile.pip +23 -0
- continuo_python_runtime-0.4.1/template/README.md +82 -0
- continuo_python_runtime-0.4.1/template/requirements.lock +22 -0
- continuo_python_runtime-0.4.1/tests/test_adapter_naming.py +41 -0
- continuo_python_runtime-0.4.1/tests/test_image_requirements_sync.py +36 -0
- continuo_python_runtime-0.4.1/uv.lock +827 -0
- continuo_python_runtime-0.4.0/.github/workflows/publish-pypi.yml +0 -74
- continuo_python_runtime-0.4.0/Dockerfile.postgres +0 -22
- continuo_python_runtime-0.4.0/Dockerfile.trino +0 -22
- continuo_python_runtime-0.4.0/template/README.md +0 -36
- continuo_python_runtime-0.4.0/uv.lock +0 -666
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/.dockerignore +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/.github/CODEOWNERS +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/.github/dependabot.yml +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/.gitignore +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/.gitleaks.toml +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/CHANGELOG.md +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/CODE_OF_CONDUCT.md +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/DCO +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/LICENSE +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/NOTICE +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/SECURITY.md +0 -0
- {continuo_python_runtime-0.4.0/adapters/postgres/continuo_python_runtime_postgres → continuo_python_runtime-0.4.1/adapters/postgres/continuo_postgres_adapter}/__init__.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/adapters/postgres/tests/__init__.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/adapters/postgres/tests/conftest.py +0 -0
- {continuo_python_runtime-0.4.0/adapters/trino/continuo_python_runtime_trino → continuo_python_runtime-0.4.1/adapters/trino/continuo_trino_adapter}/__init__.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/adapters/trino/tests/__init__.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/continuo_python_runtime/__init__.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/continuo_python_runtime/cli.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/continuo_python_runtime/closure.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/continuo_python_runtime/conform.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/continuo_python_runtime/context.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/continuo_python_runtime/contract/__init__.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/continuo_python_runtime/contract/loader.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/continuo_python_runtime/contract/merge.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/continuo_python_runtime/contract/model.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/continuo_python_runtime/contract/paths.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/continuo_python_runtime/csv_loader.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/continuo_python_runtime/csv_readers/__init__.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/continuo_python_runtime/csv_readers/https.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/continuo_python_runtime/csv_readers/s3.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/continuo_python_runtime/csv_source.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/continuo_python_runtime/errors.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/continuo_python_runtime/harness.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/continuo_python_runtime/hashing.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/continuo_python_runtime/lint.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/continuo_python_runtime/types.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/continuo_python_runtime/validation/__init__.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/continuo_python_runtime/validation/runner.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/continuo_python_runtime/validation/s3.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/contract/LICENSE +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/contract/NOTICE +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/contract/README.md +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/contract/continuo_engine_contract/__init__.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/contract/continuo_engine_contract/config.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/contract/continuo_engine_contract/port.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/contract/continuo_engine_contract/result.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/contract/continuo_engine_contract/sql.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/contract/continuo_engine_contract/types.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/contract/tests/__init__.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/contract/tests/test_config.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/contract/tests/test_contract_types.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/contract/tests/test_port.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/contract/tests/test_result.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/contract/tests/test_sql.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/docs/boundary-contract.md +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/docs/superpowers/plans/2026-07-31-python-runtime.md +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/docs/superpowers/plans/2026-08-07-step-3b-config-three-part-hash.md +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/docs/superpowers/specs/2026-07-31-python-runtime-design.md +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/scripts/security-scan.sh +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/template/.github/workflows/release.yml +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/template/contracts/example.yml +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/template/contracts/example_csv.yml +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/template/scripts/example.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/__init__.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/conftest.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/contract/__init__.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/contract/test_loader.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/contract/test_merge.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/contract/test_model.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/smoke/node_smoke/contracts/smoke.yml +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/smoke/node_smoke/scripts/smoke.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/smoke/postgres-stack/docker-compose.yml +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/smoke/trino-stack/catalog/iceberg.properties +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/smoke/trino-stack/docker-compose.yml +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/test_cli.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/test_closure.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/test_conform.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/test_context.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/test_contract_loader.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/test_contract_pin_consistency.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/test_csv_loader.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/test_csv_readers_https.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/test_csv_readers_integration.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/test_csv_source.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/test_errors.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/test_harness.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/test_hashing.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/test_image_smoke_validation.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/test_lint.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/test_no_legacy_names.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/test_package.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/test_template.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/test_types.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/test_validation_runner.py +0 -0
- {continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/tests/test_validation_s3.py +0 -0
|
@@ -6,7 +6,7 @@ jobs:
|
|
|
6
6
|
test:
|
|
7
7
|
runs-on: ubuntu-latest
|
|
8
8
|
steps:
|
|
9
|
-
- uses: actions/checkout@
|
|
9
|
+
- uses: actions/checkout@v7
|
|
10
10
|
- uses: astral-sh/setup-uv@v7
|
|
11
11
|
- name: Sync
|
|
12
12
|
run: uv sync --all-packages --all-groups
|
|
@@ -19,9 +19,9 @@ jobs:
|
|
|
19
19
|
- name: Types (contract)
|
|
20
20
|
run: uv run mypy contract/continuo_engine_contract
|
|
21
21
|
- name: Types (postgres adapter)
|
|
22
|
-
run: uv run --package continuo-
|
|
22
|
+
run: uv run --package continuo-postgres-adapter mypy adapters/postgres/continuo_postgres_adapter
|
|
23
23
|
- name: Types (trino adapter)
|
|
24
|
-
run: uv run --package continuo-
|
|
24
|
+
run: uv run --package continuo-trino-adapter mypy adapters/trino/continuo_trino_adapter
|
|
25
25
|
# `-m "not image"` deselects tests/test_image_smoke_validation.py, which
|
|
26
26
|
# needs a built engine image and the env naming it. Those tests run in
|
|
27
27
|
# images.yml's smoke jobs, where an image actually exists. `and not
|
|
@@ -41,7 +41,7 @@ jobs:
|
|
|
41
41
|
integration-postgres:
|
|
42
42
|
runs-on: ubuntu-latest
|
|
43
43
|
steps:
|
|
44
|
-
- uses: actions/checkout@
|
|
44
|
+
- uses: actions/checkout@v7
|
|
45
45
|
- uses: astral-sh/setup-uv@v7
|
|
46
46
|
- run: uv sync --all-packages --all-groups
|
|
47
47
|
- name: Start postgres stack
|
|
@@ -55,7 +55,7 @@ jobs:
|
|
|
55
55
|
integration-trino:
|
|
56
56
|
runs-on: ubuntu-latest
|
|
57
57
|
steps:
|
|
58
|
-
- uses: actions/checkout@
|
|
58
|
+
- uses: actions/checkout@v7
|
|
59
59
|
- uses: astral-sh/setup-uv@v7
|
|
60
60
|
- run: uv sync --all-packages --all-groups
|
|
61
61
|
- name: Start trino stack
|
{continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/.github/workflows/images.yml
RENAMED
|
@@ -20,12 +20,15 @@ jobs:
|
|
|
20
20
|
engine: [postgres, trino]
|
|
21
21
|
runs-on: ubuntu-latest
|
|
22
22
|
steps:
|
|
23
|
-
- uses: actions/checkout@
|
|
23
|
+
- uses: actions/checkout@v7
|
|
24
|
+
- uses: astral-sh/setup-uv@v7
|
|
25
|
+
- name: Build wheels into a wheelhouse
|
|
26
|
+
run: uv build --all-packages -o wheelhouse
|
|
24
27
|
- name: Build ${{ matrix.engine }} image
|
|
25
|
-
run: docker build -f Dockerfile.${{ matrix.engine }} -t cpr-smoke-${{ matrix.engine }} .
|
|
28
|
+
run: docker build -f Dockerfile.${{ matrix.engine }} --build-arg WHEEL_SOURCE=wheelhouse -t cpr-smoke-${{ matrix.engine }} .
|
|
26
29
|
- name: Save image
|
|
27
30
|
run: docker save cpr-smoke-${{ matrix.engine }} -o /tmp/cpr-smoke-${{ matrix.engine }}.tar
|
|
28
|
-
- uses: actions/upload-artifact@
|
|
31
|
+
- uses: actions/upload-artifact@v7
|
|
29
32
|
with:
|
|
30
33
|
name: cpr-smoke-${{ matrix.engine }}-image
|
|
31
34
|
path: /tmp/cpr-smoke-${{ matrix.engine }}.tar
|
|
@@ -49,8 +52,8 @@ jobs:
|
|
|
49
52
|
--health-timeout 5s
|
|
50
53
|
--health-retries 10
|
|
51
54
|
steps:
|
|
52
|
-
- uses: actions/checkout@
|
|
53
|
-
- uses: actions/download-artifact@
|
|
55
|
+
- uses: actions/checkout@v7
|
|
56
|
+
- uses: actions/download-artifact@v8
|
|
54
57
|
with:
|
|
55
58
|
name: cpr-smoke-postgres-image
|
|
56
59
|
path: /tmp
|
|
@@ -104,8 +107,8 @@ jobs:
|
|
|
104
107
|
needs: build
|
|
105
108
|
runs-on: ubuntu-latest
|
|
106
109
|
steps:
|
|
107
|
-
- uses: actions/checkout@
|
|
108
|
-
- uses: actions/download-artifact@
|
|
110
|
+
- uses: actions/checkout@v7
|
|
111
|
+
- uses: actions/download-artifact@v8
|
|
109
112
|
with:
|
|
110
113
|
name: cpr-smoke-trino-image
|
|
111
114
|
path: /tmp
|
|
@@ -153,21 +156,31 @@ jobs:
|
|
|
153
156
|
if: always()
|
|
154
157
|
run: docker compose -f tests/smoke/trino-stack/docker-compose.yml down -v
|
|
155
158
|
|
|
156
|
-
#
|
|
157
|
-
#
|
|
158
|
-
#
|
|
159
|
-
#
|
|
159
|
+
# Runs on this same tag push, after the smoke jobs above pass. It builds both
|
|
160
|
+
# engine images for linux/amd64 and linux/arm64 installing the pinned
|
|
161
|
+
# versions FROM PyPI (WHEEL_SOURCE=pypi, the Dockerfile default), then
|
|
162
|
+
# pushes them to ghcr.io/<owner>/continuo-python-runtime-<engine>:<tag>. The
|
|
163
|
+
# engine belongs in the image NAME, not the tag: Continuo's Helm chart pins
|
|
164
|
+
# an image as `<name>:vX.Y.Z@sha256:<digest>`, so the tag must be the bare
|
|
160
165
|
# version. Both platforms are required: domain repos build their own images
|
|
161
166
|
# FROM these, and Continuo's e2e runs them in a kind cluster on aarch64
|
|
162
|
-
# developer machines as well as on amd64 CI runners, so a single-arch
|
|
163
|
-
# is unusable off amd64. The smoke jobs above stay single-arch —
|
|
164
|
-
# `docker save` tarball, which has no multi-platform
|
|
165
|
-
#
|
|
166
|
-
#
|
|
167
|
-
#
|
|
167
|
+
# developer machines as well as on amd64 CI runners, so a single-arch
|
|
168
|
+
# publish is unusable off amd64. The smoke jobs above stay single-arch —
|
|
169
|
+
# they load a `docker save` tarball, which has no multi-platform
|
|
170
|
+
# equivalent.
|
|
171
|
+
#
|
|
172
|
+
# publish-pypi.yml runs in parallel on this same tag push, not before this
|
|
173
|
+
# job: there is no cross-workflow `needs:`, so this job cannot wait on that
|
|
174
|
+
# workflow directly. Instead the wait-until-installable step below polls
|
|
175
|
+
# PyPI until the pinned versions this tag just published are actually
|
|
176
|
+
# installable, which is what orders this build after publish-pypi.yml
|
|
177
|
+
# completes without a cross-workflow dependency.
|
|
178
|
+
# -test tags publish to TestPyPI only (see publish-pypi.yml), so this job
|
|
179
|
+
# skips them: there is no real-PyPI installable version to build an image
|
|
180
|
+
# from for those.
|
|
168
181
|
publish:
|
|
169
|
-
if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref_name, '-test')
|
|
170
182
|
needs: [smoke-postgres, smoke-trino]
|
|
183
|
+
if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref_name, '-test')
|
|
171
184
|
strategy:
|
|
172
185
|
matrix:
|
|
173
186
|
engine: [postgres, trino]
|
|
@@ -176,8 +189,8 @@ jobs:
|
|
|
176
189
|
contents: read
|
|
177
190
|
packages: write
|
|
178
191
|
steps:
|
|
179
|
-
- uses: actions/checkout@
|
|
180
|
-
- uses: docker/setup-qemu-action@
|
|
192
|
+
- uses: actions/checkout@v7
|
|
193
|
+
- uses: docker/setup-qemu-action@v4
|
|
181
194
|
- uses: docker/setup-buildx-action@v4
|
|
182
195
|
- name: Log in to ghcr.io
|
|
183
196
|
uses: docker/login-action@v4
|
|
@@ -185,6 +198,26 @@ jobs:
|
|
|
185
198
|
registry: ghcr.io
|
|
186
199
|
username: ${{ github.actor }}
|
|
187
200
|
password: ${{ secrets.GITHUB_TOKEN }}
|
|
201
|
+
# The pinned distributions declare Requires-Python >= 3.14, so the
|
|
202
|
+
# availability probe must resolve them under a 3.14 interpreter — the
|
|
203
|
+
# runner's default python is older and pip would reject them even after
|
|
204
|
+
# they are published, spinning out every retry. (The image build itself
|
|
205
|
+
# installs inside python:3.14-slim, so it is unaffected; this is only for
|
|
206
|
+
# the host-side probe below.)
|
|
207
|
+
- uses: actions/setup-python@v5
|
|
208
|
+
with:
|
|
209
|
+
python-version: '3.14'
|
|
210
|
+
- name: Wait until the pinned versions are installable from PyPI
|
|
211
|
+
run: |
|
|
212
|
+
set -eu
|
|
213
|
+
req="image-requirements-${{ matrix.engine }}.txt"
|
|
214
|
+
for i in $(seq 1 30); do
|
|
215
|
+
if python -m pip download --dest /tmp/probe -r "$req" >/tmp/probe.log 2>&1; then
|
|
216
|
+
echo "installable"; exit 0
|
|
217
|
+
fi
|
|
218
|
+
echo "attempt $i: not yet on index; sleeping"; sleep 20
|
|
219
|
+
done
|
|
220
|
+
echo "pinned versions never became installable"; cat /tmp/probe.log; exit 1
|
|
188
221
|
- name: Build and push ${{ matrix.engine }} image
|
|
189
222
|
uses: docker/build-push-action@v7
|
|
190
223
|
with:
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
name: publish-pypi
|
|
2
|
+
|
|
3
|
+
# Publishes all four PyPI distributions this repo owns — continuo-python-runtime
|
|
4
|
+
# (the harness), continuo-engine-contract (the port, result-block format, and
|
|
5
|
+
# shared guards), and the two engine adapters (continuo-postgres-adapter,
|
|
6
|
+
# continuo-trino-adapter) — via PyPI Trusted Publishing (OIDC, no stored
|
|
7
|
+
# token). They publish together on a single v* tag, each at its own
|
|
8
|
+
# pyproject version, so a tag that only bumps the runtime still carries an
|
|
9
|
+
# unchanged adapter version along for the ride; skip-existing (below) makes
|
|
10
|
+
# that a no-op rather than a duplicate-upload failure. A release-time guard
|
|
11
|
+
# (scripts/check_version_bumps.py) refuses a tag that changed a package's
|
|
12
|
+
# source without bumping its version, so skip-existing can never silently
|
|
13
|
+
# ship stale adapter code under an unchanged version number.
|
|
14
|
+
#
|
|
15
|
+
# Tag glob note: `v*` is the repository's single release pattern — the same tag
|
|
16
|
+
# that images.yml builds and pushes both engine images from, so one tag ships
|
|
17
|
+
# the whole release. GitHub Actions tag globs anchor at character 1, so `v*`
|
|
18
|
+
# claims every tag beginning with "v"; no other pattern may be introduced.
|
|
19
|
+
# Tag `v<ver>-test<n>` publishes to TestPyPI; `v<ver>` publishes to real PyPI.
|
|
20
|
+
# The GitHub environment name is what the PyPI "pending publisher" is
|
|
21
|
+
# registered against — all four project names need one on each index.
|
|
22
|
+
#
|
|
23
|
+
# All four distributions are built into a single `dist/` and uploaded in one
|
|
24
|
+
# publish call, so there is no ordering constraint between them. The runtime
|
|
25
|
+
# wheel declares continuo-engine-contract as a dependency and resolves it from
|
|
26
|
+
# the index at install time ([tool.uv.sources] is dev-only and is not embedded
|
|
27
|
+
# in the wheel).
|
|
28
|
+
on:
|
|
29
|
+
push:
|
|
30
|
+
tags:
|
|
31
|
+
- "v*"
|
|
32
|
+
|
|
33
|
+
permissions: {}
|
|
34
|
+
|
|
35
|
+
jobs:
|
|
36
|
+
publish-packages:
|
|
37
|
+
if: startsWith(github.ref_name, 'v')
|
|
38
|
+
runs-on: ubuntu-latest
|
|
39
|
+
environment: ${{ contains(github.ref_name, '-test') && 'testpypi' || 'pypi' }}
|
|
40
|
+
permissions:
|
|
41
|
+
id-token: write # OIDC token for Trusted Publishing
|
|
42
|
+
contents: read # actions/checkout needs read access to the repo
|
|
43
|
+
steps:
|
|
44
|
+
- uses: actions/checkout@v7
|
|
45
|
+
with:
|
|
46
|
+
fetch-depth: 0
|
|
47
|
+
- uses: astral-sh/setup-uv@v7
|
|
48
|
+
- name: Refuse a tag that changed a package without bumping its version
|
|
49
|
+
run: python scripts/check_version_bumps.py
|
|
50
|
+
- name: Test before publishing
|
|
51
|
+
# Gate all four published projects, including both adapter suites — an
|
|
52
|
+
# adapter regression must block its own immutable PyPI upload, and
|
|
53
|
+
# images.yml runs in parallel so its smoke failure cannot. Each suite is
|
|
54
|
+
# a SEPARATE pytest invocation: every workspace member's tests/ is its
|
|
55
|
+
# own `tests` package (with __init__.py + conftest.py), so running two
|
|
56
|
+
# of them in one process collides on the `tests.conftest` module name
|
|
57
|
+
# (see the [tool.pytest.ini_options] note in pyproject.toml). `not image
|
|
58
|
+
# and not integration` deselects the tests needing a built engine image
|
|
59
|
+
# or a live warehouse (images.yml / the smoke jobs cover those). The
|
|
60
|
+
# step's default `set -e` fails the gate if any invocation fails.
|
|
61
|
+
run: |
|
|
62
|
+
uv sync --all-packages --all-groups
|
|
63
|
+
uv run pytest tests contract/tests -m "not image and not integration" -q
|
|
64
|
+
uv run pytest adapters/postgres/tests -m "not image and not integration" -q
|
|
65
|
+
uv run pytest adapters/trino/tests -m "not image and not integration" -q
|
|
66
|
+
- name: Build the contract sdist + wheel
|
|
67
|
+
run: uv build --package continuo-engine-contract -o dist
|
|
68
|
+
- name: Build the runtime sdist + wheel
|
|
69
|
+
run: uv build -o dist
|
|
70
|
+
- name: Build the postgres adapter sdist + wheel
|
|
71
|
+
run: uv build --package continuo-postgres-adapter -o dist
|
|
72
|
+
- name: Build the trino adapter sdist + wheel
|
|
73
|
+
run: uv build --package continuo-trino-adapter -o dist
|
|
74
|
+
# Adapters change rarely, so most v* tags carry an unchanged adapter
|
|
75
|
+
# version alongside a bumped runtime/contract version. Without
|
|
76
|
+
# skip-existing, re-uploading that unchanged version 400s and fails the
|
|
77
|
+
# whole publish. Trade-off: a changed package published without a
|
|
78
|
+
# version bump is then silently skipped too — the
|
|
79
|
+
# check_version_bumps.py guard above is what catches that case, before
|
|
80
|
+
# this job's build/publish steps ever run.
|
|
81
|
+
- name: Publish to TestPyPI
|
|
82
|
+
if: contains(github.ref_name, '-test')
|
|
83
|
+
# Pinned to a commit SHA. release/v1 is a moving branch, and this job
|
|
84
|
+
# holds id-token: write for PyPI Trusted Publishing — a compromised
|
|
85
|
+
# revision could mint a token and publish under this project's name.
|
|
86
|
+
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1
|
|
87
|
+
with:
|
|
88
|
+
repository-url: https://test.pypi.org/legacy/
|
|
89
|
+
packages-dir: dist
|
|
90
|
+
skip-existing: true
|
|
91
|
+
- name: Publish to PyPI
|
|
92
|
+
if: ${{ !contains(github.ref_name, '-test') }}
|
|
93
|
+
# Pinned to a commit SHA. release/v1 is a moving branch, and this job
|
|
94
|
+
# holds id-token: write for PyPI Trusted Publishing — a compromised
|
|
95
|
+
# revision could mint a token and publish under this project's name.
|
|
96
|
+
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1
|
|
97
|
+
with:
|
|
98
|
+
packages-dir: dist
|
|
99
|
+
skip-existing: true
|
{continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/.github/workflows/release.yml
RENAMED
|
@@ -53,7 +53,7 @@ jobs:
|
|
|
53
53
|
# other source of the repo's files. Its absence went unnoticed through
|
|
54
54
|
# review because this job only triggers on push:tags, never on
|
|
55
55
|
# pull_request, so no PR's CI ever actually executes it.
|
|
56
|
-
- uses: actions/checkout@
|
|
56
|
+
- uses: actions/checkout@v7
|
|
57
57
|
|
|
58
58
|
- name: Wait for publish-pypi.yml and images.yml to finish on this commit
|
|
59
59
|
run: |
|
{continuo_python_runtime-0.4.0 → continuo_python_runtime-0.4.1}/.github/workflows/security.yml
RENAMED
|
@@ -47,7 +47,7 @@ jobs:
|
|
|
47
47
|
# range (below), and this repository is small enough (a few hundred KB,
|
|
48
48
|
# well under a second to scan) that fetch-depth: 0 costs nothing on every
|
|
49
49
|
# trigger rather than only on the schedule.
|
|
50
|
-
- uses: actions/checkout@
|
|
50
|
+
- uses: actions/checkout@v7
|
|
51
51
|
with:
|
|
52
52
|
fetch-depth: 0
|
|
53
53
|
|
|
@@ -106,7 +106,7 @@ jobs:
|
|
|
106
106
|
runs-on: ubuntu-latest
|
|
107
107
|
timeout-minutes: 20
|
|
108
108
|
steps:
|
|
109
|
-
- uses: actions/checkout@
|
|
109
|
+
- uses: actions/checkout@v7
|
|
110
110
|
|
|
111
111
|
# Advisory: reports HIGH/CRITICAL and always exits 0. Base-image and
|
|
112
112
|
# transitive CVEs are often unfixable upstream, so gating on them would
|
|
@@ -57,8 +57,8 @@ uv run ruff check .
|
|
|
57
57
|
uv run ruff check contract
|
|
58
58
|
uv run mypy continuo_python_runtime
|
|
59
59
|
uv run mypy contract/continuo_engine_contract
|
|
60
|
-
uv run --package continuo-
|
|
61
|
-
uv run --package continuo-
|
|
60
|
+
uv run --package continuo-postgres-adapter mypy adapters/postgres/continuo_postgres_adapter
|
|
61
|
+
uv run --package continuo-trino-adapter mypy adapters/trino/continuo_trino_adapter
|
|
62
62
|
uv run pytest --cov=continuo_python_runtime -m "not image and not integration" -v
|
|
63
63
|
uv run pytest tests/test_csv_readers_integration.py tests/test_validation_runner.py -m integration -v
|
|
64
64
|
uv run pytest contract/tests -v
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
FROM python:3.14-slim
|
|
2
|
+
# One dual-role image per engine — the python-node runtime harness (default
|
|
3
|
+
# command `run`) and the blue/green validation runner (`validation-op`). It
|
|
4
|
+
# installs the PUBLISHED, versioned libraries, never the repo source:
|
|
5
|
+
# WHEEL_SOURCE=pypi (release) installs the pins from PyPI. PyPI versions
|
|
6
|
+
# are immutable and the image is consumed
|
|
7
|
+
# digest-pinned, so no hash lock is needed here.
|
|
8
|
+
# WHEEL_SOURCE=wheelhouse (CI/PR) installs the same pins from ./wheelhouse
|
|
9
|
+
# (built by CI) so an unreleased change is testable.
|
|
10
|
+
# The wheelhouse holds only this repo's own first-party wheels (built via
|
|
11
|
+
# `uv build --all-packages`); third-party dependencies always resolve from
|
|
12
|
+
# PyPI in both branches, so the wheelhouse branch never passes --no-index to
|
|
13
|
+
# the requirements install below.
|
|
14
|
+
# The pinned versions live in image-requirements-postgres.txt, kept equal to the
|
|
15
|
+
# repo's pyproject versions by tests/test_image_requirements_sync.py.
|
|
16
|
+
#
|
|
17
|
+
# The wheelhouse branch installs its three first-party wheels (contract,
|
|
18
|
+
# runtime, adapter) by exact local file first, with --no-index --no-deps: a
|
|
19
|
+
# plain `--find-links=/tmp/wheelhouse -r req.txt` is not enough, because pip
|
|
20
|
+
# does not prefer a find-links wheel over an index match at the same
|
|
21
|
+
# name+version, and continuo-python-runtime / continuo-engine-contract are
|
|
22
|
+
# already published on PyPI under the version this repo's HEAD currently
|
|
23
|
+
# carries (a routine dependency bump lands between releases without a version
|
|
24
|
+
# bump). Left unpinned-by-file, pip silently installs the last PyPI release's
|
|
25
|
+
# transitive pins instead of the wheel this build just produced, defeating
|
|
26
|
+
# the point of testing an unreleased change. Installing the exact local files
|
|
27
|
+
# first (no index contacted at all for this step) is unambiguous; the second
|
|
28
|
+
# install then only has PyPI-only third-party deps left to resolve, and finds
|
|
29
|
+
# the three first-party packages already satisfied.
|
|
30
|
+
ARG WHEEL_SOURCE=pypi
|
|
31
|
+
COPY image-requirements-postgres.txt /tmp/req.txt
|
|
32
|
+
# Optional COPY: the bracket glob matches ./wheelhouse when it exists (the CI/PR
|
|
33
|
+
# WHEEL_SOURCE=wheelhouse path builds it) and no-ops when it is absent, so a
|
|
34
|
+
# release build or a plain `docker build -f Dockerfile.postgres .` needs no
|
|
35
|
+
# pre-created directory. Only the wheelhouse branch below reads its contents.
|
|
36
|
+
COPY wheelhous[e] /tmp/wheelhouse
|
|
37
|
+
RUN set -eu; \
|
|
38
|
+
if [ "$WHEEL_SOURCE" = "wheelhouse" ]; then \
|
|
39
|
+
pip install --no-cache-dir --no-index --no-deps \
|
|
40
|
+
/tmp/wheelhouse/continuo_engine_contract-*.whl \
|
|
41
|
+
/tmp/wheelhouse/continuo_python_runtime-*.whl \
|
|
42
|
+
/tmp/wheelhouse/continuo_postgres_adapter-*.whl; \
|
|
43
|
+
pip install --no-cache-dir -r /tmp/req.txt; \
|
|
44
|
+
else \
|
|
45
|
+
pip install --no-cache-dir -r /tmp/req.txt; \
|
|
46
|
+
fi; \
|
|
47
|
+
rm -rf /tmp/req.txt /tmp/wheelhouse
|
|
48
|
+
# PYTHONPATH is belt-and-braces: the harness also inserts APP_ROOT and the
|
|
49
|
+
# node script's own directory at the front of sys.path before executing it.
|
|
50
|
+
ENV CONTRACT_DIR=/app/contracts APP_ROOT=/app PYTHONPATH=/app
|
|
51
|
+
WORKDIR /app
|
|
52
|
+
# uid 65532 matches continuo's executor securityContext expectation.
|
|
53
|
+
RUN useradd --uid 65532 --no-create-home --shell /usr/sbin/nologin nonroot
|
|
54
|
+
USER 65532:65532
|
|
55
|
+
ENTRYPOINT ["continuo-runtime"]
|
|
56
|
+
CMD ["run"]
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
FROM python:3.14-slim
|
|
2
|
+
# One dual-role image per engine — the python-node runtime harness (default
|
|
3
|
+
# command `run`) and the blue/green validation runner (`validation-op`). It
|
|
4
|
+
# installs the PUBLISHED, versioned libraries, never the repo source:
|
|
5
|
+
# WHEEL_SOURCE=pypi (release) installs the pins from PyPI. PyPI versions
|
|
6
|
+
# are immutable and the image is consumed
|
|
7
|
+
# digest-pinned, so no hash lock is needed here.
|
|
8
|
+
# WHEEL_SOURCE=wheelhouse (CI/PR) installs the same pins from ./wheelhouse
|
|
9
|
+
# (built by CI) so an unreleased change is testable.
|
|
10
|
+
# The wheelhouse holds only this repo's own first-party wheels (built via
|
|
11
|
+
# `uv build --all-packages`); third-party dependencies always resolve from
|
|
12
|
+
# PyPI in both branches, so the wheelhouse branch never passes --no-index to
|
|
13
|
+
# the requirements install below.
|
|
14
|
+
# The pinned versions live in image-requirements-trino.txt, kept equal to the
|
|
15
|
+
# repo's pyproject versions by tests/test_image_requirements_sync.py.
|
|
16
|
+
#
|
|
17
|
+
# The wheelhouse branch installs its three first-party wheels (contract,
|
|
18
|
+
# runtime, adapter) by exact local file first, with --no-index --no-deps: a
|
|
19
|
+
# plain `--find-links=/tmp/wheelhouse -r req.txt` is not enough, because pip
|
|
20
|
+
# does not prefer a find-links wheel over an index match at the same
|
|
21
|
+
# name+version, and continuo-python-runtime / continuo-engine-contract are
|
|
22
|
+
# already published on PyPI under the version this repo's HEAD currently
|
|
23
|
+
# carries (a routine dependency bump lands between releases without a version
|
|
24
|
+
# bump). Left unpinned-by-file, pip silently installs the last PyPI release's
|
|
25
|
+
# transitive pins instead of the wheel this build just produced, defeating
|
|
26
|
+
# the point of testing an unreleased change. Installing the exact local files
|
|
27
|
+
# first (no index contacted at all for this step) is unambiguous; the second
|
|
28
|
+
# install then only has PyPI-only third-party deps left to resolve, and finds
|
|
29
|
+
# the three first-party packages already satisfied.
|
|
30
|
+
ARG WHEEL_SOURCE=pypi
|
|
31
|
+
COPY image-requirements-trino.txt /tmp/req.txt
|
|
32
|
+
# Optional COPY: the bracket glob matches ./wheelhouse when it exists (the CI/PR
|
|
33
|
+
# WHEEL_SOURCE=wheelhouse path builds it) and no-ops when it is absent, so a
|
|
34
|
+
# release build or a plain `docker build -f Dockerfile.trino .` needs no
|
|
35
|
+
# pre-created directory. Only the wheelhouse branch below reads its contents.
|
|
36
|
+
COPY wheelhous[e] /tmp/wheelhouse
|
|
37
|
+
RUN set -eu; \
|
|
38
|
+
if [ "$WHEEL_SOURCE" = "wheelhouse" ]; then \
|
|
39
|
+
pip install --no-cache-dir --no-index --no-deps \
|
|
40
|
+
/tmp/wheelhouse/continuo_engine_contract-*.whl \
|
|
41
|
+
/tmp/wheelhouse/continuo_python_runtime-*.whl \
|
|
42
|
+
/tmp/wheelhouse/continuo_trino_adapter-*.whl; \
|
|
43
|
+
pip install --no-cache-dir -r /tmp/req.txt; \
|
|
44
|
+
else \
|
|
45
|
+
pip install --no-cache-dir -r /tmp/req.txt; \
|
|
46
|
+
fi; \
|
|
47
|
+
rm -rf /tmp/req.txt /tmp/wheelhouse
|
|
48
|
+
# PYTHONPATH is belt-and-braces: the harness also inserts APP_ROOT and the
|
|
49
|
+
# node script's own directory at the front of sys.path before executing it.
|
|
50
|
+
ENV CONTRACT_DIR=/app/contracts APP_ROOT=/app PYTHONPATH=/app
|
|
51
|
+
WORKDIR /app
|
|
52
|
+
# uid 65532 matches continuo's executor securityContext expectation.
|
|
53
|
+
RUN useradd --uid 65532 --no-create-home --shell /usr/sbin/nologin nonroot
|
|
54
|
+
USER 65532:65532
|
|
55
|
+
ENTRYPOINT ["continuo-runtime"]
|
|
56
|
+
CMD ["run"]
|
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: continuo-python-runtime
|
|
3
|
+
Version: 0.4.1
|
|
4
|
+
Summary: Runtime harness, contract tooling, and CI lint for Continuo python nodes.
|
|
5
|
+
Author: Simone Carolini
|
|
6
|
+
Maintainer: Simone Carolini
|
|
7
|
+
License-Expression: Apache-2.0
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
License-File: NOTICE
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
13
|
+
Requires-Python: >=3.14
|
|
14
|
+
Requires-Dist: boto3==1.43.74
|
|
15
|
+
Requires-Dist: continuo-engine-contract==0.7.3
|
|
16
|
+
Requires-Dist: pyarrow==25.0.1
|
|
17
|
+
Requires-Dist: pyyaml==6.0.3
|
|
18
|
+
Requires-Dist: sqlglot==30.17.0
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
|
|
1
21
|
# Continuo Python Runtime
|
|
2
22
|
|
|
3
23
|
[](https://github.com/carolsimone/continuo-python-runtime/actions/workflows/ci.yml)
|
|
@@ -12,7 +32,7 @@ and register the release with Continuo.
|
|
|
12
32
|
|
|
13
33
|
## What this repo is
|
|
14
34
|
|
|
15
|
-
|
|
35
|
+
Five artifacts come out of this repository:
|
|
16
36
|
|
|
17
37
|
- **The `continuo-python-runtime` PyPI package** — the `continuo-runtime` CLI
|
|
18
38
|
(`validate` / `merge` / `hash` / `lint` / `run` / `validation-op`) and the
|
|
@@ -21,6 +41,13 @@ Four artifacts come out of this repository:
|
|
|
21
41
|
- **The `continuo-engine-contract` PyPI package** — the `WarehouseAdapter`
|
|
22
42
|
port, the contract schema, the shared SQL/type/config guards, and the
|
|
23
43
|
sentinel result-block format. Adapter authors outside this repo pin it.
|
|
44
|
+
- **The two engine-adapter PyPI packages** (`continuo-postgres-adapter`,
|
|
45
|
+
`continuo-trino-adapter`) — one `WarehouseAdapter` implementation per
|
|
46
|
+
warehouse engine, each published independently under the same tag. A
|
|
47
|
+
domain repo normally never installs these directly (the engine image
|
|
48
|
+
already has the matching one baked in); they exist as standalone PyPI
|
|
49
|
+
packages for the "build your own container" shape (see below) and for
|
|
50
|
+
third-party adapter authors to reference.
|
|
24
51
|
- **Per-engine base images**, one per warehouse engine
|
|
25
52
|
(`continuo-python-runtime-postgres`, `continuo-python-runtime-trino`), that
|
|
26
53
|
domain repos build `FROM`. Each image bakes in the runtime and a single
|
|
@@ -30,10 +57,11 @@ Four artifacts come out of this repository:
|
|
|
30
57
|
- **`template/`** — a copy-ready domain repo: `Dockerfile`, `contracts/`,
|
|
31
58
|
`scripts/`, and the `release.yml` CI/CD workflow.
|
|
32
59
|
|
|
33
|
-
One `vX.Y.Z` git tag releases all of it: `publish-pypi.yml` builds
|
|
34
|
-
distributions into a single `dist/` and publishes them together, and
|
|
35
|
-
`images.yml` builds and pushes both engine images
|
|
36
|
-
|
|
60
|
+
One `vX.Y.Z` git tag releases all of it: `publish-pypi.yml` builds all four
|
|
61
|
+
PyPI distributions into a single `dist/` and publishes them together, and
|
|
62
|
+
`images.yml` builds and pushes both engine images — each installing its
|
|
63
|
+
matching pinned adapter version from that same release — multi-arch under
|
|
64
|
+
the same tag.
|
|
37
65
|
|
|
38
66
|
### What this repo owns
|
|
39
67
|
|
|
@@ -50,22 +78,27 @@ validation-side port, adapter class, entry-point group, or image. One
|
|
|
50
78
|
| --- | --- | --- | --- |
|
|
51
79
|
| `continuo-python-runtime` | `continuo_python_runtime` | this repo (root) | Harness (CLI, `conform()`, `RunContext`, error taxonomy) **and** the validation runner (`continuo-runtime validation-op`). Published to PyPI. |
|
|
52
80
|
| `continuo-engine-contract` | `continuo_engine_contract` | this repo, `contract/` | The `WarehouseAdapter` port, contract schema, the SQL/type/config guards adapters must run, and the result-block format. Published to PyPI. |
|
|
53
|
-
| `continuo-
|
|
54
|
-
| `continuo-
|
|
81
|
+
| `continuo-postgres-adapter` | `continuo_postgres_adapter` | this repo, `adapters/postgres/` | `PostgresAdapter` — one class, both roles. Published to PyPI. |
|
|
82
|
+
| `continuo-trino-adapter` | `continuo_trino_adapter` | this repo, `adapters/trino/` | `TrinoAdapter` — one class, both roles, for Trino/Iceberg. Published to PyPI. |
|
|
55
83
|
|
|
56
84
|
All four are uv workspace members (`[tool.uv.workspace]` in the root
|
|
57
85
|
`pyproject.toml`), so `uv sync --all-packages --all-groups` at the repo root
|
|
58
86
|
installs everything for local development.
|
|
59
87
|
|
|
60
|
-
**
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
88
|
+
**All four packages in the table above are published to PyPI**, under the
|
|
89
|
+
same `vX.Y.Z` tag. The two engine images then **install the matching pinned
|
|
90
|
+
adapter version from PyPI** — `Dockerfile.postgres` installs
|
|
91
|
+
`continuo-postgres-adapter==X.Y.Z`, `Dockerfile.trino` installs
|
|
92
|
+
`continuo-trino-adapter==X.Y.Z` — rather than building it from this repo's
|
|
93
|
+
source tree, so each image still ships exactly one adapter and the runtime
|
|
94
|
+
still discovers it through the `continuo_engine.adapters` entry-point group
|
|
95
|
+
at run time. The image **name** (`continuo-python-runtime-<engine>`) and the
|
|
96
|
+
adapter's pip **distribution** name (`continuo-<engine>-adapter`) are two
|
|
97
|
+
different artifacts of the same adapter — same engine, same version, same
|
|
98
|
+
runtime behavior, different packaging; see "Build your own container" below
|
|
99
|
+
for a build shape that installs the pip package directly instead of `FROM`
|
|
100
|
+
the image. All four packages are still built, type-checked, and tested by CI
|
|
101
|
+
on every change.
|
|
69
102
|
|
|
70
103
|
### The result block is a frozen wire contract
|
|
71
104
|
|
|
@@ -242,26 +275,46 @@ A domain repo picks its warehouse engine by which base image it builds
|
|
|
242
275
|
`FROM`:
|
|
243
276
|
|
|
244
277
|
```dockerfile
|
|
245
|
-
FROM ghcr.io/carolsimone/continuo-python-runtime-postgres:v0.4.
|
|
278
|
+
FROM ghcr.io/carolsimone/continuo-python-runtime-postgres:v0.4.1
|
|
246
279
|
# or
|
|
247
|
-
FROM ghcr.io/carolsimone/continuo-python-runtime-trino:v0.4.
|
|
280
|
+
FROM ghcr.io/carolsimone/continuo-python-runtime-trino:v0.4.1
|
|
248
281
|
```
|
|
249
282
|
|
|
250
283
|
The engine is part of the image **name**; the tag is the bare version, so
|
|
251
284
|
Continuo's Helm chart can pin an image as `<name>:vX.Y.Z@sha256:<digest>`.
|
|
252
285
|
|
|
253
|
-
Each image bakes in exactly one `WarehouseAdapter` for that engine —
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
`
|
|
258
|
-
|
|
259
|
-
|
|
286
|
+
Each image bakes in exactly one `WarehouseAdapter` for that engine — the
|
|
287
|
+
pinned PyPI version of the `continuo-postgres-adapter` or
|
|
288
|
+
`continuo-trino-adapter` package built from this repo's `adapters/postgres/`
|
|
289
|
+
or `adapters/trino/` source (see the table above) — registered under the
|
|
290
|
+
`continuo_engine.adapters` entry-point group (entry names `postgres` /
|
|
291
|
+
`trino`). The runtime discovers it via `discover_adapter()` at run time, so a
|
|
292
|
+
single image serves every node in the service and the release-time
|
|
293
|
+
validation Job for it. The executor injects the warehouse connection as
|
|
294
|
+
environment variables (engine-native, e.g.
|
|
260
295
|
`POSTGRES_HOST`/`POSTGRES_DB`/`POSTGRES_USER`) plus the node-selection
|
|
261
296
|
environment (`NODE_ID`, `TABLE_NAME`, `TARGET_SCHEMA`, and optionally
|
|
262
297
|
`CONTRACT_DIR`/`APP_ROOT`) that `continuo-runtime run` reads to dispatch the
|
|
263
298
|
right node's script.
|
|
264
299
|
|
|
300
|
+
### Build your own container
|
|
301
|
+
|
|
302
|
+
A domain repo does not have to build `FROM` the published engine image.
|
|
303
|
+
`template/` ships two Dockerfiles for the two build shapes (see
|
|
304
|
+
`template/README.md` § "Choosing a base" for the full comparison):
|
|
305
|
+
|
|
306
|
+
- **Shape 1 — `template/Dockerfile`** — `FROM` the published engine image
|
|
307
|
+
(`continuo-python-runtime-<engine>`), as shown above. Simplest; the image
|
|
308
|
+
already has the runtime and adapter installed and pinned.
|
|
309
|
+
- **Shape 2 — `template/Dockerfile.pip`** — your own base image, installing
|
|
310
|
+
`continuo-python-runtime` and one `continuo-<engine>-adapter` from PyPI
|
|
311
|
+
via a hash-locked `requirements.lock` (`template/requirements.lock`). Use
|
|
312
|
+
this when you must control the base image yourself.
|
|
313
|
+
|
|
314
|
+
Both shapes end up running the same runtime and the same adapter version;
|
|
315
|
+
which one you pick only changes who controls the base OS layer underneath
|
|
316
|
+
them.
|
|
317
|
+
|
|
265
318
|
## Further reading
|
|
266
319
|
|
|
267
320
|
- `docs/superpowers/specs/2026-07-31-python-runtime-design.md` — this
|