mainsequence 8.1.21__tar.gz → 8.1.22.dev21__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.
Files changed (144) hide show
  1. {mainsequence-8.1.21/mainsequence.egg-info → mainsequence-8.1.22.dev21}/PKG-INFO +1 -1
  2. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/agent_scaffold/skills/application_surfaces/api_surfaces/SKILL.md +10 -10
  3. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/agent_scaffold/skills/platform_operations/orchestration_and_releases/SKILL.md +34 -100
  4. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/cli/api.py +0 -368
  5. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/cli/cli.py +0 -1227
  6. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/client/base.py +5 -0
  7. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/client/models_foundry.py +3 -71
  8. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/client/models_helpers.py +4 -544
  9. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21/mainsequence.egg-info}/PKG-INFO +1 -1
  10. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/pyproject.toml +1 -1
  11. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_cli.py +9 -1024
  12. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_code_repository_batch_jobs_from_file.py +1 -18
  13. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_filter_normalization.py +23 -309
  14. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_tolerant_value_sets.py +1 -26
  15. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/LICENSE +0 -0
  16. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/MANIFEST.in +0 -0
  17. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/README.md +0 -0
  18. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/agent_scaffold/AGENTS.md +0 -0
  19. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/agent_scaffold/skills/a2a_sdk_execution/SKILL.md +0 -0
  20. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/agent_scaffold/skills/data_access/exploration/SKILL.md +0 -0
  21. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/agent_scaffold/skills/data_publishing/meta_table_migrations/SKILL.md +0 -0
  22. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/agent_scaffold/skills/data_publishing/meta_tables/SKILL.md +0 -0
  23. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/agent_scaffold/skills/data_publishing/time_index_table_updates/SKILL.md +0 -0
  24. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md +0 -0
  25. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/agent_scaffold/skills/maintenance/code_repository_maintenance/SKILL.md +0 -0
  26. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/agent_scaffold/skills/platform_operations/access_control_and_sharing/SKILL.md +0 -0
  27. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/agent_scaffold/skills/sdk_code_repository_execution/SKILL.md +0 -0
  28. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/__init__.py +0 -0
  29. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/__main__.py +0 -0
  30. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/bootstrap.py +0 -0
  31. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/cli/__init__.py +0 -0
  32. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/cli/browser_auth.py +0 -0
  33. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/cli/code_repository_status.py +0 -0
  34. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/cli/config.py +0 -0
  35. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/cli/docker_utils.py +0 -0
  36. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/cli/doctor.py +0 -0
  37. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/cli/local_ops.py +0 -0
  38. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/cli/migrations.py +0 -0
  39. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/cli/model_filters.py +0 -0
  40. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/cli/pydantic_cli.py +0 -0
  41. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/cli/sdk_utils.py +0 -0
  42. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/cli/ssh_utils.py +0 -0
  43. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/cli/ui.py +0 -0
  44. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/client/__init__.py +0 -0
  45. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/client/agent_runtime_models.py +0 -0
  46. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/client/client.py +0 -0
  47. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/client/compute_validation.py +0 -0
  48. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/client/data_sources_interfaces/__init__.py +0 -0
  49. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/client/data_sources_interfaces/duckdb.py +0 -0
  50. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/client/data_sources_interfaces/local_paths.py +0 -0
  51. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/client/data_sources_interfaces/sqlite.py +0 -0
  52. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/client/dtype_codec.py +0 -0
  53. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/client/exceptions.py +0 -0
  54. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/client/github_issues.py +0 -0
  55. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/client/metatables/__init__.py +0 -0
  56. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/client/metatables/core.py +0 -0
  57. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/client/models_user.py +0 -0
  58. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/client/observability.py +0 -0
  59. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/client/utils.py +0 -0
  60. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/client/value_sets.py +0 -0
  61. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/code_repository_context.py +0 -0
  62. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/code_repository_skills.py +0 -0
  63. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/defaults.py +0 -0
  64. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/instrumentation/__init__.py +0 -0
  65. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/instrumentation/utils.py +0 -0
  66. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/logconf.py +0 -0
  67. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/meta_tables/__init__.py +0 -0
  68. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/meta_tables/__main__.py +0 -0
  69. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/meta_tables/compiled_sql/__init__.py +0 -0
  70. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/meta_tables/compiled_sql/v1.py +0 -0
  71. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/meta_tables/future_registry.py +0 -0
  72. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/meta_tables/hashing.py +0 -0
  73. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/meta_tables/migrations/__init__.py +0 -0
  74. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/meta_tables/migrations/alembic.py +0 -0
  75. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/meta_tables/migrations/env.py +0 -0
  76. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/meta_tables/migrations/provider.py +0 -0
  77. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/meta_tables/migrations/registry.py +0 -0
  78. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/meta_tables/migrations/scaffold.py +0 -0
  79. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/meta_tables/migrations/templates/__init__.py +0 -0
  80. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/meta_tables/migrations/templates/env.py.mako +0 -0
  81. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/meta_tables/migrations/templates/script.py.mako +0 -0
  82. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/meta_tables/pydantic_metadata.py +0 -0
  83. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/meta_tables/schema_names.py +0 -0
  84. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/meta_tables/sqlalchemy_contracts.py +0 -0
  85. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/meta_tables/time_index_table_refs.py +0 -0
  86. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/meta_tables/time_index_table_updates/__init__.py +0 -0
  87. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/meta_tables/time_index_table_updates/configuration.py +0 -0
  88. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/meta_tables/time_index_table_updates/dependencies.py +0 -0
  89. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/meta_tables/time_index_table_updates/managers.py +0 -0
  90. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/meta_tables/time_index_table_updates/namespacing.py +0 -0
  91. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/meta_tables/time_index_table_updates/runner.py +0 -0
  92. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/meta_tables/time_index_table_updates/updaters.py +0 -0
  93. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/meta_tables/time_index_table_updates/utils.py +0 -0
  94. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/repository_identity_security.py +0 -0
  95. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/runtime_flags.py +0 -0
  96. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence/scaffold_skills.py +0 -0
  97. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence.egg-info/SOURCES.txt +0 -0
  98. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence.egg-info/dependency_links.txt +0 -0
  99. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence.egg-info/entry_points.txt +0 -0
  100. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence.egg-info/requires.txt +0 -0
  101. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/mainsequence.egg-info/top_level.txt +0 -0
  102. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/setup.cfg +0 -0
  103. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/fixtures/time_index_table_update_hash_v2_golden.json +0 -0
  104. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_auth_precedence.py +0 -0
  105. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_canonical_api_route_contract.py +0 -0
  106. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_cli_browser_auth.py +0 -0
  107. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_cli_migrations.py +0 -0
  108. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_client.py +0 -0
  109. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_code_repository_branch_contract.py +0 -0
  110. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_code_repository_documentation_contract.py +0 -0
  111. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_code_repository_runtime_context.py +0 -0
  112. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_code_repository_skills.py +0 -0
  113. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_dependency_extras.py +0 -0
  114. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_dev_release_version.py +0 -0
  115. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_duckdb_interface_dimensions.py +0 -0
  116. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_environment_resource_context.py +0 -0
  117. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_environment_response_contracts.py +0 -0
  118. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_github_issues_client.py +0 -0
  119. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_instrumentation.py +0 -0
  120. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_local_ops.py +0 -0
  121. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_logconf.py +0 -0
  122. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_meta_table_migrations.py +0 -0
  123. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_meta_tables_client_models.py +0 -0
  124. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_meta_tables_sqlalchemy_contracts.py +0 -0
  125. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_models_user_request_bound_auth.py +0 -0
  126. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_notification_uid_contract.py +0 -0
  127. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_observability_client.py +0 -0
  128. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_pod_project_resolution.py +0 -0
  129. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_scaffold_skills.py +0 -0
  130. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_schema_names.py +0 -0
  131. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_secret_client_model.py +0 -0
  132. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_source_table_configuration.py +0 -0
  133. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_sqlite_interface_dimensions.py +0 -0
  134. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_ssh_utils.py +0 -0
  135. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_time_index_table_access_dimension_audit.py +0 -0
  136. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_time_index_table_dimension_queries.py +0 -0
  137. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_time_index_table_update_configuration.py +0 -0
  138. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_time_index_table_update_configuration_client.py +0 -0
  139. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_time_index_table_update_flow.py +0 -0
  140. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_time_index_table_update_hard_cut.py +0 -0
  141. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_tolerant_response_reading.py +0 -0
  142. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_update_runner_uid_runtime.py +0 -0
  143. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_update_statistics.py +0 -0
  144. {mainsequence-8.1.21 → mainsequence-8.1.22.dev21}/tests/test_update_uid_guards.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mainsequence
