mainsequence 6.0.22__tar.gz → 6.0.24__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.
- {mainsequence-6.0.22/mainsequence.egg-info → mainsequence-6.0.24}/PKG-INFO +1 -1
- {mainsequence-6.0.22 → mainsequence-6.0.24}/agent_scaffold/skills/platform_operations/orchestration_and_releases/SKILL.md +5 -21
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/client/base.py +0 -1
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/client/models_helpers.py +28 -111
- {mainsequence-6.0.22 → mainsequence-6.0.24/mainsequence.egg-info}/PKG-INFO +1 -1
- {mainsequence-6.0.22 → mainsequence-6.0.24}/pyproject.toml +1 -1
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_filter_normalization.py +120 -53
- {mainsequence-6.0.22 → mainsequence-6.0.24}/LICENSE +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/README.md +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/agent_scaffold/AGENTS.md +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/agent_scaffold/skills/a2a_sdk_execution/SKILL.md +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/agent_scaffold/skills/application_surfaces/api_surfaces/SKILL.md +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/agent_scaffold/skills/data_access/exploration/SKILL.md +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/agent_scaffold/skills/data_publishing/data_nodes/SKILL.md +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/agent_scaffold/skills/data_publishing/meta_table_migrations/SKILL.md +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/agent_scaffold/skills/data_publishing/meta_tables/SKILL.md +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/agent_scaffold/skills/maintenance/project-maintenance/SKILL.md +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/agent_scaffold/skills/platform_operations/access_control_and_sharing/SKILL.md +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/agent_scaffold/skills/sdk_project_execution/SKILL.md +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/__init__.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/__main__.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/bootstrap.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/cli/__init__.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/cli/api.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/cli/browser_auth.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/cli/cli.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/cli/config.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/cli/docker_utils.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/cli/doctor.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/cli/local_ops.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/cli/migrations.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/cli/model_filters.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/cli/project_status.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/cli/pydantic_cli.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/cli/sdk_utils.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/cli/ssh_utils.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/cli/ui.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/client/__init__.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/client/agent_runtime_models.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/client/client.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/client/compute_validation.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/client/data_sources_interfaces/__init__.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/client/data_sources_interfaces/duckdb.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/client/data_sources_interfaces/local_paths.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/client/data_sources_interfaces/sqlite.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/client/dtype_codec.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/client/exceptions.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/client/fastapi/__init__.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/client/fastapi/auth.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/client/metatables/__init__.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/client/metatables/core.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/client/models_foundry.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/client/models_user.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/client/utils.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/defaults.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/instrumentation/__init__.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/instrumentation/utils.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/logconf.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/__init__.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/__main__.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/compiled_sql/__init__.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/compiled_sql/v1.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/data_nodes/__init__.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/data_nodes/build_operations.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/data_nodes/data_nodes.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/data_nodes/models.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/data_nodes/namespacing.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/data_nodes/persist_managers.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/data_nodes/run_operations.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/data_nodes/utils.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/future_registry.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/hashing.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/migrations/__init__.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/migrations/alembic.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/migrations/env.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/migrations/provider.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/migrations/registry.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/migrations/scaffold.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/migrations/templates/__init__.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/migrations/templates/env.py.mako +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/migrations/templates/script.py.mako +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/pydantic_metadata.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/schema_names.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/sqlalchemy_contracts.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/project_skills.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/runtime_context.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/runtime_flags.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/scaffold_skills.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence.egg-info/SOURCES.txt +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence.egg-info/dependency_links.txt +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence.egg-info/entry_points.txt +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence.egg-info/requires.txt +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence.egg-info/top_level.txt +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/setup.cfg +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_auth_precedence.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_build_operations_hashing.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_canonical_api_route_contract.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_cli.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_cli_browser_auth.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_cli_migrations.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_client.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_data_access_mixin_dimension_audit.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_data_node_storage_dimension_queries.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_data_node_update_flow.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_dependency_extras.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_duckdb_interface_dimensions.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_instrumentation.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_logconf.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_meta_table_migrations.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_meta_tables_client_models.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_meta_tables_sqlalchemy_contracts.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_models_user_request_bound_auth.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_pod_project_resolution.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_project_batch_jobs_from_file.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_project_branch_contract.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_project_skills.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_run_configuration.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_scaffold_skills.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_schema_names.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_secret_client_model.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_source_table_configuration.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_sqlite_interface_dimensions.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_update_runner_uid_runtime.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_update_statistics.py +0 -0
- {mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_update_uid_guards.py +0 -0
|
@@ -209,14 +209,14 @@ Validate the deployment path, not the Streamlit design.
|
|
|
209
209
|
|
|
210
210
|
`automatic_deployment` is the automated deployment opt-in flag on a `ResourceRelease`. It means repository synchronization can rotate an existing release to the latest synced project commit for the same resource path.
|
|
211
211
|
|
|
212
|
-
When `automatic_deployment=True`, repository-sync events may create a `
|
|
212
|
+
When `automatic_deployment=True`, repository-sync events may create a unified `DeploymentRun` with `target_type="resource_release"` and source `repository_event`. That run:
|
|
213
213
|
|
|
214
214
|
- reads the project's current synced commit
|
|
215
215
|
- resolves the current project resource at the release's existing resource path
|
|
216
216
|
- resolves the current adjacent `README.md` when the release kind requires one, such as Streamlit dashboards
|
|
217
217
|
- creates or resolves the project image for that commit
|
|
218
218
|
- redeploys the existing release to the current resource, README, and project image
|
|
219
|
-
- records
|
|
219
|
+
- records state, phase, outcome, revision context, artifact context, steps, logs, result, and errors on the deployment run
|
|
220
220
|
|
|
221
221
|
This is not a local development shortcut. It does not deploy unpushed local files. The repository must be pushed, the project repository must be synced, and project resource discovery must find the resource at the same path for the current commit.
|
|
222
222
|
|
|
@@ -247,28 +247,12 @@ The SDK surface also accepts:
|
|
|
247
247
|
- `ProjectResource.create_dashboard(..., automatic_deployment=True)`
|
|
248
248
|
- `ProjectResource.create_fastapi(..., automatic_deployment=True)`
|
|
249
249
|
- `ResourceRelease.create(..., automatic_deployment=True)`
|
|
250
|
-
- `ResourceRelease.deploy_current_version()` for an SDK-triggered manual deployment run
|
|
250
|
+
- `ResourceRelease.deploy_current_version()` for an SDK-triggered manual deployment run; it returns `DeploymentRun`
|
|
251
|
+
- `DeploymentRun.filter(target_type="resource_release", target_uid=release.uid)` to inspect runs for one release
|
|
251
252
|
|
|
252
253
|
Do not claim there is a CLI command for `deploy_current_version` unless the local CLI actually exposes one. In this SDK, the manual detail action is available through the client model.
|
|
253
254
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
- `pending`
|
|
257
|
-
- `running`
|
|
258
|
-
- `waiting_project_image`
|
|
259
|
-
- `waiting_runtime_ready`
|
|
260
|
-
- `no_action`
|
|
261
|
-
- `deployed`
|
|
262
|
-
- `skipped`
|
|
263
|
-
- `blocked`
|
|
264
|
-
- `failed`
|
|
265
|
-
|
|
266
|
-
Important blocked/skipped cases include:
|
|
267
|
-
|
|
268
|
-
- `automatic_deployment_disabled`: repository-event rotation skipped because the release is not opted in
|
|
269
|
-
- `project_current_version_missing`: the project has no current synced version
|
|
270
|
-
- `resource_missing_for_current_commit`: no resource exists at the release path for the latest synced commit
|
|
271
|
-
- `readme_missing_for_current_commit`: a dashboard-style release needs an adjacent README for the current commit
|
|
255
|
+
Inspect the unified run's `state`, `phase`, `outcome`, `steps`, `logs`, and `error` fields. Do not use legacy resource-release deployment status fields or filters.
|
|
272
256
|
|
|
273
257
|
## Review Rules
|
|
274
258
|
|
|
@@ -100,7 +100,6 @@ class BaseObjectOrm:
|
|
|
100
100
|
"GithubOrganization": "github-organizations",
|
|
101
101
|
"ProjectResource": "project-resources",
|
|
102
102
|
"ResourceRelease": "resource-releases",
|
|
103
|
-
"ResourceReleaseAutomaticDeploymentRun": "deployment-runs",
|
|
104
103
|
"DeploymentRun": "deployment-runs",
|
|
105
104
|
"Bucket": "buckets",
|
|
106
105
|
}
|
|
@@ -963,6 +963,24 @@ class ResourceReleaseKind(str, Enum):
|
|
|
963
963
|
STATIC_SITE = "static_site"
|
|
964
964
|
|
|
965
965
|
|
|
966
|
+
class AutomaticRedeploymentPolicy(BaseModel):
|
|
967
|
+
tag_regex: str | None = Field(
|
|
968
|
+
...,
|
|
969
|
+
title="Tag Regex",
|
|
970
|
+
description=(
|
|
971
|
+
"Regular expression matched against immutable repository tags. "
|
|
972
|
+
"Null enables redeployment for every commit."
|
|
973
|
+
),
|
|
974
|
+
examples=[None, r"^v(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)$"],
|
|
975
|
+
)
|
|
976
|
+
policy_revision: PositiveInt = Field(
|
|
977
|
+
...,
|
|
978
|
+
title="Policy Revision",
|
|
979
|
+
description="Immutable revision of the current automatic redeployment policy.",
|
|
980
|
+
examples=[1, 3],
|
|
981
|
+
)
|
|
982
|
+
|
|
983
|
+
|
|
966
984
|
class ResourceRelease(ShareableObjectMixin, BaseObjectOrm, BasePydanticModel):
|
|
967
985
|
FILTERSET_FIELDS: ClassVar[dict[str, list[str]]] = {
|
|
968
986
|
"uid": ["exact", "in"],
|
|
@@ -1065,6 +1083,14 @@ class ResourceRelease(ShareableObjectMixin, BaseObjectOrm, BasePydanticModel):
|
|
|
1065
1083
|
),
|
|
1066
1084
|
examples=[False, True],
|
|
1067
1085
|
)
|
|
1086
|
+
automatic_redeployment_policy: AutomaticRedeploymentPolicy | None = Field(
|
|
1087
|
+
default=None,
|
|
1088
|
+
title="Automatic Redeployment Policy",
|
|
1089
|
+
description=(
|
|
1090
|
+
"Backend-owned tag matching policy and its current immutable revision. "
|
|
1091
|
+
"The revision is returned by the API and is not part of create requests."
|
|
1092
|
+
),
|
|
1093
|
+
)
|
|
1068
1094
|
|
|
1069
1095
|
@classmethod
|
|
1070
1096
|
def create(
|
|
@@ -1148,7 +1174,7 @@ class ResourceRelease(ShareableObjectMixin, BaseObjectOrm, BasePydanticModel):
|
|
|
1148
1174
|
self,
|
|
1149
1175
|
*,
|
|
1150
1176
|
timeout: int | float | tuple[float, float] | None = None,
|
|
1151
|
-
) ->
|
|
1177
|
+
) -> DeploymentRun:
|
|
1152
1178
|
data = self._request_detail_action(
|
|
1153
1179
|
r_type="POST",
|
|
1154
1180
|
action_name="deploy-current-version",
|
|
@@ -1156,116 +1182,7 @@ class ResourceRelease(ShareableObjectMixin, BaseObjectOrm, BasePydanticModel):
|
|
|
1156
1182
|
timeout=timeout,
|
|
1157
1183
|
expected_statuses=(200, 202),
|
|
1158
1184
|
)
|
|
1159
|
-
return
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
class ResourceReleaseAutomaticDeploymentRun(BaseObjectOrm, BasePydanticModel):
|
|
1163
|
-
FILTERSET_FIELDS: ClassVar[dict[str, list[str]]] = {
|
|
1164
|
-
"resource_release__uid": ["exact", "in"],
|
|
1165
|
-
"status": ["exact", "in"],
|
|
1166
|
-
"release_kind": ["exact", "in"],
|
|
1167
|
-
"automatic_deployment_source": ["exact", "in"],
|
|
1168
|
-
}
|
|
1169
|
-
FILTER_VALUE_NORMALIZERS: ClassVar[dict[str, str]] = {
|
|
1170
|
-
"resource_release__uid": "uid",
|
|
1171
|
-
"status": "str",
|
|
1172
|
-
"release_kind": "str",
|
|
1173
|
-
"automatic_deployment_source": "str",
|
|
1174
|
-
}
|
|
1175
|
-
|
|
1176
|
-
STATUS_PENDING: ClassVar[str] = "pending"
|
|
1177
|
-
STATUS_RUNNING: ClassVar[str] = "running"
|
|
1178
|
-
STATUS_WAITING_PROJECT_IMAGE: ClassVar[str] = "waiting_project_image"
|
|
1179
|
-
STATUS_WAITING_RUNTIME_READY: ClassVar[str] = "waiting_runtime_ready"
|
|
1180
|
-
STATUS_NO_ACTION: ClassVar[str] = "no_action"
|
|
1181
|
-
STATUS_DEPLOYED: ClassVar[str] = "deployed"
|
|
1182
|
-
STATUS_SKIPPED: ClassVar[str] = "skipped"
|
|
1183
|
-
STATUS_BLOCKED: ClassVar[str] = "blocked"
|
|
1184
|
-
STATUS_FAILED: ClassVar[str] = "failed"
|
|
1185
|
-
|
|
1186
|
-
SOURCE_MANUAL: ClassVar[str] = "manual"
|
|
1187
|
-
SOURCE_REPOSITORY_EVENT: ClassVar[str] = "repository_event"
|
|
1188
|
-
|
|
1189
|
-
uid: str | None = Field(
|
|
1190
|
-
None,
|
|
1191
|
-
title="Resource Release Automatic Deployment Run UID",
|
|
1192
|
-
description="Public UID of the automatic deployment run.",
|
|
1193
|
-
)
|
|
1194
|
-
resource_release_uid: str | None = Field(
|
|
1195
|
-
None,
|
|
1196
|
-
title="Resource Release UID",
|
|
1197
|
-
description="Public UID snapshot of the resource release targeted by this run.",
|
|
1198
|
-
)
|
|
1199
|
-
resource_release_name: str = Field(
|
|
1200
|
-
default="",
|
|
1201
|
-
title="Resource Release Name",
|
|
1202
|
-
description="Display-name snapshot of the targeted resource release.",
|
|
1203
|
-
)
|
|
1204
|
-
release_kind: ResourceReleaseKind | str | None = Field(
|
|
1205
|
-
None,
|
|
1206
|
-
title="Release Kind",
|
|
1207
|
-
description="Resource release kind targeted by this run.",
|
|
1208
|
-
)
|
|
1209
|
-
status: str | None = Field(
|
|
1210
|
-
None,
|
|
1211
|
-
title="Status",
|
|
1212
|
-
description="Deployment run status.",
|
|
1213
|
-
)
|
|
1214
|
-
current_step: str = Field(
|
|
1215
|
-
default="",
|
|
1216
|
-
title="Current Step",
|
|
1217
|
-
description="Current orchestration step key.",
|
|
1218
|
-
)
|
|
1219
|
-
automatic_deployment_source: str | None = Field(
|
|
1220
|
-
None,
|
|
1221
|
-
title="Automatic Deployment Source",
|
|
1222
|
-
description="Run trigger source, for example manual or repository_event.",
|
|
1223
|
-
)
|
|
1224
|
-
revision_context: dict[str, Any] = Field(
|
|
1225
|
-
default_factory=dict,
|
|
1226
|
-
title="Revision Context",
|
|
1227
|
-
description="Stable project/revision/resource context for the run.",
|
|
1228
|
-
)
|
|
1229
|
-
trigger_context: dict[str, Any] = Field(
|
|
1230
|
-
default_factory=dict,
|
|
1231
|
-
title="Trigger Context",
|
|
1232
|
-
description="Repository event or manual trigger correlation metadata.",
|
|
1233
|
-
)
|
|
1234
|
-
image_artifact_context: dict[str, Any] = Field(
|
|
1235
|
-
default_factory=dict,
|
|
1236
|
-
title="Image Artifact Context",
|
|
1237
|
-
description="Project image and resource snapshots captured by the run.",
|
|
1238
|
-
)
|
|
1239
|
-
cleanup_context: dict[str, Any] = Field(
|
|
1240
|
-
default_factory=dict,
|
|
1241
|
-
title="Cleanup Context",
|
|
1242
|
-
description="Cleanup outcomes captured by the run.",
|
|
1243
|
-
)
|
|
1244
|
-
started_at: datetime.datetime | None = Field(
|
|
1245
|
-
None,
|
|
1246
|
-
title="Started At",
|
|
1247
|
-
description="Timestamp when execution started.",
|
|
1248
|
-
)
|
|
1249
|
-
finished_at: datetime.datetime | None = Field(
|
|
1250
|
-
None,
|
|
1251
|
-
title="Finished At",
|
|
1252
|
-
description="Timestamp when execution finished.",
|
|
1253
|
-
)
|
|
1254
|
-
result: dict[str, Any] = Field(
|
|
1255
|
-
default_factory=dict,
|
|
1256
|
-
title="Result",
|
|
1257
|
-
description="Terminal or intermediate deployment result payload.",
|
|
1258
|
-
)
|
|
1259
|
-
error_code: str = Field(
|
|
1260
|
-
default="",
|
|
1261
|
-
title="Error Code",
|
|
1262
|
-
description="Machine-readable error code when the run failed or was blocked.",
|
|
1263
|
-
)
|
|
1264
|
-
error_detail: str = Field(
|
|
1265
|
-
default="",
|
|
1266
|
-
title="Error Detail",
|
|
1267
|
-
description="Human-readable error detail when the run failed or was blocked.",
|
|
1268
|
-
)
|
|
1185
|
+
return DeploymentRun(**data)
|
|
1269
1186
|
|
|
1270
1187
|
|
|
1271
1188
|
class DeploymentRunTarget(BaseModel):
|
|
@@ -2041,7 +2041,7 @@ def test_resource_release_model_accepts_collection_payload_without_runtime_child
|
|
|
2041
2041
|
assert release.related_job_uid is None
|
|
2042
2042
|
|
|
2043
2043
|
|
|
2044
|
-
def
|
|
2044
|
+
def test_resource_release_model_supports_automatic_deployment_payloads():
|
|
2045
2045
|
release_uid = "2f4c4c3d-5669-4da5-9d86-b84633c1e6ed"
|
|
2046
2046
|
resource_uid = "857bec7b-dd77-4272-aecd-13fc2138eacc"
|
|
2047
2047
|
job_uid = "7d0ab07c-d1c0-4b7f-9c69-3c1a41c0a4da"
|
|
@@ -2055,40 +2055,30 @@ def test_resource_release_models_support_automatic_deployment_payloads():
|
|
|
2055
2055
|
"related_job_uid": job_uid,
|
|
2056
2056
|
"release_kind": "fastapi",
|
|
2057
2057
|
"automatic_deployment": True,
|
|
2058
|
+
"automatic_redeployment_policy": {
|
|
2059
|
+
"tag_regex": None,
|
|
2060
|
+
"policy_revision": 3,
|
|
2061
|
+
},
|
|
2058
2062
|
}
|
|
2059
2063
|
)
|
|
2060
2064
|
|
|
2061
2065
|
assert release.uid == release_uid
|
|
2062
2066
|
assert release.release_kind == models_helpers_mod.ResourceReleaseKind.FAST_API
|
|
2063
2067
|
assert release.automatic_deployment is True
|
|
2068
|
+
assert release.automatic_redeployment_policy is not None
|
|
2069
|
+
assert release.automatic_redeployment_policy.tag_regex is None
|
|
2070
|
+
assert release.automatic_redeployment_policy.policy_revision == 3
|
|
2064
2071
|
|
|
2065
|
-
run = models_helpers_mod.ResourceReleaseAutomaticDeploymentRun.model_validate(
|
|
2066
|
-
{
|
|
2067
|
-
"uid": "11111111-1111-4111-8111-111111111111",
|
|
2068
|
-
"resource_release_uid": release_uid,
|
|
2069
|
-
"resource_release_name": "analytics-123",
|
|
2070
|
-
"release_kind": "fastapi",
|
|
2071
|
-
"status": "waiting_project_image",
|
|
2072
|
-
"current_step": "wait_project_image",
|
|
2073
|
-
"automatic_deployment_source": "manual",
|
|
2074
|
-
"revision_context": {"current_commit_sha": "abc123"},
|
|
2075
|
-
"trigger_context": {},
|
|
2076
|
-
"image_artifact_context": {"project_image": {"state": "waiting"}},
|
|
2077
|
-
"cleanup_context": {},
|
|
2078
|
-
"started_at": "2026-01-01T00:00:00Z",
|
|
2079
|
-
"finished_at": None,
|
|
2080
|
-
"result": {},
|
|
2081
|
-
"error_code": "",
|
|
2082
|
-
"error_detail": "",
|
|
2083
|
-
}
|
|
2084
|
-
)
|
|
2085
2072
|
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
assert
|
|
2073
|
+
def test_legacy_resource_release_deployment_run_model_is_not_exported():
|
|
2074
|
+
import mainsequence.client as client_package
|
|
2075
|
+
|
|
2076
|
+
legacy_name = "ResourceReleaseAutomaticDeploymentRun"
|
|
2077
|
+
|
|
2078
|
+
assert not hasattr(models_helpers_mod, legacy_name)
|
|
2079
|
+
assert not hasattr(client_package, legacy_name)
|
|
2080
|
+
with pytest.raises(KeyError, match=legacy_name):
|
|
2081
|
+
models_helpers_mod.get_model_class(legacy_name)
|
|
2092
2082
|
|
|
2093
2083
|
|
|
2094
2084
|
def test_resource_release_create_sends_automatic_deployment(monkeypatch):
|
|
@@ -2110,6 +2100,10 @@ def test_resource_release_create_sends_automatic_deployment(monkeypatch):
|
|
|
2110
2100
|
"related_job_uid": "7d0ab07c-d1c0-4b7f-9c69-3c1a41c0a4da",
|
|
2111
2101
|
"release_kind": "fastapi",
|
|
2112
2102
|
"automatic_deployment": True,
|
|
2103
|
+
"automatic_redeployment_policy": {
|
|
2104
|
+
"tag_regex": "^v[0-9]+\\.[0-9]+\\.[0-9]+$",
|
|
2105
|
+
"policy_revision": 1,
|
|
2106
|
+
},
|
|
2113
2107
|
}
|
|
2114
2108
|
|
|
2115
2109
|
def _fake_make_request(*, s, loaders, r_type, url, payload, time_out=None):
|
|
@@ -2132,6 +2126,9 @@ def test_resource_release_create_sends_automatic_deployment(monkeypatch):
|
|
|
2132
2126
|
)
|
|
2133
2127
|
|
|
2134
2128
|
assert release.automatic_deployment is True
|
|
2129
|
+
assert release.automatic_redeployment_policy is not None
|
|
2130
|
+
assert release.automatic_redeployment_policy.tag_regex == "^v[0-9]+\\.[0-9]+\\.[0-9]+$"
|
|
2131
|
+
assert release.automatic_redeployment_policy.policy_revision == 1
|
|
2135
2132
|
assert captured["r_type"] == "POST"
|
|
2136
2133
|
assert str(captured["url"]).endswith("/api/v1/resource-releases/")
|
|
2137
2134
|
assert captured["payload"]["json"]["automatic_deployment"] is True
|
|
@@ -2209,21 +2206,31 @@ def test_resource_release_deploy_current_version_posts_detail_action(monkeypatch
|
|
|
2209
2206
|
def json():
|
|
2210
2207
|
return {
|
|
2211
2208
|
"uid": run_uid,
|
|
2212
|
-
"
|
|
2213
|
-
"
|
|
2214
|
-
"
|
|
2215
|
-
"
|
|
2216
|
-
"
|
|
2217
|
-
"
|
|
2209
|
+
"target_type": "resource_release",
|
|
2210
|
+
"target": {"uid": release_uid, "name": "analytics-123", "kind": "fastapi"},
|
|
2211
|
+
"project_branch_uid": "33333333-3333-4333-8333-333333333333",
|
|
2212
|
+
"operation": "build_and_deploy",
|
|
2213
|
+
"source": "manual",
|
|
2214
|
+
"commit_sha": "a" * 40,
|
|
2215
|
+
"configuration_revision": 4,
|
|
2216
|
+
"state": "succeeded",
|
|
2217
|
+
"phase": "completed",
|
|
2218
|
+
"outcome": "deployed",
|
|
2219
|
+
"created_at": "2026-07-19T12:00:00Z",
|
|
2220
|
+
"started_at": "2026-07-19T12:00:01Z",
|
|
2221
|
+
"finished_at": "2026-07-19T12:00:05Z",
|
|
2218
2222
|
"revision_context": {},
|
|
2219
2223
|
"trigger_context": {},
|
|
2220
|
-
"
|
|
2224
|
+
"artifact_context": {},
|
|
2221
2225
|
"cleanup_context": {},
|
|
2222
|
-
"started_at": None,
|
|
2223
|
-
"finished_at": None,
|
|
2224
2226
|
"result": {},
|
|
2225
|
-
"
|
|
2226
|
-
"
|
|
2227
|
+
"steps": [],
|
|
2228
|
+
"logs": {
|
|
2229
|
+
"state": "available",
|
|
2230
|
+
"url": f"/api/v1/deployment-runs/{run_uid}/logs/",
|
|
2231
|
+
"retention_expires_at": None,
|
|
2232
|
+
},
|
|
2233
|
+
"error": None,
|
|
2227
2234
|
}
|
|
2228
2235
|
|
|
2229
2236
|
def _fake_make_request(*, s, loaders, r_type, url, payload, time_out=None):
|
|
@@ -2238,7 +2245,13 @@ def test_resource_release_deploy_current_version_posts_detail_action(monkeypatch
|
|
|
2238
2245
|
run = release.deploy_current_version(timeout=9)
|
|
2239
2246
|
|
|
2240
2247
|
assert run.uid == run_uid
|
|
2241
|
-
assert run
|
|
2248
|
+
assert isinstance(run, models_helpers_mod.DeploymentRun)
|
|
2249
|
+
assert run.target.uid == release_uid
|
|
2250
|
+
assert run.state == "succeeded"
|
|
2251
|
+
assert run.phase == "completed"
|
|
2252
|
+
assert run.outcome == "deployed"
|
|
2253
|
+
assert run.logs.state == "available"
|
|
2254
|
+
assert run.error is None
|
|
2242
2255
|
assert captured == {
|
|
2243
2256
|
"r_type": "POST",
|
|
2244
2257
|
"url": (
|
|
@@ -2250,24 +2263,78 @@ def test_resource_release_deploy_current_version_posts_detail_action(monkeypatch
|
|
|
2250
2263
|
}
|
|
2251
2264
|
|
|
2252
2265
|
|
|
2253
|
-
def
|
|
2254
|
-
|
|
2266
|
+
def test_deployment_run_collection_and_detail_use_unified_resource_release_contract(monkeypatch):
|
|
2267
|
+
captured = []
|
|
2268
|
+
run_uid = "11111111-1111-4111-8111-111111111111"
|
|
2269
|
+
release_uid = "2f4c4c3d-5669-4da5-9d86-b84633c1e6ed"
|
|
2270
|
+
response_payload = {
|
|
2271
|
+
"uid": run_uid,
|
|
2272
|
+
"target_type": "resource_release",
|
|
2273
|
+
"target": {"uid": release_uid, "name": "analytics-123", "kind": "fastapi"},
|
|
2274
|
+
"project_branch_uid": "33333333-3333-4333-8333-333333333333",
|
|
2275
|
+
"operation": "build_and_deploy",
|
|
2276
|
+
"source": "repository_event",
|
|
2277
|
+
"commit_sha": "a" * 40,
|
|
2278
|
+
"configuration_revision": 4,
|
|
2279
|
+
"state": "succeeded",
|
|
2280
|
+
"phase": "completed",
|
|
2281
|
+
"outcome": "deployed",
|
|
2282
|
+
"created_at": "2026-07-19T12:00:00Z",
|
|
2283
|
+
"started_at": "2026-07-19T12:00:01Z",
|
|
2284
|
+
"finished_at": "2026-07-19T12:00:05Z",
|
|
2285
|
+
"revision_context": {},
|
|
2286
|
+
"trigger_context": {},
|
|
2287
|
+
"artifact_context": {},
|
|
2288
|
+
"cleanup_context": {},
|
|
2289
|
+
"result": {},
|
|
2290
|
+
"steps": [],
|
|
2291
|
+
"logs": {
|
|
2292
|
+
"state": "available",
|
|
2293
|
+
"url": f"/api/v1/deployment-runs/{run_uid}/logs/",
|
|
2294
|
+
"retention_expires_at": None,
|
|
2295
|
+
},
|
|
2296
|
+
"error": None,
|
|
2297
|
+
}
|
|
2298
|
+
|
|
2299
|
+
class FakeResponse:
|
|
2300
|
+
status_code = 200
|
|
2301
|
+
|
|
2302
|
+
def __init__(self, payload):
|
|
2303
|
+
self.payload = payload
|
|
2255
2304
|
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2305
|
+
def json(self):
|
|
2306
|
+
return self.payload
|
|
2307
|
+
|
|
2308
|
+
def _fake_make_request(*, s, loaders, r_type, url, payload, time_out=None):
|
|
2309
|
+
captured.append({"r_type": r_type, "url": url, "payload": payload})
|
|
2310
|
+
if url.rstrip("/") == models_helpers_mod.DeploymentRun.get_object_url():
|
|
2311
|
+
return FakeResponse({"results": [dict(response_payload)], "next": None})
|
|
2312
|
+
return FakeResponse(dict(response_payload))
|
|
2313
|
+
|
|
2314
|
+
monkeypatch.setattr(
|
|
2315
|
+
models_helpers_mod.DeploymentRun,
|
|
2316
|
+
"build_session",
|
|
2317
|
+
classmethod(lambda cls: object()),
|
|
2263
2318
|
)
|
|
2319
|
+
monkeypatch.setattr(base_mod, "make_request", _fake_make_request)
|
|
2264
2320
|
|
|
2265
|
-
|
|
2266
|
-
"
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2321
|
+
runs = models_helpers_mod.DeploymentRun.filter(
|
|
2322
|
+
target_type="resource_release",
|
|
2323
|
+
target_uid=release_uid,
|
|
2324
|
+
)
|
|
2325
|
+
detail = models_helpers_mod.DeploymentRun.get(pk=run_uid)
|
|
2326
|
+
|
|
2327
|
+
assert len(runs) == 1
|
|
2328
|
+
assert runs[0].target.uid == release_uid
|
|
2329
|
+
assert detail.state == "succeeded"
|
|
2330
|
+
assert detail.phase == "completed"
|
|
2331
|
+
assert detail.outcome == "deployed"
|
|
2332
|
+
assert detail.logs.state == "available"
|
|
2333
|
+
assert detail.error is None
|
|
2334
|
+
assert captured[0]["payload"] == {
|
|
2335
|
+
"params": {"target_type": "resource_release", "target_uid": release_uid}
|
|
2270
2336
|
}
|
|
2337
|
+
assert captured[1]["url"].endswith(f"/deployment-runs/{run_uid}/")
|
|
2271
2338
|
|
|
2272
2339
|
|
|
2273
2340
|
def test_unified_deployment_run_models_and_filters(monkeypatch):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-6.0.22 → mainsequence-6.0.24}/agent_scaffold/skills/a2a_sdk_execution/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
{mainsequence-6.0.22 → mainsequence-6.0.24}/agent_scaffold/skills/data_access/exploration/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-6.0.22 → mainsequence-6.0.24}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-6.0.22 → mainsequence-6.0.24}/agent_scaffold/skills/sdk_project_execution/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/client/data_sources_interfaces/__init__.py
RENAMED
|
File without changes
|
{mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/client/data_sources_interfaces/duckdb.py
RENAMED
|
File without changes
|
|
File without changes
|
{mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/client/data_sources_interfaces/sqlite.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/compiled_sql/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/data_nodes/build_operations.py
RENAMED
|
File without changes
|
{mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/data_nodes/data_nodes.py
RENAMED
|
File without changes
|
|
File without changes
|
{mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/data_nodes/namespacing.py
RENAMED
|
File without changes
|
{mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/data_nodes/persist_managers.py
RENAMED
|
File without changes
|
{mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/data_nodes/run_operations.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-6.0.22 → mainsequence-6.0.24}/mainsequence/meta_tables/sqlalchemy_contracts.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-6.0.22 → mainsequence-6.0.24}/tests/test_data_node_storage_dimension_queries.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|