terrine 0.1.0.dev0__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.
- terrine-0.1.0.dev0/.github/CLA.md +154 -0
- terrine-0.1.0.dev0/.github/workflows/ci.yml +188 -0
- terrine-0.1.0.dev0/.github/workflows/cla.yml +61 -0
- terrine-0.1.0.dev0/.github/workflows/release.yml +173 -0
- terrine-0.1.0.dev0/.github/workflows/scale.yml +32 -0
- terrine-0.1.0.dev0/.github/workflows/warehouse-backends.yml +127 -0
- terrine-0.1.0.dev0/.gitignore +20 -0
- terrine-0.1.0.dev0/.kata.toml +4 -0
- terrine-0.1.0.dev0/.pre-commit-config.yaml +14 -0
- terrine-0.1.0.dev0/.python-version +1 -0
- terrine-0.1.0.dev0/.roborev.toml +11 -0
- terrine-0.1.0.dev0/AGENTS.md +271 -0
- terrine-0.1.0.dev0/CHANGELOG.md +300 -0
- terrine-0.1.0.dev0/CLAUDE.md +1 -0
- terrine-0.1.0.dev0/CONTRIBUTING.md +70 -0
- terrine-0.1.0.dev0/LICENSE +202 -0
- terrine-0.1.0.dev0/Makefile +66 -0
- terrine-0.1.0.dev0/NOTICE +4 -0
- terrine-0.1.0.dev0/PKG-INFO +164 -0
- terrine-0.1.0.dev0/README.md +107 -0
- terrine-0.1.0.dev0/THIRD_PARTY_NOTICES.txt +219 -0
- terrine-0.1.0.dev0/benchmarks/README.md +238 -0
- terrine-0.1.0.dev0/benchmarks/report.py +51 -0
- terrine-0.1.0.dev0/benchmarks/results/duckdb-scale-v2-small.json +1 -0
- terrine-0.1.0.dev0/benchmarks/run_duckdb.py +288 -0
- terrine-0.1.0.dev0/benchmarks/run_live.py +361 -0
- terrine-0.1.0.dev0/benchmarks/run_overhead.py +494 -0
- terrine-0.1.0.dev0/benchmarks/workloads/small.json +10 -0
- terrine-0.1.0.dev0/benchmarks/workloads.py +338 -0
- terrine-0.1.0.dev0/docs/guides/backend-compatibility.md +407 -0
- terrine-0.1.0.dev0/docs/guides/candidate-anchors.md +26 -0
- terrine-0.1.0.dev0/docs/guides/capabilities.md +51 -0
- terrine-0.1.0.dev0/docs/guides/common-feature-patterns.md +174 -0
- terrine-0.1.0.dev0/docs/guides/common-stack-interop.md +143 -0
- terrine-0.1.0.dev0/docs/guides/cost-and-residency.md +68 -0
- terrine-0.1.0.dev0/docs/guides/dataset-agent-tools.md +187 -0
- terrine-0.1.0.dev0/docs/guides/design-specs.md +95 -0
- terrine-0.1.0.dev0/docs/guides/design-validation.md +35 -0
- terrine-0.1.0.dev0/docs/guides/first-dataset.md +123 -0
- terrine-0.1.0.dev0/docs/guides/increment-compatibility.md +41 -0
- terrine-0.1.0.dev0/docs/guides/index.md +50 -0
- terrine-0.1.0.dev0/docs/guides/library-handoffs.md +247 -0
- terrine-0.1.0.dev0/docs/guides/limitations.md +65 -0
- terrine-0.1.0.dev0/docs/guides/materialization-runtime.md +295 -0
- terrine-0.1.0.dev0/docs/guides/ml-staging.md +206 -0
- terrine-0.1.0.dev0/docs/guides/orchestrators.md +161 -0
- terrine-0.1.0.dev0/docs/guides/public-api.md +120 -0
- terrine-0.1.0.dev0/docs/guides/semantic-layer-interop.md +30 -0
- terrine-0.1.0.dev0/docs/guides/sequential-panels.md +127 -0
- terrine-0.1.0.dev0/docs/guides/shared-dataset-contract.md +108 -0
- terrine-0.1.0.dev0/docs/guides/state-panels.md +100 -0
- terrine-0.1.0.dev0/docs/guides/synthetic-worlds.md +70 -0
- terrine-0.1.0.dev0/docs/guides/temporal-attributes.md +63 -0
- terrine-0.1.0.dev0/docs/guides/temporal-engine.md +708 -0
- terrine-0.1.0.dev0/docs/guides/trajectories-survival.md +185 -0
- terrine-0.1.0.dev0/docs/index.md +30 -0
- terrine-0.1.0.dev0/docs/reference/refusals.md +498 -0
- terrine-0.1.0.dev0/docs/research/edge-case-designs.md +60 -0
- terrine-0.1.0.dev0/docs/research/landscape.md +133 -0
- terrine-0.1.0.dev0/docs/research/ohdsi-study-design.md +109 -0
- terrine-0.1.0.dev0/docs/research/point-in-time-feature-apis.md +80 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/2026-10-16-terrine-build.md +416 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/2026-10-16-terrine-dataset-workflows.md +164 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/2026-10-16-terrine-study-api.md +312 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/2026-10-16-terrine-temporal.md +345 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/2026-10-17-terrine-frame.md +182 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/2026-10-18-terrine-event-sequences.md +200 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/2026-10-18-terrine-materialization-runtime.md +267 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/2026-10-18-terrine-ml-staging.md +201 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/2026-10-18-terrine-orchestrators.md +131 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/2026-10-18-terrine-sequential-panels.md +183 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/2026-10-18-terrine-trajectories-survival.md +269 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/2026-10-18-terrine-warehouse-scale.md +163 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/2026-10-19-terrine-agent-tools.md +181 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/2026-10-19-terrine-fast-tests-inventory.md +478 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/2026-10-19-terrine-fast-tests-ledger.md +561 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/2026-10-19-terrine-fast-tests.md +145 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/2026-10-19-terrine-interop.md +202 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/2026-10-19-terrine-library-handoffs.md +81 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/2026-10-19-terrine-release-readiness.md +100 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/2026-10-20-terrine-test-tiers.md +113 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/2026-10-21-terrine-postgres-execution.md +170 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/2026-10-22-bigquery-execution.md +66 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/2026-10-22-ibis-study-queries.md +73 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/2026-10-22-postgres-float-windows.md +56 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/2026-10-23-exact-float-windows.md +88 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/2026-10-23-snowflake-execution.md +323 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/2026-10-24-mutation-audit.md +80 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/2026-10-24-test-suite-speed.md +68 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/2026-10-26-public-readiness.md +255 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/2026-10-26-table-first-binding-and-recipes.md +184 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/ledger-compile.md +345 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/ledger-dataset.md +136 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/ledger-runtime.md +180 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/ledger-test-tiers-misc.md +14 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/ledger-test-tiers-state-panels.md +37 -0
- terrine-0.1.0.dev0/docs/superpowers/plans/ledger-test-tiers-temporal.md +29 -0
- terrine-0.1.0.dev0/docs/superpowers/specs/2026-10-16-terrine-handoff.md +635 -0
- terrine-0.1.0.dev0/docs/superpowers/specs/2026-10-17-terrine-frame-design.md +135 -0
- terrine-0.1.0.dev0/docs/superpowers/specs/2026-10-18-terrine-scope-datasets-only.md +76 -0
- terrine-0.1.0.dev0/docs/superpowers/specs/2026-10-26-table-first-binding-and-recipes-design.md +146 -0
- terrine-0.1.0.dev0/evals/agent_dataset_tools.yaml +84 -0
- terrine-0.1.0.dev0/examples/batch_scoring.py +68 -0
- terrine-0.1.0.dev0/examples/bigquery/dataset.py +106 -0
- terrine-0.1.0.dev0/examples/common_stack_interop.py +115 -0
- terrine-0.1.0.dev0/examples/dataset_agent_tools.py +130 -0
- terrine-0.1.0.dev0/examples/event_sequences.py +190 -0
- terrine-0.1.0.dev0/examples/first_dataset.py +14 -0
- terrine-0.1.0.dev0/examples/increment_parity.py +237 -0
- terrine-0.1.0.dev0/examples/materialization_runtime.py +256 -0
- terrine-0.1.0.dev0/examples/ml_staging.py +174 -0
- terrine-0.1.0.dev0/examples/nonadditive_metrics.py +87 -0
- terrine-0.1.0.dev0/examples/orchestrators/airflow_materialization.py +43 -0
- terrine-0.1.0.dev0/examples/orchestrators/dagster_materialization.py +34 -0
- terrine-0.1.0.dev0/examples/orchestrators/dbt_core_after_build.py +85 -0
- terrine-0.1.0.dev0/examples/postgres/dataset.py +105 -0
- terrine-0.1.0.dev0/examples/retention_and_winsorization.py +82 -0
- terrine-0.1.0.dev0/examples/retention_metrics.py +100 -0
- terrine-0.1.0.dev0/examples/sequential_trials.py +133 -0
- terrine-0.1.0.dev0/examples/snowflake/dataset.py +149 -0
- terrine-0.1.0.dev0/examples/state_panel.py +190 -0
- terrine-0.1.0.dev0/examples/table_first_dataset.py +126 -0
- terrine-0.1.0.dev0/examples/trajectories_survival.py +180 -0
- terrine-0.1.0.dev0/integration/.test_durations +259 -0
- terrine-0.1.0.dev0/integration/agent/test_dataset_tool_example.py +27 -0
- terrine-0.1.0.dev0/integration/agent/test_dataset_tool_flow.py +80 -0
- terrine-0.1.0.dev0/integration/agent/test_dataset_tool_runtime.py +822 -0
- terrine-0.1.0.dev0/integration/backends/test_numeric.py +62 -0
- terrine-0.1.0.dev0/integration/compat/test_native_catalog.py +110 -0
- terrine-0.1.0.dev0/integration/compile/test_boolean_outputs.py +275 -0
- terrine-0.1.0.dev0/integration/compile/test_column_runtime_contracts.py +256 -0
- terrine-0.1.0.dev0/integration/compile/test_frame_runtime_window_export.py +34 -0
- terrine-0.1.0.dev0/integration/compile/test_ltv.py +148 -0
- terrine-0.1.0.dev0/integration/compile/test_retention.py +34 -0
- terrine-0.1.0.dev0/integration/compile/test_time_to_event.py +504 -0
- terrine-0.1.0.dev0/integration/conftest.py +1 -0
- terrine-0.1.0.dev0/integration/handoffs/__init__.py +0 -0
- terrine-0.1.0.dev0/integration/handoffs/conftest.py +53 -0
- terrine-0.1.0.dev0/integration/handoffs/test_diff_diff.py +53 -0
- terrine-0.1.0.dev0/integration/handoffs/test_library_handoffs.py +85 -0
- terrine-0.1.0.dev0/integration/handoffs/test_lifelines.py +88 -0
- terrine-0.1.0.dev0/integration/parity/test_increment_panel_parity.py +56 -0
- terrine-0.1.0.dev0/integration/state_panels/test_state_panel_workflows.py +398 -0
- terrine-0.1.0.dev0/integration/temporal/test_retention_bands.py +158 -0
- terrine-0.1.0.dev0/integration/temporal/test_window_quotient_composition.py +293 -0
- terrine-0.1.0.dev0/integration/test_independence.py +32 -0
- terrine-0.1.0.dev0/integration/test_model_from_tables.py +177 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/bigquery_fixtures.py +80 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/postgres_fixtures.py +68 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/snowflake_fixtures.py +121 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_backend_capabilities.py +536 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_bigquery_admission.py +141 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_bigquery_execution.py +28 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_bigquery_parity.py +277 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_duckdb_compiler_scale.py +67 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_duckdb_runtime_recovery.py +83 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_duckdb_scale.py +34 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_incremental_equivalence.py +955 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_live_warehouse_scale.py +34 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_materialization_example.py +32 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_ml_staging_duckdb.py +1897 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_ml_staging_examples.py +62 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_orchestrator_adapters.py +883 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_planning.py +131 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_postgres_admission.py +252 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_postgres_execution.py +86 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_postgres_shapes.py +249 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_postgres_timestamps.py +108 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_postgres_windows.py +336 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_request_replay_process.py +151 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_runtime_api.py +571 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_runtime_cli.py +70 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_runtime_control.py +63 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_runtime_cost_budget.py +83 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_saved_plan_restart.py +664 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_snapshot_capture_bounds.py +102 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_snapshot_partition_consistency.py +235 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_snowflake_admission.py +342 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_snowflake_execution.py +34 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_snowflake_parity.py +672 -0
- terrine-0.1.0.dev0/integration/warehouse_execution/test_winsorization_definition.py +120 -0
- terrine-0.1.0.dev0/mkdocs.yml +32 -0
- terrine-0.1.0.dev0/pyproject.toml +126 -0
- terrine-0.1.0.dev0/scripts/mutate.py +218 -0
- terrine-0.1.0.dev0/tach.toml +109 -0
- terrine-0.1.0.dev0/terrine/__init__.py +120 -0
- terrine-0.1.0.dev0/terrine/_time.py +21 -0
- terrine-0.1.0.dev0/terrine/adapters/__init__.py +3 -0
- terrine-0.1.0.dev0/terrine/adapters/increment.py +365 -0
- terrine-0.1.0.dev0/terrine/adapters/opentelemetry.py +63 -0
- terrine-0.1.0.dev0/terrine/agent/__init__.py +6 -0
- terrine-0.1.0.dev0/terrine/agent/definitions.py +143 -0
- terrine-0.1.0.dev0/terrine/agent/design_schema.py +220 -0
- terrine-0.1.0.dev0/terrine/agent/policy.py +144 -0
- terrine-0.1.0.dev0/terrine/agent/schemas.py +285 -0
- terrine-0.1.0.dev0/terrine/agent/tools.py +956 -0
- terrine-0.1.0.dev0/terrine/backends/__init__.py +3 -0
- terrine-0.1.0.dev0/terrine/backends/capabilities.py +117 -0
- terrine-0.1.0.dev0/terrine/backends/dialect.py +55 -0
- terrine-0.1.0.dev0/terrine/backends/extrema.py +40 -0
- terrine-0.1.0.dev0/terrine/backends/joins.py +75 -0
- terrine-0.1.0.dev0/terrine/backends/numeric.py +657 -0
- terrine-0.1.0.dev0/terrine/backends/sequences.py +40 -0
- terrine-0.1.0.dev0/terrine/backends/timestamps.py +421 -0
- terrine-0.1.0.dev0/terrine/compile/__init__.py +3 -0
- terrine-0.1.0.dev0/terrine/compile/_asof.py +165 -0
- terrine-0.1.0.dev0/terrine/compile/_predicates.py +110 -0
- terrine-0.1.0.dev0/terrine/compile/anchors.py +492 -0
- terrine-0.1.0.dev0/terrine/compile/columns.py +1353 -0
- terrine-0.1.0.dev0/terrine/compile/cost.py +110 -0
- terrine-0.1.0.dev0/terrine/compile/dispatch.py +148 -0
- terrine-0.1.0.dev0/terrine/compile/layers.py +242 -0
- terrine-0.1.0.dev0/terrine/compile/materialize.py +91 -0
- terrine-0.1.0.dev0/terrine/compile/provenance.py +120 -0
- terrine-0.1.0.dev0/terrine/compile/ranges.py +91 -0
- terrine-0.1.0.dev0/terrine/compile/retention.py +127 -0
- terrine-0.1.0.dev0/terrine/compile/shapes/__init__.py +3 -0
- terrine-0.1.0.dev0/terrine/compile/shapes/_observations.py +502 -0
- terrine-0.1.0.dev0/terrine/compile/shapes/calendar_comparison.py +370 -0
- terrine-0.1.0.dev0/terrine/compile/shapes/cohorts.py +285 -0
- terrine-0.1.0.dev0/terrine/compile/shapes/event_panel.py +46 -0
- terrine-0.1.0.dev0/terrine/compile/shapes/event_sequence.py +498 -0
- terrine-0.1.0.dev0/terrine/compile/shapes/life_table.py +244 -0
- terrine-0.1.0.dev0/terrine/compile/shapes/ltv.py +287 -0
- terrine-0.1.0.dev0/terrine/compile/shapes/matched_t0.py +75 -0
- terrine-0.1.0.dev0/terrine/compile/shapes/sequential.py +320 -0
- terrine-0.1.0.dev0/terrine/compile/shapes/state_panel.py +460 -0
- terrine-0.1.0.dev0/terrine/compile/shapes/time_to_event.py +521 -0
- terrine-0.1.0.dev0/terrine/data.py +1311 -0
- terrine-0.1.0.dev0/terrine/dataset/__init__.py +5 -0
- terrine-0.1.0.dev0/terrine/dataset/export.py +463 -0
- terrine-0.1.0.dev0/terrine/dataset/manifest.py +254 -0
- terrine-0.1.0.dev0/terrine/dataset/reference.py +582 -0
- terrine-0.1.0.dev0/terrine/dataset/splits.py +373 -0
- terrine-0.1.0.dev0/terrine/dataset/training.py +114 -0
- terrine-0.1.0.dev0/terrine/dataset/transforms.py +182 -0
- terrine-0.1.0.dev0/terrine/errors.py +98 -0
- terrine-0.1.0.dev0/terrine/execution/__init__.py +5 -0
- terrine-0.1.0.dev0/terrine/execution/_bigquery.py +318 -0
- terrine-0.1.0.dev0/terrine/execution/_metadata.py +47 -0
- terrine-0.1.0.dev0/terrine/execution/_native.py +574 -0
- terrine-0.1.0.dev0/terrine/execution/_postgres.py +468 -0
- terrine-0.1.0.dev0/terrine/execution/_publish.py +299 -0
- terrine-0.1.0.dev0/terrine/execution/_snowflake.py +684 -0
- terrine-0.1.0.dev0/terrine/execution/backend.py +349 -0
- terrine-0.1.0.dev0/terrine/execution/gates.py +90 -0
- terrine-0.1.0.dev0/terrine/execution/inputs.py +923 -0
- terrine-0.1.0.dev0/terrine/export/__init__.py +31 -0
- terrine-0.1.0.dev0/terrine/export/diff_diff.py +177 -0
- terrine-0.1.0.dev0/terrine/export/lifelines.py +219 -0
- terrine-0.1.0.dev0/terrine/export/preflight.py +243 -0
- terrine-0.1.0.dev0/terrine/export/surrogate.py +168 -0
- terrine-0.1.0.dev0/terrine/frame.py +1042 -0
- terrine-0.1.0.dev0/terrine/model.py +397 -0
- terrine-0.1.0.dev0/terrine/orchestration/__init__.py +3 -0
- terrine-0.1.0.dev0/terrine/orchestration/airflow.py +115 -0
- terrine-0.1.0.dev0/terrine/orchestration/dagster.py +103 -0
- terrine-0.1.0.dev0/terrine/py.typed +0 -0
- terrine-0.1.0.dev0/terrine/recipes.py +295 -0
- terrine-0.1.0.dev0/terrine/runtime/__init__.py +70 -0
- terrine-0.1.0.dev0/terrine/runtime/api.py +803 -0
- terrine-0.1.0.dev0/terrine/runtime/arrow.py +98 -0
- terrine-0.1.0.dev0/terrine/runtime/backends/base.py +70 -0
- terrine-0.1.0.dev0/terrine/runtime/backends/duckdb.py +645 -0
- terrine-0.1.0.dev0/terrine/runtime/changes.py +71 -0
- terrine-0.1.0.dev0/terrine/runtime/cli.py +108 -0
- terrine-0.1.0.dev0/terrine/runtime/control.py +355 -0
- terrine-0.1.0.dev0/terrine/runtime/cost.py +211 -0
- terrine-0.1.0.dev0/terrine/runtime/events.py +194 -0
- terrine-0.1.0.dev0/terrine/runtime/execute.py +932 -0
- terrine-0.1.0.dev0/terrine/runtime/gc.py +43 -0
- terrine-0.1.0.dev0/terrine/runtime/graph.py +200 -0
- terrine-0.1.0.dev0/terrine/runtime/layers.py +61 -0
- terrine-0.1.0.dev0/terrine/runtime/leases.py +165 -0
- terrine-0.1.0.dev0/terrine/runtime/materialize.py +53 -0
- terrine-0.1.0.dev0/terrine/runtime/owner.py +57 -0
- terrine-0.1.0.dev0/terrine/runtime/planner.py +441 -0
- terrine-0.1.0.dev0/terrine/runtime/planning.py +394 -0
- terrine-0.1.0.dev0/terrine/runtime/saved_plan.py +337 -0
- terrine-0.1.0.dev0/terrine/runtime/snapshot.py +541 -0
- terrine-0.1.0.dev0/terrine/runtime/state.py +585 -0
- terrine-0.1.0.dev0/terrine/runtime/status.py +360 -0
- terrine-0.1.0.dev0/terrine/runtime/synchronization.py +15 -0
- terrine-0.1.0.dev0/terrine/semantic/__init__.py +3 -0
- terrine-0.1.0.dev0/terrine/semantic/bind.py +309 -0
- terrine-0.1.0.dev0/terrine/semantic/io.py +116 -0
- terrine-0.1.0.dev0/terrine/semantic/models.py +342 -0
- terrine-0.1.0.dev0/terrine/semantic/rules.py +113 -0
- terrine-0.1.0.dev0/terrine/semantic/sql.py +185 -0
- terrine-0.1.0.dev0/terrine/semantic/time.py +42 -0
- terrine-0.1.0.dev0/terrine/simulate/__init__.py +24 -0
- terrine-0.1.0.dev0/terrine/simulate/baseline.yaml +57 -0
- terrine-0.1.0.dev0/terrine/simulate/generate.py +182 -0
- terrine-0.1.0.dev0/terrine/simulate/scale.py +234 -0
- terrine-0.1.0.dev0/terrine/simulate/world.py +75 -0
- terrine-0.1.0.dev0/terrine/spec/__init__.py +96 -0
- terrine-0.1.0.dev0/terrine/spec/anchors.py +107 -0
- terrine-0.1.0.dev0/terrine/spec/dataset.py +260 -0
- terrine-0.1.0.dev0/terrine/spec/design.py +361 -0
- terrine-0.1.0.dev0/terrine/spec/expressions.py +440 -0
- terrine-0.1.0.dev0/terrine/spec/io.py +829 -0
- terrine-0.1.0.dev0/terrine/spec/panels.py +359 -0
- terrine-0.1.0.dev0/terrine/spec/sequence.py +165 -0
- terrine-0.1.0.dev0/terrine/spec/state_panel.py +246 -0
- terrine-0.1.0.dev0/terrine/spec/trajectory.py +144 -0
- terrine-0.1.0.dev0/terrine/spec/transforms.py +260 -0
- terrine-0.1.0.dev0/terrine/spec/validate.py +758 -0
- terrine-0.1.0.dev0/terrine/temporal/__init__.py +3 -0
- terrine-0.1.0.dev0/terrine/temporal/aggregate.py +688 -0
- terrine-0.1.0.dev0/terrine/temporal/attributes.py +389 -0
- terrine-0.1.0.dev0/terrine/temporal/daily.py +481 -0
- terrine-0.1.0.dev0/terrine/temporal/first.py +239 -0
- terrine-0.1.0.dev0/terrine/temporal/lookup.py +194 -0
- terrine-0.1.0.dev0/terrine/temporal/nonadditive.py +466 -0
- terrine-0.1.0.dev0/terrine/temporal/prefix.py +104 -0
- terrine-0.1.0.dev0/terrine/temporal/ranges.py +122 -0
- terrine-0.1.0.dev0/terrine/temporal/readiness.py +41 -0
- terrine-0.1.0.dev0/terrine/temporal/retention.py +225 -0
- terrine-0.1.0.dev0/terrine/temporal/sequence.py +900 -0
- terrine-0.1.0.dev0/terrine/temporal/sessionize.py +135 -0
- terrine-0.1.0.dev0/terrine/temporal/sketches.py +329 -0
- terrine-0.1.0.dev0/terrine/windows.py +54 -0
- terrine-0.1.0.dev0/tests/.test_durations +1229 -0
- terrine-0.1.0.dev0/tests/__init__.py +0 -0
- terrine-0.1.0.dev0/tests/_timing.py +3 -0
- terrine-0.1.0.dev0/tests/_worlds.py +126 -0
- terrine-0.1.0.dev0/tests/adapters/test_airflow.py +238 -0
- terrine-0.1.0.dev0/tests/adapters/test_dagster.py +199 -0
- terrine-0.1.0.dev0/tests/adapters/test_dbt_core_after_build.py +240 -0
- terrine-0.1.0.dev0/tests/agent/conftest.py +76 -0
- terrine-0.1.0.dev0/tests/agent/fixtures/catalog.yaml +19 -0
- terrine-0.1.0.dev0/tests/agent/test_inspect_design.py +271 -0
- terrine-0.1.0.dev0/tests/agent/test_materialize.py +135 -0
- terrine-0.1.0.dev0/tests/agent/test_plan_authorization.py +191 -0
- terrine-0.1.0.dev0/tests/agent/test_policy.py +71 -0
- terrine-0.1.0.dev0/tests/agent/test_requests.py +61 -0
- terrine-0.1.0.dev0/tests/agent/test_schemas.py +159 -0
- terrine-0.1.0.dev0/tests/backends/__init__.py +0 -0
- terrine-0.1.0.dev0/tests/backends/test_numeric.py +318 -0
- terrine-0.1.0.dev0/tests/backends/test_sequences.py +14 -0
- terrine-0.1.0.dev0/tests/backends/test_timestamps.py +62 -0
- terrine-0.1.0.dev0/tests/compat/__init__.py +0 -0
- terrine-0.1.0.dev0/tests/compat/fixtures/catalog.yaml +103 -0
- terrine-0.1.0.dev0/tests/compat/fixtures/increment.yaml +109 -0
- terrine-0.1.0.dev0/tests/compat/fixtures/same-name-collision.yaml +19 -0
- terrine-0.1.0.dev0/tests/compat/fixtures/unsupported-metric.yaml +13 -0
- terrine-0.1.0.dev0/tests/compat/test_increment_semantics.py +148 -0
- terrine-0.1.0.dev0/tests/compat/test_semantic_interop.py +28 -0
- terrine-0.1.0.dev0/tests/compile/__init__.py +0 -0
- terrine-0.1.0.dev0/tests/compile/test_anchors.py +494 -0
- terrine-0.1.0.dev0/tests/compile/test_cohorts.py +210 -0
- terrine-0.1.0.dev0/tests/compile/test_columns.py +753 -0
- terrine-0.1.0.dev0/tests/compile/test_completeness_columns.py +228 -0
- terrine-0.1.0.dev0/tests/compile/test_cost_estimates.py +29 -0
- terrine-0.1.0.dev0/tests/compile/test_event_sequence.py +1124 -0
- terrine-0.1.0.dev0/tests/compile/test_ltv.py +301 -0
- terrine-0.1.0.dev0/tests/compile/test_matched_t0.py +150 -0
- terrine-0.1.0.dev0/tests/compile/test_nonadditive.py +398 -0
- terrine-0.1.0.dev0/tests/compile/test_panels.py +551 -0
- terrine-0.1.0.dev0/tests/compile/test_persisted_layers.py +429 -0
- terrine-0.1.0.dev0/tests/compile/test_range_scaling.py +224 -0
- terrine-0.1.0.dev0/tests/compile/test_retention.py +278 -0
- terrine-0.1.0.dev0/tests/compile/test_state_panel.py +851 -0
- terrine-0.1.0.dev0/tests/compile/test_survival_bounds.py +39 -0
- terrine-0.1.0.dev0/tests/compile/test_time_to_event.py +461 -0
- terrine-0.1.0.dev0/tests/compile/test_winsorization.py +98 -0
- terrine-0.1.0.dev0/tests/conftest.py +60 -0
- terrine-0.1.0.dev0/tests/dataset/__init__.py +0 -0
- terrine-0.1.0.dev0/tests/dataset/test_definition.py +171 -0
- terrine-0.1.0.dev0/tests/dataset/test_label_support.py +97 -0
- terrine-0.1.0.dev0/tests/dataset/test_manifest.py +127 -0
- terrine-0.1.0.dev0/tests/dataset/test_runtime_staging.py +64 -0
- terrine-0.1.0.dev0/tests/dataset/test_splits.py +173 -0
- terrine-0.1.0.dev0/tests/dataset/test_staging.py +28 -0
- terrine-0.1.0.dev0/tests/dataset/test_training_view.py +298 -0
- terrine-0.1.0.dev0/tests/dataset/test_winsorization_definition.py +69 -0
- terrine-0.1.0.dev0/tests/documentation.py +236 -0
- terrine-0.1.0.dev0/tests/execution/__init__.py +0 -0
- terrine-0.1.0.dev0/tests/execution/test_backend_provider.py +272 -0
- terrine-0.1.0.dev0/tests/execution/test_inputs.py +631 -0
- terrine-0.1.0.dev0/tests/execution/test_snowflake_session.py +204 -0
- terrine-0.1.0.dev0/tests/export/conftest.py +60 -0
- terrine-0.1.0.dev0/tests/export/test_diff_diff.py +136 -0
- terrine-0.1.0.dev0/tests/export/test_lifelines.py +228 -0
- terrine-0.1.0.dev0/tests/export/test_preflight.py +115 -0
- terrine-0.1.0.dev0/tests/export/test_surrogate.py +103 -0
- terrine-0.1.0.dev0/tests/export/test_warehouse_preflight.py +105 -0
- terrine-0.1.0.dev0/tests/fixtures/__init__.py +0 -0
- terrine-0.1.0.dev0/tests/fixtures/baseline.py +260 -0
- terrine-0.1.0.dev0/tests/fixtures/interop.py +117 -0
- terrine-0.1.0.dev0/tests/fixtures/materialized_frame_v1.json +1 -0
- terrine-0.1.0.dev0/tests/fixtures/pre_rename_definition.json +1 -0
- terrine-0.1.0.dev0/tests/fixtures/pre_rename_fitted_definition.json +1 -0
- terrine-0.1.0.dev0/tests/fixtures/pre_rename_fitted_transform.json +1 -0
- terrine-0.1.0.dev0/tests/fixtures/pre_rename_invocation.json +1 -0
- terrine-0.1.0.dev0/tests/fixtures/pre_rename_manifest.json +1 -0
- terrine-0.1.0.dev0/tests/fixtures/pre_rename_plan_request.json +1 -0
- terrine-0.1.0.dev0/tests/fixtures/pre_rename_saved_plan.json +1 -0
- terrine-0.1.0.dev0/tests/fixtures/test_baseline.py +68 -0
- terrine-0.1.0.dev0/tests/fixtures/winsorization.py +98 -0
- terrine-0.1.0.dev0/tests/integration/__init__.py +0 -0
- terrine-0.1.0.dev0/tests/integration/distribution_smoke.py +253 -0
- terrine-0.1.0.dev0/tests/integration/postgres_scratch.py +122 -0
- terrine-0.1.0.dev0/tests/integration/study_api_smoke.py +232 -0
- terrine-0.1.0.dev0/tests/integration/test_benchmark_failure_reporting.py +167 -0
- terrine-0.1.0.dev0/tests/integration/test_live_scale_gate.py +169 -0
- terrine-0.1.0.dev0/tests/parity/__init__.py +0 -0
- terrine-0.1.0.dev0/tests/parity/test_increment_frames.py +225 -0
- terrine-0.1.0.dev0/tests/reference/__init__.py +0 -0
- terrine-0.1.0.dev0/tests/reference/baseline.py +135 -0
- terrine-0.1.0.dev0/tests/reference/nonadditive.py +13 -0
- terrine-0.1.0.dev0/tests/reference/panels.py +133 -0
- terrine-0.1.0.dev0/tests/reference/ranges.py +42 -0
- terrine-0.1.0.dev0/tests/reference/retention.py +69 -0
- terrine-0.1.0.dev0/tests/reference/scale_metrics.py +94 -0
- terrine-0.1.0.dev0/tests/reference/test_baseline.py +120 -0
- terrine-0.1.0.dev0/tests/reference/test_event_sequences.py +153 -0
- terrine-0.1.0.dev0/tests/reference/test_panels.py +80 -0
- terrine-0.1.0.dev0/tests/runtime/__init__.py +0 -0
- terrine-0.1.0.dev0/tests/runtime/test_api.py +598 -0
- terrine-0.1.0.dev0/tests/runtime/test_arrow_output.py +40 -0
- terrine-0.1.0.dev0/tests/runtime/test_backend_capabilities.py +237 -0
- terrine-0.1.0.dev0/tests/runtime/test_batch_cleanup.py +51 -0
- terrine-0.1.0.dev0/tests/runtime/test_cancel_publication.py +166 -0
- terrine-0.1.0.dev0/tests/runtime/test_cli.py +256 -0
- terrine-0.1.0.dev0/tests/runtime/test_control_ipc.py +123 -0
- terrine-0.1.0.dev0/tests/runtime/test_control_recovery.py +188 -0
- terrine-0.1.0.dev0/tests/runtime/test_cost_estimates.py +372 -0
- terrine-0.1.0.dev0/tests/runtime/test_duckdb_publication.py +399 -0
- terrine-0.1.0.dev0/tests/runtime/test_execute.py +1247 -0
- terrine-0.1.0.dev0/tests/runtime/test_gc.py +133 -0
- terrine-0.1.0.dev0/tests/runtime/test_graph.py +117 -0
- terrine-0.1.0.dev0/tests/runtime/test_imports.py +22 -0
- terrine-0.1.0.dev0/tests/runtime/test_invalidation.py +118 -0
- terrine-0.1.0.dev0/tests/runtime/test_layers.py +325 -0
- terrine-0.1.0.dev0/tests/runtime/test_leases.py +115 -0
- terrine-0.1.0.dev0/tests/runtime/test_opentelemetry.py +86 -0
- terrine-0.1.0.dev0/tests/runtime/test_planner.py +437 -0
- terrine-0.1.0.dev0/tests/runtime/test_planning.py +284 -0
- terrine-0.1.0.dev0/tests/runtime/test_recovery_lease.py +41 -0
- terrine-0.1.0.dev0/tests/runtime/test_request_replay.py +195 -0
- terrine-0.1.0.dev0/tests/runtime/test_run_events.py +213 -0
- terrine-0.1.0.dev0/tests/runtime/test_run_status.py +173 -0
- terrine-0.1.0.dev0/tests/runtime/test_saved_plan.py +445 -0
- terrine-0.1.0.dev0/tests/runtime/test_snapshot.py +329 -0
- terrine-0.1.0.dev0/tests/runtime/test_snapshot_lifecycle.py +297 -0
- terrine-0.1.0.dev0/tests/runtime/test_state.py +184 -0
- terrine-0.1.0.dev0/tests/semantic/__init__.py +0 -0
- terrine-0.1.0.dev0/tests/semantic/test_catalog.py +458 -0
- terrine-0.1.0.dev0/tests/semantic/test_metric_rules.py +41 -0
- terrine-0.1.0.dev0/tests/semantic/test_rules_import.py +29 -0
- terrine-0.1.0.dev0/tests/semantic/test_sql.py +32 -0
- terrine-0.1.0.dev0/tests/simulate/__init__.py +0 -0
- terrine-0.1.0.dev0/tests/simulate/test_scale_generator.py +177 -0
- terrine-0.1.0.dev0/tests/simulate/test_world.py +98 -0
- terrine-0.1.0.dev0/tests/spec/__init__.py +0 -0
- terrine-0.1.0.dev0/tests/spec/test_calendar_comparison.py +88 -0
- terrine-0.1.0.dev0/tests/spec/test_design_io.py +279 -0
- terrine-0.1.0.dev0/tests/spec/test_expressions.py +54 -0
- terrine-0.1.0.dev0/tests/spec/test_nonadditive_spec.py +94 -0
- terrine-0.1.0.dev0/tests/spec/test_panels.py +172 -0
- terrine-0.1.0.dev0/tests/spec/test_recipes.py +360 -0
- terrine-0.1.0.dev0/tests/spec/test_retention.py +27 -0
- terrine-0.1.0.dev0/tests/spec/test_sequence.py +113 -0
- terrine-0.1.0.dev0/tests/spec/test_sketch_refusal.py +94 -0
- terrine-0.1.0.dev0/tests/spec/test_state_panel.py +103 -0
- terrine-0.1.0.dev0/tests/spec/test_validate.py +982 -0
- terrine-0.1.0.dev0/tests/temporal/__init__.py +0 -0
- terrine-0.1.0.dev0/tests/temporal/test_first_occurrence.py +230 -0
- terrine-0.1.0.dev0/tests/temporal/test_nonadditive.py +66 -0
- terrine-0.1.0.dev0/tests/temporal/test_prefix_lookup.py +249 -0
- terrine-0.1.0.dev0/tests/temporal/test_range_scaling.py +243 -0
- terrine-0.1.0.dev0/tests/temporal/test_readiness.py +16 -0
- terrine-0.1.0.dev0/tests/temporal/test_retention.py +386 -0
- terrine-0.1.0.dev0/tests/temporal/test_scd2_attributes.py +363 -0
- terrine-0.1.0.dev0/tests/temporal/test_semantic_binding.py +451 -0
- terrine-0.1.0.dev0/tests/temporal/test_sequence.py +293 -0
- terrine-0.1.0.dev0/tests/temporal/test_sessionize.py +206 -0
- terrine-0.1.0.dev0/tests/temporal/test_sketches.py +86 -0
- terrine-0.1.0.dev0/tests/temporal/test_sparse_state.py +543 -0
- terrine-0.1.0.dev0/tests/temporal/test_window_aggregates.py +391 -0
- terrine-0.1.0.dev0/tests/test_common_stack_interop.py +32 -0
- terrine-0.1.0.dev0/tests/test_distribution.py +21 -0
- terrine-0.1.0.dev0/tests/test_documentation.py +65 -0
- terrine-0.1.0.dev0/tests/test_errors.py +45 -0
- terrine-0.1.0.dev0/tests/test_frame.py +74 -0
- terrine-0.1.0.dev0/tests/test_frame_runtime.py +297 -0
- terrine-0.1.0.dev0/tests/test_metadata.py +453 -0
- terrine-0.1.0.dev0/tests/test_mutation_runner.py +33 -0
- terrine-0.1.0.dev0/tests/test_optional_dependencies.py +48 -0
- terrine-0.1.0.dev0/tests/test_windows.py +28 -0
- terrine-0.1.0.dev0/uv.lock +5333 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# terrine Individual Contributor License Agreement
|
|
2
|
+
|
|
3
|
+
Version 1.0 · effective 2026-10-20
|
|
4
|
+
|
|
5
|
+
The signature record stores the commit at which you signed, so the exact text
|
|
6
|
+
you agreed to is always recoverable from this file's git history. If this
|
|
7
|
+
Agreement is revised, the version above changes and existing signatures remain
|
|
8
|
+
bound to the version in force when they were made.
|
|
9
|
+
|
|
10
|
+
Thank you for your interest in contributing to terrine (the "Project"),
|
|
11
|
+
owned by Kyle Caron ("Owner", "we", "us").
|
|
12
|
+
|
|
13
|
+
This agreement clarifies the intellectual property license granted with
|
|
14
|
+
Contributions from any person or entity. It protects both you and the Owner;
|
|
15
|
+
it does **not** change your rights to use your own Contributions for any other
|
|
16
|
+
purpose.
|
|
17
|
+
|
|
18
|
+
**You keep the copyright in everything you contribute.** This is a license, not
|
|
19
|
+
an assignment. You are free to use, sell, relicense, and redistribute your own
|
|
20
|
+
Contributions however you wish, with no obligation to us.
|
|
21
|
+
|
|
22
|
+
You accept and agree to the following terms for your present and future
|
|
23
|
+
Contributions to the Project.
|
|
24
|
+
|
|
25
|
+
## 1. Definitions
|
|
26
|
+
|
|
27
|
+
"You" (or "Your") means the copyright owner, or the legal entity authorized by
|
|
28
|
+
the copyright owner, entering into this Agreement.
|
|
29
|
+
|
|
30
|
+
"Contribution" means any original work of authorship, including any
|
|
31
|
+
modifications to or additions to an existing work, that is or previously has
|
|
32
|
+
been intentionally submitted by You to the Owner for inclusion in, or
|
|
33
|
+
documentation of, the Project. "Submitted" means any form of electronic,
|
|
34
|
+
verbal, or written communication sent to the Owner or its representatives,
|
|
35
|
+
including but not limited to communication on electronic mailing lists, source
|
|
36
|
+
code control systems, and issue tracking systems that are managed by, or on
|
|
37
|
+
behalf of, the Owner for the purpose of discussing and improving the Project,
|
|
38
|
+
but excluding communication that is conspicuously marked or otherwise
|
|
39
|
+
designated in writing by You as "Not a Contribution."
|
|
40
|
+
|
|
41
|
+
## 2. Grant of Copyright License
|
|
42
|
+
|
|
43
|
+
Subject to the terms and conditions of this Agreement, You hereby grant to the
|
|
44
|
+
Owner and to recipients of software distributed by the Owner a perpetual,
|
|
45
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable, **transferable
|
|
46
|
+
and assignable** copyright license to reproduce, prepare derivative works of,
|
|
47
|
+
publicly display, publicly perform, **sublicense**, and distribute Your
|
|
48
|
+
Contributions and such derivative works.
|
|
49
|
+
|
|
50
|
+
The Owner may assign this Agreement, and the licenses granted under it, to a
|
|
51
|
+
successor in interest to the Project, including by merger, reorganization, or
|
|
52
|
+
sale of the assets to which the Project relates. This Agreement binds and
|
|
53
|
+
benefits the Owner's successors and assigns.
|
|
54
|
+
|
|
55
|
+
## 3. Right to License Under Any Terms
|
|
56
|
+
|
|
57
|
+
You acknowledge and agree that the Owner may license, sublicense, and
|
|
58
|
+
distribute Your Contributions — alone or as part of the Project — **under any
|
|
59
|
+
license terms the Owner chooses**, including open source licenses, source
|
|
60
|
+
available licenses, and proprietary or commercial licenses, and that the Owner
|
|
61
|
+
may offer the Project under multiple licenses simultaneously (dual licensing).
|
|
62
|
+
|
|
63
|
+
The Owner is under no obligation to distribute Your Contributions under the
|
|
64
|
+
license currently applied to the Project.
|
|
65
|
+
|
|
66
|
+
This clause exists so that the Owner can sustain the Project commercially. It
|
|
67
|
+
does not restrict You: the rights You grant here are non-exclusive, and Your
|
|
68
|
+
own rights in Your Contributions are unaffected.
|
|
69
|
+
|
|
70
|
+
## 4. Grant of Patent License
|
|
71
|
+
|
|
72
|
+
Subject to the terms and conditions of this Agreement, You hereby grant to the
|
|
73
|
+
Owner and to recipients of software distributed by the Owner a perpetual,
|
|
74
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as
|
|
75
|
+
stated in this section) patent license to make, have made, use, offer to sell,
|
|
76
|
+
sell, import, and otherwise transfer the Project, where such license applies
|
|
77
|
+
only to those patent claims licensable by You that are necessarily infringed by
|
|
78
|
+
Your Contribution(s) alone or by combination of Your Contribution(s) with the
|
|
79
|
+
Project to which such Contribution(s) was submitted.
|
|
80
|
+
|
|
81
|
+
If any entity institutes patent litigation against You or any other entity
|
|
82
|
+
(including a cross-claim or counterclaim in a lawsuit) alleging that Your
|
|
83
|
+
Contribution, or the Project to which You have contributed, constitutes direct
|
|
84
|
+
or contributory patent infringement, then any patent licenses granted to that
|
|
85
|
+
entity under this Agreement for that Contribution or Project shall terminate as
|
|
86
|
+
of the date such litigation is filed.
|
|
87
|
+
|
|
88
|
+
## 5. You Represent That You Are Entitled To Grant This License
|
|
89
|
+
|
|
90
|
+
You represent that You are legally entitled to grant the above license. If Your
|
|
91
|
+
employer(s) has rights to intellectual property that You create that includes
|
|
92
|
+
Your Contributions, You represent that You have received permission to make
|
|
93
|
+
Contributions on behalf of that employer, that You will have received
|
|
94
|
+
permission from Your current and future employers for all future
|
|
95
|
+
Contributions, that Your employer has waived such rights for all of Your
|
|
96
|
+
current and future Contributions to the Owner, or that Your employer has
|
|
97
|
+
executed a Corporate Contributor License Agreement with the Owner.
|
|
98
|
+
|
|
99
|
+
## 6. You Represent That Each Contribution Is Your Original Creation
|
|
100
|
+
|
|
101
|
+
You represent that each of Your Contributions is Your original creation. You
|
|
102
|
+
represent that Your Contribution submissions include complete details of any
|
|
103
|
+
third-party license or other restriction (including, but not limited to,
|
|
104
|
+
related patents and trademarks) of which You are personally aware and which are
|
|
105
|
+
associated with any part of Your Contributions.
|
|
106
|
+
|
|
107
|
+
## 7. Third-Party Work
|
|
108
|
+
|
|
109
|
+
Should You wish to submit work that is not Your original creation, You may
|
|
110
|
+
submit it to the Owner separately from any Contribution, identifying the
|
|
111
|
+
complete details of its source and of any license or other restriction
|
|
112
|
+
(including, but not limited to, related patents, trademarks, and license
|
|
113
|
+
agreements) of which You are personally aware, and conspicuously marking the
|
|
114
|
+
work as "Submitted on behalf of a third-party: [named here]".
|
|
115
|
+
|
|
116
|
+
## 8. No Obligation of Support or Warranty
|
|
117
|
+
|
|
118
|
+
You are not expected to provide support for Your Contributions, except to the
|
|
119
|
+
extent You desire to provide support. You may provide support for free, for a
|
|
120
|
+
fee, or not at all. Unless required by applicable law or agreed to in writing,
|
|
121
|
+
You provide Your Contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
122
|
+
CONDITIONS OF ANY KIND, either express or implied, including, without
|
|
123
|
+
limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT,
|
|
124
|
+
MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.
|
|
125
|
+
|
|
126
|
+
## 9. Notification of Changed Circumstances
|
|
127
|
+
|
|
128
|
+
You agree to notify the Owner of any facts or circumstances of which You become
|
|
129
|
+
aware that would make these representations inaccurate in any respect.
|
|
130
|
+
|
|
131
|
+
## Signing
|
|
132
|
+
|
|
133
|
+
Contributions are accepted only from signers of this Agreement, except for
|
|
134
|
+
automated accounts and coding agents named in the workflow allowlist, which
|
|
135
|
+
cannot themselves sign; the human opening the pull request remains responsible
|
|
136
|
+
for the representations above.
|
|
137
|
+
|
|
138
|
+
Sign electronically by commenting the following on your pull request, exactly:
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
I have read the CLA Document and I hereby sign the CLA
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
You sign once; the signature covers all of Your Contributions to the Project,
|
|
145
|
+
past and future.
|
|
146
|
+
|
|
147
|
+
**Record kept.** Signing stores your GitHub username, the text of your comment,
|
|
148
|
+
and a timestamp in the `cla-signatures` branch of this repository. That record
|
|
149
|
+
is retained for as long as the Project exists, because it is the evidence of
|
|
150
|
+
the licenses granted above. It is public if this repository is public.
|
|
151
|
+
|
|
152
|
+
If you are contributing on behalf of a company and your employer requires its
|
|
153
|
+
own agreement rather than the representations in section 5, contact
|
|
154
|
+
kyle.j.caron@gmail.com before opening a pull request.
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
pull_request:
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
# A newer push supersedes an in-flight run of the same ref.
|
|
9
|
+
concurrency:
|
|
10
|
+
group: ci-${{ github.ref }}
|
|
11
|
+
cancel-in-progress: true
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
checks:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
timeout-minutes: 30
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
- uses: astral-sh/setup-uv@v5
|
|
21
|
+
with:
|
|
22
|
+
enable-cache: true
|
|
23
|
+
- uses: actions/setup-python@v5
|
|
24
|
+
with:
|
|
25
|
+
python-version: "3.13"
|
|
26
|
+
- run: uv sync --locked --group dev --group docs --all-extras
|
|
27
|
+
- run: make lint
|
|
28
|
+
- run: make typecheck
|
|
29
|
+
unit:
|
|
30
|
+
runs-on: ubuntu-latest
|
|
31
|
+
timeout-minutes: 30
|
|
32
|
+
strategy:
|
|
33
|
+
fail-fast: false
|
|
34
|
+
matrix:
|
|
35
|
+
group: [1, 2, 3, 4]
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v4
|
|
38
|
+
- uses: astral-sh/setup-uv@v5
|
|
39
|
+
with:
|
|
40
|
+
enable-cache: true
|
|
41
|
+
- uses: actions/setup-python@v5
|
|
42
|
+
with:
|
|
43
|
+
python-version: "3.13"
|
|
44
|
+
- run: uv sync --locked --group dev --all-extras
|
|
45
|
+
- run: >-
|
|
46
|
+
uv run pytest -q tests
|
|
47
|
+
--splits 4 --group ${{ matrix.group }}
|
|
48
|
+
--splitting-algorithm least_duration
|
|
49
|
+
--durations-path tests/.test_durations
|
|
50
|
+
integration:
|
|
51
|
+
runs-on: ubuntu-latest
|
|
52
|
+
timeout-minutes: 30
|
|
53
|
+
strategy:
|
|
54
|
+
fail-fast: false
|
|
55
|
+
matrix:
|
|
56
|
+
# Groups are balanced from integration/.test_durations; tests without a
|
|
57
|
+
# stored duration get the average and are still assigned to a group.
|
|
58
|
+
group: [1, 2, 3, 4, 5, 6]
|
|
59
|
+
steps:
|
|
60
|
+
- uses: actions/checkout@v4
|
|
61
|
+
- uses: astral-sh/setup-uv@v5
|
|
62
|
+
with:
|
|
63
|
+
enable-cache: true
|
|
64
|
+
- uses: actions/setup-python@v5
|
|
65
|
+
with:
|
|
66
|
+
python-version: "3.13"
|
|
67
|
+
- run: uv sync --locked --group dev --all-extras
|
|
68
|
+
- if: matrix.group == 1
|
|
69
|
+
run: uv run python -m tests.integration.study_api_smoke
|
|
70
|
+
- run: >-
|
|
71
|
+
uv run pytest -q integration
|
|
72
|
+
--splits 6 --group ${{ matrix.group }}
|
|
73
|
+
--splitting-algorithm least_duration
|
|
74
|
+
--durations-path integration/.test_durations
|
|
75
|
+
docs-and-examples:
|
|
76
|
+
runs-on: ubuntu-latest
|
|
77
|
+
timeout-minutes: 30
|
|
78
|
+
steps:
|
|
79
|
+
- uses: actions/checkout@v4
|
|
80
|
+
- uses: astral-sh/setup-uv@v5
|
|
81
|
+
with:
|
|
82
|
+
enable-cache: true
|
|
83
|
+
- uses: actions/setup-python@v5
|
|
84
|
+
with:
|
|
85
|
+
python-version: "3.13"
|
|
86
|
+
- run: uv sync --locked --group dev --group docs --all-extras
|
|
87
|
+
- run: |
|
|
88
|
+
for example in examples/*.py; do
|
|
89
|
+
uv run python "$example"
|
|
90
|
+
done
|
|
91
|
+
- run: uv run --group docs python -m tests.documentation --build
|
|
92
|
+
- run: uv build
|
|
93
|
+
distributions:
|
|
94
|
+
runs-on: ubuntu-latest
|
|
95
|
+
strategy:
|
|
96
|
+
fail-fast: false
|
|
97
|
+
matrix:
|
|
98
|
+
python: ["3.13", "3.14"]
|
|
99
|
+
resolution: [highest, lowest-direct]
|
|
100
|
+
steps:
|
|
101
|
+
- uses: actions/checkout@v4
|
|
102
|
+
- uses: astral-sh/setup-uv@v5
|
|
103
|
+
with:
|
|
104
|
+
enable-cache: true
|
|
105
|
+
- uses: actions/setup-python@v5
|
|
106
|
+
with:
|
|
107
|
+
python-version: ${{ matrix.python }}
|
|
108
|
+
- run: uv build
|
|
109
|
+
- run: >-
|
|
110
|
+
uv run --no-project --python "${{ matrix.python }}" python
|
|
111
|
+
-m tests.integration.distribution_smoke
|
|
112
|
+
--wheel dist/*.whl --sdist dist/*.tar.gz
|
|
113
|
+
--python "${{ matrix.python }}" --resolution "${{ matrix.resolution }}"
|
|
114
|
+
sketches:
|
|
115
|
+
runs-on: ubuntu-latest
|
|
116
|
+
steps:
|
|
117
|
+
- uses: actions/checkout@v4
|
|
118
|
+
- uses: astral-sh/setup-uv@v5
|
|
119
|
+
with:
|
|
120
|
+
enable-cache: true
|
|
121
|
+
- uses: actions/setup-python@v5
|
|
122
|
+
with:
|
|
123
|
+
python-version: "3.13"
|
|
124
|
+
- run: uv sync --group dev --extra duckdb --extra pandas --extra sketches
|
|
125
|
+
- run: uv run pytest tests/temporal/test_sketches.py tests/spec/test_sketch_refusal.py tests/compile/test_nonadditive.py -q
|
|
126
|
+
|
|
127
|
+
postgres:
|
|
128
|
+
uses: ./.github/workflows/warehouse-backends.yml
|
|
129
|
+
with:
|
|
130
|
+
backend_mode: postgres
|
|
131
|
+
|
|
132
|
+
increment-compatibility:
|
|
133
|
+
runs-on: ubuntu-latest
|
|
134
|
+
steps:
|
|
135
|
+
- uses: actions/checkout@v4
|
|
136
|
+
- uses: astral-sh/setup-uv@v5
|
|
137
|
+
with:
|
|
138
|
+
enable-cache: true
|
|
139
|
+
- uses: actions/setup-python@v5
|
|
140
|
+
with:
|
|
141
|
+
python-version: "3.13"
|
|
142
|
+
- run: uv sync --locked --group dev --extra duckdb --extra increment
|
|
143
|
+
- run: uv run pytest tests/compat tests/parity
|
|
144
|
+
- run: uv run pytest integration/parity
|
|
145
|
+
|
|
146
|
+
library-handoffs:
|
|
147
|
+
runs-on: ubuntu-latest
|
|
148
|
+
steps:
|
|
149
|
+
- uses: actions/checkout@v4
|
|
150
|
+
- uses: astral-sh/setup-uv@v5
|
|
151
|
+
with:
|
|
152
|
+
enable-cache: true
|
|
153
|
+
- uses: actions/setup-python@v5
|
|
154
|
+
with:
|
|
155
|
+
python-version: "3.13"
|
|
156
|
+
- run: uv sync --locked --group dev --extra duckdb --extra doubleml --extra dowhy --extra duckreg --extra lifelines --extra diff-diff
|
|
157
|
+
- run: uv run pytest -q integration/handoffs
|
|
158
|
+
|
|
159
|
+
# Single check to require in branch protection. Matrix jobs report one check
|
|
160
|
+
# per entry, so requiring them individually means editing the ruleset every
|
|
161
|
+
# time a matrix changes.
|
|
162
|
+
ci-ok:
|
|
163
|
+
runs-on: ubuntu-latest
|
|
164
|
+
timeout-minutes: 5
|
|
165
|
+
needs:
|
|
166
|
+
- checks
|
|
167
|
+
- unit
|
|
168
|
+
- integration
|
|
169
|
+
- docs-and-examples
|
|
170
|
+
- distributions
|
|
171
|
+
- sketches
|
|
172
|
+
- postgres
|
|
173
|
+
- increment-compatibility
|
|
174
|
+
- library-handoffs
|
|
175
|
+
if: always()
|
|
176
|
+
permissions: {}
|
|
177
|
+
steps:
|
|
178
|
+
- name: Require every job to succeed
|
|
179
|
+
env:
|
|
180
|
+
NEEDS: ${{ toJSON(needs) }}
|
|
181
|
+
run: |
|
|
182
|
+
set -euo pipefail
|
|
183
|
+
echo "$NEEDS" | jq -r 'to_entries[] | "\(.key): \(.value.result)"'
|
|
184
|
+
failed=$(echo "$NEEDS" | jq -r '[to_entries[] | select(.value.result != "success") | .key] | join(", ")')
|
|
185
|
+
if [ -n "$failed" ]; then
|
|
186
|
+
echo "::error::jobs did not succeed: $failed"
|
|
187
|
+
exit 1
|
|
188
|
+
fi
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
name: cla
|
|
2
|
+
|
|
3
|
+
# Signatures are committed to the `cla-signatures` branch of this repo using
|
|
4
|
+
# the job's GITHUB_TOKEN, which is why `contents: write` below is required.
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
issue_comment: {types: [created]}
|
|
8
|
+
pull_request_target: {types: [opened, closed, reopened, synchronize]}
|
|
9
|
+
|
|
10
|
+
concurrency:
|
|
11
|
+
# Recording a signature is a read-modify-write on one JSON file guarded by a
|
|
12
|
+
# SHA precondition; concurrent signings would race and one would 409.
|
|
13
|
+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.event.issue.number }}
|
|
14
|
+
cancel-in-progress: false
|
|
15
|
+
|
|
16
|
+
permissions: {}
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
cla:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
timeout-minutes: 10
|
|
22
|
+
permissions:
|
|
23
|
+
actions: write
|
|
24
|
+
contents: write
|
|
25
|
+
pull-requests: write
|
|
26
|
+
statuses: write
|
|
27
|
+
# Write scopes on a pull_request_target job are safe only while nothing
|
|
28
|
+
# here checks out or executes PR-controlled content. Don't add a checkout
|
|
29
|
+
# or build step.
|
|
30
|
+
steps:
|
|
31
|
+
# Maintained fork of the archived contributor-assistant/github-action,
|
|
32
|
+
# pinned by SHA because this job holds write scopes under
|
|
33
|
+
# pull_request_target.
|
|
34
|
+
- uses: iainmcgin/cla-github-action@0d27e5a16278d4adb6b0c4b92f08ad27b0a21dc8 # v3.2.0
|
|
35
|
+
# Without this guard the action runs on every comment on every plain
|
|
36
|
+
# issue, where there is no pull request to resolve, and fails the check.
|
|
37
|
+
if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
|
|
38
|
+
env:
|
|
39
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
40
|
+
with:
|
|
41
|
+
path-to-document: ${{ github.server_url }}/${{ github.repository }}/blob/${{ github.event.repository.default_branch }}/.github/CLA.md
|
|
42
|
+
path-to-signatures: signatures/v1/cla.json
|
|
43
|
+
branch: cla-signatures
|
|
44
|
+
# AI coding agents add Co-authored-by trailers; they are counted as
|
|
45
|
+
# committers but cannot comment to sign, so they must be allowlisted
|
|
46
|
+
# or every agent-assisted PR blocks permanently.
|
|
47
|
+
# Name automated accounts explicitly; a wildcard such as bot* would also
|
|
48
|
+
# exempt human accounts whose names start with "bot".
|
|
49
|
+
allowlist: kylejcaron,dependabot[bot],renovate[bot],github-actions[bot],copilot,Copilot,Codex,Cursor,noreply@anthropic.com,cursoragent@cursor.com,codex@openai.com
|
|
50
|
+
# Fail the check when the PR opener authored none of the commits.
|
|
51
|
+
require-opener-as-author: true
|
|
52
|
+
lock-pullrequest-aftermerge: false
|
|
53
|
+
custom-pr-sign-comment: I have read the CLA Document and I hereby sign the CLA
|
|
54
|
+
custom-notsigned-prcomment: >
|
|
55
|
+
Thanks for the pull request. Before it can be merged, please read
|
|
56
|
+
the [Contributor License Agreement](${{ github.server_url }}/${{ github.repository }}/blob/${{ github.event.repository.default_branch }}/.github/CLA.md)
|
|
57
|
+
and sign it by posting the comment below. You keep the copyright in
|
|
58
|
+
your work; the CLA grants terrine's owner the right to license it,
|
|
59
|
+
including commercially. You sign once and it covers all your future
|
|
60
|
+
contributions.
|
|
61
|
+
custom-allsigned-prcomment: CLA signed by all contributors. Thank you.
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
name: release
|
|
2
|
+
|
|
3
|
+
# Tag-driven release: pushing a vX.Y.Z tag whose version equals
|
|
4
|
+
# `project.version` in pyproject.toml builds, verifies and publishes to PyPI,
|
|
5
|
+
# then creates a GitHub Release.
|
|
6
|
+
#
|
|
7
|
+
# Publishing uses PyPI Trusted Publishing (OIDC). No API token is stored.
|
|
8
|
+
# PyPI publisher settings:
|
|
9
|
+
# owner: kylejcaron repository: terrine
|
|
10
|
+
# workflow: release.yml environment: pypi
|
|
11
|
+
# Configure required reviewers on the `pypi` environment so a pushed tag alone
|
|
12
|
+
# cannot publish.
|
|
13
|
+
|
|
14
|
+
on:
|
|
15
|
+
push:
|
|
16
|
+
tags: ["v*"]
|
|
17
|
+
workflow_dispatch:
|
|
18
|
+
|
|
19
|
+
concurrency:
|
|
20
|
+
group: release-${{ github.ref }}
|
|
21
|
+
cancel-in-progress: false
|
|
22
|
+
|
|
23
|
+
permissions: {}
|
|
24
|
+
|
|
25
|
+
jobs:
|
|
26
|
+
build:
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
timeout-minutes: 15
|
|
29
|
+
permissions:
|
|
30
|
+
contents: read
|
|
31
|
+
outputs:
|
|
32
|
+
version: ${{ steps.check.outputs.version }}
|
|
33
|
+
prerelease: ${{ steps.check.outputs.prerelease }}
|
|
34
|
+
steps:
|
|
35
|
+
- name: Require a version tag
|
|
36
|
+
env:
|
|
37
|
+
REF: ${{ github.ref }}
|
|
38
|
+
run: |
|
|
39
|
+
set -euo pipefail
|
|
40
|
+
case "$REF" in
|
|
41
|
+
refs/tags/v*) ;;
|
|
42
|
+
*) echo "::error::release requires a v* tag ref, not a branch"; exit 1 ;;
|
|
43
|
+
esac
|
|
44
|
+
|
|
45
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
46
|
+
with:
|
|
47
|
+
persist-credentials: false
|
|
48
|
+
|
|
49
|
+
- uses: astral-sh/setup-uv@ae62891fec2bb8e7d6c99fc78c9fec3a63790f8d # v10.0.0
|
|
50
|
+
with:
|
|
51
|
+
enable-cache: true
|
|
52
|
+
|
|
53
|
+
- run: uv build --sdist --wheel --out-dir dist
|
|
54
|
+
|
|
55
|
+
- name: Verify built version matches the tag
|
|
56
|
+
id: check
|
|
57
|
+
shell: bash
|
|
58
|
+
run: |
|
|
59
|
+
set -euo pipefail
|
|
60
|
+
tag="${GITHUB_REF_NAME#v}"
|
|
61
|
+
# Wheel filename is {name}-{version}-{python}-{abi}-{platform}.whl
|
|
62
|
+
whl=$(ls dist/*.whl)
|
|
63
|
+
built=$(basename "$whl" | cut -d- -f2)
|
|
64
|
+
echo "tag=$tag built=$built"
|
|
65
|
+
|
|
66
|
+
if [ "$tag" != "$built" ]; then
|
|
67
|
+
echo "::error::tag v$tag does not match built version $built (pyproject.toml project.version)."
|
|
68
|
+
exit 1
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
# PyPI rejects PEP 440 local versions; fail before publishing.
|
|
72
|
+
case "$built" in
|
|
73
|
+
*+*) echo "::error::version $built has a local segment; PyPI will reject it"; exit 1 ;;
|
|
74
|
+
esac
|
|
75
|
+
|
|
76
|
+
# a/b/rc/dev -> mark the GitHub Release as a prerelease
|
|
77
|
+
if printf '%s' "$built" | grep -Eq '(a|b|rc|\.dev)[0-9]+'; then
|
|
78
|
+
echo "prerelease=true" >> "$GITHUB_OUTPUT"
|
|
79
|
+
else
|
|
80
|
+
echo "prerelease=false" >> "$GITHUB_OUTPUT"
|
|
81
|
+
fi
|
|
82
|
+
echo "version=$built" >> "$GITHUB_OUTPUT"
|
|
83
|
+
|
|
84
|
+
- name: Check metadata renders on PyPI
|
|
85
|
+
run: uvx twine check --strict dist/*
|
|
86
|
+
|
|
87
|
+
- name: Verify artifacts actually contain the package
|
|
88
|
+
shell: bash
|
|
89
|
+
run: |
|
|
90
|
+
set -euo pipefail
|
|
91
|
+
# hatchling builds a metadata-only wheel when the package directory is
|
|
92
|
+
# missing; refuse to publish an empty package, since PyPI versions can
|
|
93
|
+
# never be reused.
|
|
94
|
+
python3 - <<'PY'
|
|
95
|
+
import glob, sys, tarfile, zipfile
|
|
96
|
+
|
|
97
|
+
def one(pattern):
|
|
98
|
+
hits = glob.glob(pattern)
|
|
99
|
+
if not hits:
|
|
100
|
+
sys.exit(f"::error::no artifact matching {pattern} -- the build produced nothing")
|
|
101
|
+
if len(hits) > 1:
|
|
102
|
+
sys.exit(f"::error::expected exactly one {pattern}, found {len(hits)}: {hits}")
|
|
103
|
+
return hits[0]
|
|
104
|
+
|
|
105
|
+
whl = one("dist/*.whl")
|
|
106
|
+
mods = [n for n in zipfile.ZipFile(whl).namelist()
|
|
107
|
+
if n.startswith("terrine/") and n.endswith(".py")]
|
|
108
|
+
if not mods:
|
|
109
|
+
sys.exit(f"::error::{whl} contains no terrine/*.py modules")
|
|
110
|
+
print(f"wheel: {len(mods)} module(s)")
|
|
111
|
+
|
|
112
|
+
sdist = one("dist/*.tar.gz")
|
|
113
|
+
with tarfile.open(sdist) as tf:
|
|
114
|
+
src = [n for n in tf.getnames()
|
|
115
|
+
if "/terrine/" in n and n.endswith(".py")]
|
|
116
|
+
if not src:
|
|
117
|
+
sys.exit(f"::error::{sdist} contains no terrine/ sources")
|
|
118
|
+
print(f"sdist: {len(src)} module(s)")
|
|
119
|
+
PY
|
|
120
|
+
|
|
121
|
+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
122
|
+
with:
|
|
123
|
+
name: dist
|
|
124
|
+
path: dist/
|
|
125
|
+
if-no-files-found: error
|
|
126
|
+
|
|
127
|
+
publish:
|
|
128
|
+
needs: build
|
|
129
|
+
runs-on: ubuntu-latest
|
|
130
|
+
timeout-minutes: 15
|
|
131
|
+
environment:
|
|
132
|
+
name: pypi
|
|
133
|
+
url: https://pypi.org/project/terrine/${{ needs.build.outputs.version }}
|
|
134
|
+
permissions:
|
|
135
|
+
# OIDC token for Trusted Publishing. This is the only credential used.
|
|
136
|
+
id-token: write
|
|
137
|
+
steps:
|
|
138
|
+
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
139
|
+
with:
|
|
140
|
+
name: dist
|
|
141
|
+
path: dist/
|
|
142
|
+
|
|
143
|
+
- uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
|
|
144
|
+
with:
|
|
145
|
+
attestations: true
|
|
146
|
+
print-hash: true
|
|
147
|
+
|
|
148
|
+
github-release:
|
|
149
|
+
needs: [build, publish]
|
|
150
|
+
runs-on: ubuntu-latest
|
|
151
|
+
timeout-minutes: 10
|
|
152
|
+
permissions:
|
|
153
|
+
contents: write
|
|
154
|
+
steps:
|
|
155
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
156
|
+
with:
|
|
157
|
+
persist-credentials: false
|
|
158
|
+
|
|
159
|
+
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
160
|
+
with:
|
|
161
|
+
name: dist
|
|
162
|
+
path: dist/
|
|
163
|
+
|
|
164
|
+
- name: Create GitHub Release
|
|
165
|
+
env:
|
|
166
|
+
GH_TOKEN: ${{ github.token }}
|
|
167
|
+
TAG: ${{ github.ref_name }}
|
|
168
|
+
PRERELEASE: ${{ needs.build.outputs.prerelease }}
|
|
169
|
+
run: |
|
|
170
|
+
set -euo pipefail
|
|
171
|
+
args=(--verify-tag --generate-notes --title "$TAG")
|
|
172
|
+
[ "$PRERELEASE" = "true" ] && args+=(--prerelease)
|
|
173
|
+
gh release create "$TAG" "${args[@]}" dist/*
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
name: scale
|
|
2
|
+
|
|
3
|
+
# Resource-bound scale, oracle and live-warehouse checks. Too slow for every
|
|
4
|
+
# push; run weekly and on demand.
|
|
5
|
+
on:
|
|
6
|
+
schedule:
|
|
7
|
+
- cron: "0 7 * * 1"
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
concurrency:
|
|
11
|
+
group: scale
|
|
12
|
+
cancel-in-progress: false
|
|
13
|
+
|
|
14
|
+
env:
|
|
15
|
+
# One test at a time: each scale test saturates the 2-CPU runner (DuckDB uses
|
|
16
|
+
# every core), so parallel workers only contend and trip the hang guards.
|
|
17
|
+
PYTEST_ADDOPTS: -n 0
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
scale:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
timeout-minutes: 60
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v4
|
|
25
|
+
- uses: astral-sh/setup-uv@v5
|
|
26
|
+
with:
|
|
27
|
+
enable-cache: true
|
|
28
|
+
- uses: actions/setup-python@v5
|
|
29
|
+
with:
|
|
30
|
+
python-version: "3.13"
|
|
31
|
+
- run: uv sync --locked --group dev --all-extras
|
|
32
|
+
- run: make test-scale
|