3
- Version: 8.1.21
3
+ Version: 8.1.22.dev21
4
4
  Summary: Main Sequence SDK
5
5
  Author-email: Main Sequence GmbH <dev@main-sequence.io>
6
6
  License-Expression: LicenseRef-MainSequence-Proprietary
@@ -187,27 +187,27 @@ Before release, verify local CodeRepository resolution:
187
187
  mainsequence code-repository current --debug --json
188
188
  ```
189
189
 
190
- Then move the tested code through the canonical lifecycle:
190
+ Declare the FastAPI resource in `.mainsequence/workflows/`, validate the
191
+ workflow against the backend template, then move the tested commit through the
192
+ canonical lifecycle:
191
193
 
192
194
  ```bash
193
195
  mainsequence code-repository sync -m "Release Command Center API"
194
- mainsequence code-repository images create
195
196
  mainsequence code-repository resources list --filter resource_type=fastapi
196
- mainsequence code-repository resources create_fastapi
197
197
  ```
198
198
 
199
199
  Verify that:
200
200
 
201
201
  - code-repository sync used the intended Git branch
202
- - the selected image contains the exact tested commit
203
- - resource discovery found the expected FastAPI path at that commit
204
- - the selected resource UID and image UID refer to the same commit
205
- - the created release kind is `fastapi`
202
+ - the workflow declaration identifies the tested FastAPI source path
203
+ - resource discovery found that path at the exact deployed commit
204
+ - Django resolved and built the exact image for the workflow event
205
+ - the resulting release kind is `fastapi`
206
206
  - compute and spot settings are intentional
207
207
 
208
- Use `--automatic-deployment` only after the route paths, resource path, and
209
- frontend contracts are stable and the release should follow future repository
210
- syncs. Otherwise keep the release pinned and create deliberate replacements.
208
+ Enable automatic deployment in the repository workflow when the route paths,
209
+ resource path, and frontend contracts are stable enough for future repository
210
+ events to promote exact images.
211
211
 
212
212
  ### 6. Verify the deployed API
213
213
 
@@ -21,17 +21,11 @@ This skill is for:
21
21
 
22
22
  ## This Skill Can Do
23
23
 
24
- - create or review manual jobs
25
- - create or review scheduled jobs
26
- - author backend-managed declarations under `.mainsequence/workflows/`
27
- - validate workflow files through the CodeRepositoryBranch workflow endpoints
28
- - create or select code repository images
29
- - bind every job to one exact code repository image
30
- - configure standalone Job automatic deployment as future exact-image promotion
31
- - inspect job runs and logs
32
- - reason about code repository resources and resource releases
33
- - decide whether a `ResourceRelease` should opt into `automatic_deployment`
34
- - inspect automatic deployment run state for release rotations
24
+ - author and validate Job, FastAPI, and Static Site workflow declarations
25
+ - inspect exact CodeRepository images, Jobs, ResourceReleases, and deployment runs
26
+ - run an existing Job manually and inspect logs
27
+ - update supported properties on an existing Job or release
28
+ - reason about automatic deployment and repository-event image promotion
35
29
  - review Artifact-based workflows in operational pipelines
36
30
 
37
31
  ## This Skill Must Not Claim
@@ -68,41 +62,19 @@ changing the operational workflow.
68
62
 
69
63
  ## Inputs This Skill Needs
70
64
 
71
- Before changing orchestration or release behavior, collect or infer:
72
-
73
- - the execution target:
74
- - `execution_path`
75
- - app entrypoint
76
- - whether the job is:
77
- - manual
78
- - interval
79
- - crontab
80
- - one-off
81
- - the image strategy:
82
- - existing image
83
- - new image
84
- - whether the workflow is:
85
- - direct CLI/client job creation
86
- - backend-managed code-repository workflow declarations
87
- - whether a `ResourceRelease` should be manually pinned or opted into repository-sync automatic deployment
88
- - whether Artifact inputs or outputs are part of the run
89
- - who owns the exact initial image: the caller for manual pinning or the
90
- backend for automatic deployment
91
- - whether future qualifying immutable repository events may promote a standalone Job
92
-
93
- If the execution target or image strategy is unclear, stop before scheduling anything.
65
+ Identify the repository source path or Job execution path, the product kind,
66
+ schedule and compute intent, and whether future qualifying repository events
67
+ should promote the target. For an existing target, obtain its public UID before
68
+ running or updating it. The repository workflow is the creation input; callers
69
+ do not select image, resource, Job, or release UIDs for creation.
94
70
 
95
71
  ## Required Decisions
96
72
 
97
- For every non-trivial orchestration task, decide:
98
-
99
- 1. Is this a one-off/manual workflow or a repository-managed recurring workflow?
100
- 2. Should the jobs live in a `.mainsequence/workflows/*.yaml` declaration?
101
- 3. Is the Job manually pinned to a caller-selected exact ready image, or does
102
- automatic deployment make the backend derive it from the synchronized commit?
103
- 4. Does the workflow depend on Artifacts?
104
- 5. Is the task actually a release/resource problem instead of only a job problem?
105
- 6. For a `ResourceRelease`, should repository sync be allowed to rotate the release automatically through `automatic_deployment`?
73
+ 1. Which repository workflow declaration owns the target?
74
+ 2. Is the Job manual, interval, crontab, or one-off?
75
+ 3. Should future exact repository events promote its image automatically?
76
+ 4. Are Artifacts inputs or outputs of the run?
77
+ 5. Which existing Job or release needs observation or an explicit operation?
106
78
 
107
79
  ## Build Rules
108
80
 
@@ -129,38 +101,11 @@ Do not hide important recurring schedules in ad hoc shell history or one-off man
129
101
 
130
102
  ### 2. Every Job requires one exact image
131
103
 
132
- Every persisted direct Job has one exact code repository image, but the creation mode
133
- determines who supplies it.
134
-
135
- Remember:
136
-
137
- - images are built from pushed commits
138
- - if a commit is not on the remote, it cannot be used for an image
139
- - there is no dynamic, blank-image, branch-tip, or `latest` Job mode
140
- - a manual Job requires the caller to select `related_image_uid`
141
- - an automatic Job forbids caller image selection; the backend derives the
142
- exact initial image from the CodeRepositoryBranch's persisted synchronized commit
143
-
144
- When standalone Job automatic deployment is enabled during creation, the
145
- backend prepares the exact initial image and later qualifying immutable
146
- repository events may atomically promote another exact image. On an existing
147
- Job, enabling or disabling it retains the current exact image. The backend owns
148
- repository-event truth, policy evaluation, image preparation, and promotion;
149
- CodeRepository code and the SDK must not choose a Job's deployment branch or image.
150
- This deployment-policy rule does not replace ADR-0037 runtime source discovery:
151
- code executing inside the resulting code repository image still resolves and validates
152
- its attached Git branch and exact commit.
153
-
154
- For direct creation use:
155
-
156
- - `--automatic-deployment` to permit future exact-image promotion
157
- - `--no-automatic-deployment` to keep future repository events from changing
158
- the Job image
159
- - `--automatic-redeployment-tag-regex` to require a full matching immutable
160
- tag; omit the regex for every otherwise-eligible exact event
161
-
162
- Use `--related-image-uid` only for manual pinning. Omit it with
163
- `--automatic-deployment`; passing both is invalid.
104
+ Django derives the initial image from the exact repository event when it
105
+ applies a `kind: job` workflow declaration. A later qualifying event may
106
+ promote another exact image under the Job's automatic deployment policy.
107
+ There is no dynamic, blank-image, branch-tip, or `latest` execution mode.
108
+ A caller does not create an image or Job by selecting a stored image UID.
164
109
 
165
110
  ### 3. Jobs must be verifiable after creation
166
111
 
@@ -201,7 +146,7 @@ Current support matrix:
201
146
  | `Job.run_job(command_args=[...])` | Supported for that manual run |
202
147
  | `mainsequence code-repository jobs run ... --arg/-- ...` | Supported for that manual run |
203
148
  | `Job.scheduled_command_args` | Persisted list copied into future scheduler-created runs |
204
- | `mainsequence code-repository jobs create/update --scheduled-arg ...` | Creates or replaces the persisted scheduled list |
149
+ | `mainsequence code-repository jobs update --scheduled-arg ...` | Replaces the persisted list on an existing Job |
205
150
  | `.mainsequence/workflows/*.yaml` Job declaration | Supports `scheduled_command_args` as an ordered `list[str]` |
206
151
 
207
152
  Keep `scheduled_command_args` separate from manual `command_args`. Retrieve the
@@ -298,36 +243,27 @@ Enable `automatic_deployment` only when:
298
243
 
299
244
  Keep `automatic_deployment` disabled when:
300
245
 
301
- - the release must stay pinned to a manually selected image or resource version
246
+ - the release should not promote on future repository events
302
247
  - each release rotation needs human approval
303
248
  - the resource path or entrypoint is still moving
304
249
  - API or widget contracts are not stable enough for automatic rotation
305
250
  - the current branch/CodeRepository sync target is not the intended deployment source
306
251
 
307
- Create opted-in releases with the CLI flags that exist:
308
-
309
- - `mainsequence code-repository resources create_fastapi --automatic-deployment`
310
- - use `--no-automatic-deployment` when the decision is explicitly to keep the release pinned/manual
311
-
312
- The SDK surface also accepts:
313
-
314
- - `CodeRepositoryResource.create_fastapi(..., automatic_deployment=True)`
315
- - `ResourceRelease.create(..., automatic_deployment=True)`
316
- - `ResourceRelease.deploy_current_version()` for an SDK-triggered manual deployment run; it returns `DeploymentRun`
317
- - `DeploymentRun.filter(target_type="resource_release", target_uid=release.uid)` to inspect runs for one release
252
+ Declare opted-in releases in the repository workflow and validate the file
253
+ against the backend template. Repository events create deployment runs.
254
+ `DeploymentRun.filter(target_type="resource_release", target_uid=release.uid)`
255
+ inspects runs for an existing release.
318
256
 
319
257
  Every release also exposes its immutable revision lifecycle:
320
258
 
321
259
  - `desired_revision` is the public UID of the accepted revision being materialized
322
260
  - `active_revision` is the public UID of the ready revision currently serving behind the stable release URL
323
261
  - the two UIDs may differ while a deployment is running or after a deployment fails
324
- - `revision_retention_count` is the positive release-owned retention setting; omission on create uses the backend default
325
- - configure retention with `ResourceRelease.create(..., revision_retention_count=3)` or `release.patch(revision_retention_count=5)`
262
+ - `revision_retention_count` is the positive release-owned retention setting; omission in the workflow uses the backend default
263
+ - configure retention in the workflow or update an existing release with `release.patch(revision_retention_count=5)`
326
264
 
327
265
  Treat `active_revision` and `desired_revision` as read-only public identities. Do not substitute provider revision names, deployment names, or internal database IDs.
328
266
 
329
- 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.
330
-
331
267
  Inspect the unified run's `state`, `phase`, `outcome`, `steps`, `logs`, and `error` fields. Do not use legacy resource-release deployment status fields or filters.
332
268
  Detail responses also expose `builder_image` and `builder_runtime`; these are empty strings when the run has no static-site builder metadata.
333
269
 
@@ -336,11 +272,9 @@ Detail responses also expose `builder_image` and `builder_runtime`; these are em
336
272
  When reviewing an orchestration task, look for:
337
273
 
338
274
  - schedules that should have been version-controlled
339
- - direct job creation where a batch file should exist
340
- - missing or wrong `related_image_uid`
341
- - jobs tied to moving repository state instead of a pinned image
342
- - manual Job creation that omits an exact ready image
343
- - automatic Job creation that supplies a caller-selected image
275
+ - a missing repository workflow declaration for a new Job
276
+ - a workflow with a caller-selected image or generated platform UID
277
+ - jobs tied to moving repository state instead of an exact image
344
278
  - client code that interprets automatic deployment as a branch-tip or `latest` selector
345
279
  - no run/log verification after creation
346
280
  - unsafe use of `--strict`
@@ -360,9 +294,9 @@ Do not claim success until you have checked:
360
294
  - interval
361
295
  - crontab
362
296
  - one-off
363
- - manual image selection or backend-owned automatic image preparation is intentional
297
+ - the exact repository event and backend-owned image preparation are intentional
364
298
  - standalone Job automatic deployment and tag policy are intentionally enabled or disabled
365
- - the job exists after direct creation or repository workflow application
299
+ - the Job exists after repository workflow application
366
300
  - runs and logs were inspected when execution success matters
367
301
  - resources and releases were verified when deployment success matters
368
302
  - `automatic_deployment` is intentionally enabled or disabled on each release
@@ -386,7 +320,7 @@ If the workflow uses Artifacts, also check:
386
320
  - the execution target is unclear
387
321
  - the image strategy is unclear but reproducibility matters
388
322
  - the backend rejects the workflow version, resource kind, or requested field
389
- - a manually pinned Job has no exact ready initial image
323
+ - a Job workflow cannot resolve an exact source image
390
324
  - an automatically deployed Job has no persisted synchronized CodeRepositoryBranch commit
391
325
  - the workflow depends on local file paths that should be platform Artifacts
392
326
  - automatic deployment is requested but the deployment source branch/current synced CodeRepository version is unclear
@@ -2171,117 +2171,6 @@ def get_code_repository_time_index_table_updates(
2171
2171
  os.environ[k] = v
2172
2172
 
2173
2173
 
2174
- def create_code_repository_image(
2175
- *,
2176
- code_repository_commit_hash: str,
2177
- related_code_repository_branch_uid: str,
2178
- base_image_uid: str | None = None,
2179
- timeout: int | None = None,
2180
- ) -> dict[str, Any]:
2181
- """
2182
- Create a code repository image via SDK client model.
2183
-
2184
- Single source of truth:
2185
- - delegates payload construction and request behavior to `CodeRepositoryImage.create()`
2186
- - avoids duplicating the endpoint contract in the CLI API wrapper
2187
- """
2188
- tokens = get_tokens()
2189
- access = (tokens.get("access") or "").strip()
2190
- refresh = (tokens.get("refresh") or "").strip()
2191
- if not access:
2192
- raise NotLoggedIn("Not logged in.")
2193
-
2194
- endpoint = backend_url().rstrip("/")
2195
- root_url = f"{endpoint}/api/v1"
2196
-
2197
- old_env = {
2198
- "MAINSEQUENCE_AUTH_MODE": os.environ.get("MAINSEQUENCE_AUTH_MODE"),
2199
- "MAINSEQUENCE_ACCESS_TOKEN": os.environ.get("MAINSEQUENCE_ACCESS_TOKEN"),
2200
- "MAINSEQUENCE_REFRESH_TOKEN": os.environ.get("MAINSEQUENCE_REFRESH_TOKEN"),
2201
- "MAINSEQUENCE_ENDPOINT": os.environ.get("MAINSEQUENCE_ENDPOINT"),
2202
- }
2203
-
2204
- client_utils = None
2205
- old_provider = None
2206
- old_base_root_url = None
2207
- old_image_root_url = None
2208
-
2209
- try:
2210
- os.environ["MAINSEQUENCE_AUTH_MODE"] = "jwt"
2211
- os.environ["MAINSEQUENCE_ACCESS_TOKEN"] = access
2212
- if refresh:
2213
- os.environ["MAINSEQUENCE_REFRESH_TOKEN"] = refresh
2214
- else:
2215
- os.environ.pop("MAINSEQUENCE_REFRESH_TOKEN", None)
2216
- os.environ["MAINSEQUENCE_ENDPOINT"] = endpoint
2217
- resolved_branch_uid = resolve_code_repository_branch_uid(related_code_repository_branch_uid)
2218
-
2219
- from mainsequence.client import utils as _client_utils
2220
- from mainsequence.client.base import BaseObjectOrm
2221
- from mainsequence.client.models_foundry import (
2222
- CodeRepositoryImage as ClientCodeRepositoryImage,
2223
- )
2224
-
2225
- client_utils = _client_utils
2226
- old_provider = getattr(client_utils.loaders, "provider", None)
2227
- old_base_root_url = BaseObjectOrm.ROOT_URL
2228
- old_image_root_url = getattr(ClientCodeRepositoryImage, "ROOT_URL", None)
2229
-
2230
- _set_client_utils_endpoint(client_utils, endpoint)
2231
- client_utils.loaders.use_jwt(access=access, refresh=refresh or None)
2232
-
2233
- BaseObjectOrm.ROOT_URL = root_url
2234
- ClientCodeRepositoryImage.ROOT_URL = root_url
2235
-
2236
- created = ClientCodeRepositoryImage.create(
2237
- code_repository_commit_hash=code_repository_commit_hash,
2238
- related_code_repository_branch_uid=resolved_branch_uid,
2239
- base_image_uid=base_image_uid,
2240
- timeout=timeout,
2241
- )
2242
- if isinstance(created, dict):
2243
- return created
2244
- if hasattr(created, "model_dump"):
2245
- return created.model_dump()
2246
- return {"uid": getattr(created, "uid", None)}
2247
-
2248
- except Exception as e:
2249
- err_name = type(e).__name__
2250
- if err_name in {"AuthenticationError", "PermissionDeniedError"}:
2251
- raise NotLoggedIn(str(e) or "Not logged in.") from e
2252
- if err_name == "NotFoundError":
2253
- raise ApiError(
2254
- f"CodeRepositoryBranch not found: {related_code_repository_branch_uid}"
2255
- ) from e
2256
- raise ApiError(f"CodeRepository image create failed: {e}") from e
2257
- finally:
2258
- if client_utils is not None:
2259
- try:
2260
- client_utils.loaders.provider = old_provider
2261
- except Exception:
2262
- pass
2263
- if old_base_root_url is not None:
2264
- try:
2265
- from mainsequence.client.base import BaseObjectOrm
2266
-
2267
- BaseObjectOrm.ROOT_URL = old_base_root_url
2268
- except Exception:
2269
- pass
2270
- if old_image_root_url is not None:
2271
- try:
2272
- from mainsequence.client.models_foundry import (
2273
- CodeRepositoryImage as ClientCodeRepositoryImage,
2274
- )
2275
-
2276
- ClientCodeRepositoryImage.ROOT_URL = old_image_root_url
2277
- except Exception:
2278
- pass
2279
-
2280
- for k, v in old_env.items():
2281
- if v is None:
2282
- os.environ.pop(k, None)
2283
- else:
2284
- os.environ[k] = v
2285
2174
 
2286
2175
 
2287
2176
  def list_code_repository_images(
@@ -2797,135 +2686,6 @@ def list_code_repository_resources(
2797
2686
  os.environ[k] = v
2798
2687
 
2799
2688
 
2800
- def create_code_repository_resource_release(
2801
- *,
2802
- release_kind: str,
2803
- resource_uid: str,
2804
- related_image_uid: str | None = None,
2805
- cpu_request: str | int | float | None = None,
2806
- memory_request: str | int | float | None = None,
2807
- gpu_request: str | int | None = None,
2808
- gpu_type: str | None = None,
2809
- spot: bool | None = None,
2810
- automatic_deployment: bool | None = None,
2811
- timeout: int | None = None,
2812
- ) -> dict[str, Any]:
2813
- """
2814
- Create a resource release via SDK client model.
2815
-
2816
- Single source of truth:
2817
- - delegates to `CodeRepositoryResource.create_fastapi()`
2818
- - which in turn use `ResourceRelease.create()`
2819
- """
2820
- normalized_release_kind = str(release_kind).strip()
2821
- if normalized_release_kind != "fastapi":
2822
- raise ApiError("release_kind must be 'fastapi'.")
2823
-
2824
- tokens = get_tokens()
2825
- access = (tokens.get("access") or "").strip()
2826
- refresh = (tokens.get("refresh") or "").strip()
2827
- if not access:
2828
- raise NotLoggedIn("Not logged in.")
2829
-
2830
- endpoint = backend_url().rstrip("/")
2831
- root_url = f"{endpoint}/api/v1"
2832
-
2833
- old_env = {
2834
- "MAINSEQUENCE_AUTH_MODE": os.environ.get("MAINSEQUENCE_AUTH_MODE"),
2835
- "MAINSEQUENCE_ACCESS_TOKEN": os.environ.get("MAINSEQUENCE_ACCESS_TOKEN"),
2836
- "MAINSEQUENCE_REFRESH_TOKEN": os.environ.get("MAINSEQUENCE_REFRESH_TOKEN"),
2837
- "MAINSEQUENCE_ENDPOINT": os.environ.get("MAINSEQUENCE_ENDPOINT"),
2838
- }
2839
-
2840
- client_utils = None
2841
- old_provider = None
2842
- old_base_root_url = None
2843
- old_resource_root_url = None
2844
-
2845
- try:
2846
- os.environ["MAINSEQUENCE_AUTH_MODE"] = "jwt"
2847
- os.environ["MAINSEQUENCE_ACCESS_TOKEN"] = access
2848
- if refresh:
2849
- os.environ["MAINSEQUENCE_REFRESH_TOKEN"] = refresh
2850
- else:
2851
- os.environ.pop("MAINSEQUENCE_REFRESH_TOKEN", None)
2852
- os.environ["MAINSEQUENCE_ENDPOINT"] = endpoint
2853
-
2854
- from mainsequence.client import utils as _client_utils
2855
- from mainsequence.client.base import BaseObjectOrm
2856
- from mainsequence.client.models_helpers import (
2857
- CodeRepositoryResource as ClientCodeRepositoryResource,
2858
- )
2859
-
2860
- client_utils = _client_utils
2861
- old_provider = getattr(client_utils.loaders, "provider", None)
2862
- old_base_root_url = BaseObjectOrm.ROOT_URL
2863
- old_resource_root_url = getattr(ClientCodeRepositoryResource, "ROOT_URL", None)
2864
-
2865
- _set_client_utils_endpoint(client_utils, endpoint)
2866
- client_utils.loaders.use_jwt(access=access, refresh=refresh or None)
2867
-
2868
- BaseObjectOrm.ROOT_URL = root_url
2869
- ClientCodeRepositoryResource.ROOT_URL = root_url
2870
-
2871
- resource = ClientCodeRepositoryResource.get(pk=resource_uid, timeout=timeout)
2872
- create_kwargs: dict[str, Any] = {
2873
- "related_image_uid": related_image_uid,
2874
- "cpu_request": cpu_request,
2875
- "memory_request": memory_request,
2876
- "gpu_request": gpu_request,
2877
- "gpu_type": gpu_type,
2878
- "spot": spot,
2879
- "automatic_deployment": automatic_deployment,
2880
- "timeout": timeout,
2881
- }
2882
-
2883
- create_method = getattr(resource, "create_fastapi", None)
2884
- if not callable(create_method):
2885
- raise ApiError("CodeRepositoryResource does not implement create_fastapi().")
2886
- created = create_method(**create_kwargs)
2887
-
2888
- if isinstance(created, dict):
2889
- return created
2890
- if hasattr(created, "model_dump"):
2891
- return created.model_dump()
2892
- return {"uid": getattr(created, "uid", None)}
2893
-
2894
- except Exception as e:
2895
- err_name = type(e).__name__
2896
- if err_name in {"AuthenticationError", "PermissionDeniedError"}:
2897
- raise NotLoggedIn(str(e) or "Not logged in.") from e
2898
- if err_name == "NotFoundError":
2899
- raise ApiError(f"CodeRepository resource not found: {resource_uid}") from e
2900
- raise ApiError(f"CodeRepository resource release create failed: {e}") from e
2901
- finally:
2902
- if client_utils is not None:
2903
- try:
2904
- client_utils.loaders.provider = old_provider
2905
- except Exception:
2906
- pass
2907
- if old_base_root_url is not None:
2908
- try:
2909
- from mainsequence.client.base import BaseObjectOrm
2910
-
2911
- BaseObjectOrm.ROOT_URL = old_base_root_url
2912
- except Exception:
2913
- pass
2914
- if old_resource_root_url is not None:
2915
- try:
2916
- from mainsequence.client.models_helpers import (
2917
- CodeRepositoryResource as ClientCodeRepositoryResource,
2918
- )
2919
-
2920
- ClientCodeRepositoryResource.ROOT_URL = old_resource_root_url
2921
- except Exception:
2922
- pass
2923
-
2924
- for k, v in old_env.items():
2925
- if v is None:
2926
- os.environ.pop(k, None)
2927
- else:
2928
- os.environ[k] = v
2929
2689
 
2930
2690
 
2931
2691
  def list_time_index_tables(
@@ -4476,134 +4236,6 @@ def remove_meta_table_labels(
4476
4236
  )
4477
4237
 
4478
4238
 
4479
- def create_code_repository_job(
4480
- *,
4481
- name: str,
4482
- code_repository_branch_uid: str,
4483
- execution_path: str | None = None,
4484
- task_schedule: dict[str, Any] | str | None = None,
4485
- scheduled_command_args: list[str] | None = None,
4486
- cpu_request: str | int | float | None = None,
4487
- memory_request: str | int | float | None = None,
4488
- gpu_request: str | int | float | None = None,
4489
- gpu_type: str | None = None,
4490
- spot: bool | None = None,
4491
- max_runtime_seconds: int | None = None,
4492
- related_image_uid: str | None = None,
4493
- automatic_deployment: bool = False,
4494
- automatic_redeployment_tag_regex: str | None = None,
4495
- timeout: int | None = None,
4496
- ) -> dict[str, Any]:
4497
- """
4498
- Create a CodeRepository job via the SDK client model.
4499
-
4500
- Single source of truth:
4501
- - delegates payload construction and request behavior to `Job.create()`
4502
- """
4503
- tokens = get_tokens()
4504
- access = (tokens.get("access") or "").strip()
4505
- refresh = (tokens.get("refresh") or "").strip()
4506
- if not access:
4507
- raise NotLoggedIn("Not logged in.")
4508
-
4509
- endpoint = backend_url().rstrip("/")
4510
- root_url = f"{endpoint}/api/v1"
4511
-
4512
- old_env = {
4513
- "MAINSEQUENCE_AUTH_MODE": os.environ.get("MAINSEQUENCE_AUTH_MODE"),
4514
- "MAINSEQUENCE_ACCESS_TOKEN": os.environ.get("MAINSEQUENCE_ACCESS_TOKEN"),
4515
- "MAINSEQUENCE_REFRESH_TOKEN": os.environ.get("MAINSEQUENCE_REFRESH_TOKEN"),
4516
- "MAINSEQUENCE_ENDPOINT": os.environ.get("MAINSEQUENCE_ENDPOINT"),
4517
- }
4518
-
4519
- client_utils = None
4520
- old_provider = None
4521
- old_base_root_url = None
4522
- old_job_root_url = None
4523
-
4524
- try:
4525
- os.environ["MAINSEQUENCE_AUTH_MODE"] = "jwt"
4526
- os.environ["MAINSEQUENCE_ACCESS_TOKEN"] = access
4527
- if refresh:
4528
- os.environ["MAINSEQUENCE_REFRESH_TOKEN"] = refresh
4529
- else:
4530
- os.environ.pop("MAINSEQUENCE_REFRESH_TOKEN", None)
4531
- os.environ["MAINSEQUENCE_ENDPOINT"] = endpoint
4532
- resolved_branch_uid = resolve_code_repository_branch_uid(code_repository_branch_uid)
4533
-
4534
- from mainsequence.client import utils as _client_utils
4535
- from mainsequence.client.base import BaseObjectOrm
4536
- from mainsequence.client.models_helpers import Job as ClientJob
4537
-
4538
- client_utils = _client_utils
4539
- old_provider = getattr(client_utils.loaders, "provider", None)
4540
- old_base_root_url = BaseObjectOrm.ROOT_URL
4541
- old_job_root_url = getattr(ClientJob, "ROOT_URL", None)
4542
-
4543
- _set_client_utils_endpoint(client_utils, endpoint)
4544
- client_utils.loaders.use_jwt(access=access, refresh=refresh or None)
4545
-
4546
- BaseObjectOrm.ROOT_URL = root_url
4547
- ClientJob.ROOT_URL = root_url
4548
-
4549
- created = ClientJob.create(
4550
- name=name,
4551
- code_repository_branch_uid=resolved_branch_uid,
4552
- execution_path=execution_path,
4553
- task_schedule=task_schedule,
4554
- scheduled_command_args=scheduled_command_args,
4555
- cpu_request=cpu_request,
4556
- memory_request=memory_request,
4557
- gpu_request=gpu_request,
4558
- gpu_type=gpu_type,
4559
- spot=spot,
4560
- max_runtime_seconds=max_runtime_seconds,
4561
- related_image_uid=related_image_uid,
4562
- automatic_deployment=automatic_deployment,
4563
- automatic_redeployment_policy={
4564
- "tag_regex": automatic_redeployment_tag_regex,
4565
- },
4566
- timeout=timeout,
4567
- )
4568
- if isinstance(created, dict):
4569
- return created
4570
- if hasattr(created, "model_dump"):
4571
- return created.model_dump()
4572
- return {"uid": getattr(created, "uid", None)}
4573
-
4574
- except Exception as e:
4575
- err_name = type(e).__name__
4576
- if err_name in {"AuthenticationError", "PermissionDeniedError"}:
4577
- raise NotLoggedIn(str(e) or "Not logged in.") from e
4578
- if err_name == "NotFoundError":
4579
- raise ApiError(f"CodeRepositoryBranch not found: {code_repository_branch_uid}") from e
4580
- raise ApiError(f"CodeRepository job create failed: {e}") from e
4581
- finally:
4582
- if client_utils is not None:
4583
- try:
4584
- client_utils.loaders.provider = old_provider
4585
- except Exception:
4586
- pass
4587
- if old_base_root_url is not None:
4588
- try:
4589
- from mainsequence.client.base import BaseObjectOrm
4590
-
4591
- BaseObjectOrm.ROOT_URL = old_base_root_url
4592
- except Exception:
4593
- pass
4594
- if old_job_root_url is not None:
4595
- try:
4596
- from mainsequence.client.models_helpers import Job as ClientJob
4597
-
4598
- ClientJob.ROOT_URL = old_job_root_url
4599
- except Exception:
4600
- pass
4601
-
4602
- for k, v in old_env.items():
4603
- if v is None:
4604
- os.environ.pop(k, None)
4605
- else:
4606
- os.environ[k] = v
4607
4239
 
4608
4240
 
4609
4241
  def update_code_repository_job_scheduled_command_args(