runnable 0.17.1__tar.gz → 0.19.0__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {runnable-0.17.1 → runnable-0.19.0}/PKG-INFO +1 -7
- runnable-0.19.0/extensions/catalog/pyproject.toml +14 -0
- {runnable-0.17.1 → runnable-0.19.0}/extensions/job_executor/k8s.py +148 -26
- runnable-0.19.0/extensions/job_executor/pyproject.toml +16 -0
- runnable-0.19.0/extensions/nodes/pyproject.toml +15 -0
- {runnable-0.17.1 → runnable-0.19.0}/extensions/pipeline_executor/local_container.py +0 -1
- runnable-0.19.0/extensions/pipeline_executor/pyproject.toml +16 -0
- runnable-0.19.0/extensions/run_log_store/pyproject.toml +15 -0
- runnable-0.19.0/extensions/secrets/pyproject.toml +15 -0
- {runnable-0.17.1 → runnable-0.19.0}/pyproject.toml +26 -15
- {runnable-0.17.1 → runnable-0.19.0}/runnable/__init__.py +1 -0
- {runnable-0.17.1 → runnable-0.19.0}/runnable/catalog.py +1 -2
- {runnable-0.17.1 → runnable-0.19.0}/runnable/entrypoints.py +1 -5
- {runnable-0.17.1 → runnable-0.19.0}/runnable/executor.py +1 -1
- {runnable-0.17.1 → runnable-0.19.0}/runnable/parameters.py +0 -9
- {runnable-0.17.1 → runnable-0.19.0}/runnable/utils.py +5 -25
- runnable-0.17.1/.dockerignore +0 -10
- runnable-0.17.1/.github/workflows/docs.yaml +0 -18
- runnable-0.17.1/.github/workflows/pr.yaml +0 -53
- runnable-0.17.1/.github/workflows/release.yaml +0 -101
- runnable-0.17.1/.mypy.ini +0 -48
- runnable-0.17.1/.pre-commit-config.yaml +0 -34
- runnable-0.17.1/.python-version +0 -1
- runnable-0.17.1/CHANGELOG.md +0 -1897
- runnable-0.17.1/Dockerfile +0 -22
- runnable-0.17.1/docs/assets/cropped.png +0 -0
- runnable-0.17.1/docs/assets/screenshots/argo-expose-parameters.png +0 -0
- runnable-0.17.1/docs/assets/screenshots/argo-kubeflow-exec.png +0 -0
- runnable-0.17.1/docs/assets/screenshots/argo-kubeflow-ui.png +0 -0
- runnable-0.17.1/docs/assets/screenshots/argo-nested.png +0 -0
- runnable-0.17.1/docs/assets/screenshots/argo-parallel-map.png +0 -0
- runnable-0.17.1/docs/assets/screenshots/argo-sequential-map.png +0 -0
- runnable-0.17.1/docs/assets/screenshots/argo-workflows-gant.png +0 -0
- runnable-0.17.1/docs/assets/screenshots/argo-workflows-logs.png +0 -0
- runnable-0.17.1/docs/assets/screenshots/mlflow.png +0 -0
- runnable-0.17.1/docs/assets/screenshots/mlflow_example.png +0 -0
- runnable-0.17.1/docs/assets/screenshots/mlflow_step.png +0 -0
- runnable-0.17.1/docs/assets/screenshots/notebook_api_parameters.png +0 -0
- runnable-0.17.1/docs/assets/screenshots/notebook_env_parameters.png +0 -0
- runnable-0.17.1/docs/assets/screenshots/notebook_input_parameters.png +0 -0
- runnable-0.17.1/docs/assets/screenshots/notebook_native_parameters.png +0 -0
- runnable-0.17.1/docs/assets/screenshots/simple_notebook.png +0 -0
- runnable-0.17.1/docs/assets/speed.png +0 -0
- runnable-0.17.1/docs/assets/sport.png +0 -0
- runnable-0.17.1/docs/assets/work_dark.png +0 -0
- runnable-0.17.1/docs/assets/work_light.png +0 -0
- runnable-0.17.1/docs/concepts/catalog.md +0 -87
- runnable-0.17.1/docs/concepts/index.md +0 -55
- runnable-0.17.1/docs/concepts/map.md +0 -227
- runnable-0.17.1/docs/concepts/nesting.md +0 -1354
- runnable-0.17.1/docs/concepts/parallel.md +0 -134
- runnable-0.17.1/docs/concepts/parameters.md +0 -255
- runnable-0.17.1/docs/concepts/pipeline.md +0 -176
- runnable-0.17.1/docs/concepts/run-log.md +0 -144
- runnable-0.17.1/docs/concepts/secrets.md +0 -69
- runnable-0.17.1/docs/concepts/task.md +0 -146
- runnable-0.17.1/docs/configurations/catalog.md +0 -279
- runnable-0.17.1/docs/configurations/executors/argo.md +0 -1650
- runnable-0.17.1/docs/configurations/executors/container-environments.md +0 -71
- runnable-0.17.1/docs/configurations/executors/local-container.md +0 -352
- runnable-0.17.1/docs/configurations/executors/local.md +0 -17
- runnable-0.17.1/docs/configurations/executors/mocked.md +0 -1015
- runnable-0.17.1/docs/configurations/overview.md +0 -80
- runnable-0.17.1/docs/configurations/run-log.md +0 -427
- runnable-0.17.1/docs/configurations/secrets.md +0 -140
- runnable-0.17.1/docs/css/extra.css +0 -3
- runnable-0.17.1/docs/index.md +0 -190
- runnable-0.17.1/docs/iterative.md +0 -44
- runnable-0.17.1/docs/reference.md +0 -146
- runnable-0.17.1/docs/tutorial/overview.md +0 -0
- runnable-0.17.1/docs/tutorial/script-based.md +0 -0
- runnable-0.17.1/docs/tutorial/single-notebook.md +0 -0
- runnable-0.17.1/docs/tutorial/switching-configs.md +0 -0
- runnable-0.17.1/docs/tutorial/using-parallel.md +0 -0
- runnable-0.17.1/docs/tutorial/wrap-up.md +0 -0
- runnable-0.17.1/docs/usage.md +0 -56
- runnable-0.17.1/docs/why-runnable.md +0 -104
- runnable-0.17.1/examples/01-tasks/notebook.py +0 -44
- runnable-0.17.1/examples/01-tasks/notebook.yaml +0 -31
- runnable-0.17.1/examples/01-tasks/python_tasks.py +0 -43
- runnable-0.17.1/examples/01-tasks/python_tasks.yaml +0 -23
- runnable-0.17.1/examples/01-tasks/scripts.py +0 -37
- runnable-0.17.1/examples/01-tasks/scripts.yaml +0 -20
- runnable-0.17.1/examples/01-tasks/stub.py +0 -42
- runnable-0.17.1/examples/01-tasks/stub.yaml +0 -29
- runnable-0.17.1/examples/02-sequential/default_fail.py +0 -36
- runnable-0.17.1/examples/02-sequential/default_fail.yaml +0 -23
- runnable-0.17.1/examples/02-sequential/on_failure_fail.py +0 -43
- runnable-0.17.1/examples/02-sequential/on_failure_fail.yaml +0 -34
- runnable-0.17.1/examples/02-sequential/on_failure_succeed.py +0 -44
- runnable-0.17.1/examples/02-sequential/on_failure_succeed.yaml +0 -34
- runnable-0.17.1/examples/02-sequential/traversal.py +0 -65
- runnable-0.17.1/examples/02-sequential/traversal.yaml +0 -46
- runnable-0.17.1/examples/03-parameters/passing_parameters_notebook.py +0 -59
- runnable-0.17.1/examples/03-parameters/passing_parameters_notebook.yaml +0 -38
- runnable-0.17.1/examples/03-parameters/passing_parameters_python.py +0 -55
- runnable-0.17.1/examples/03-parameters/passing_parameters_python.yaml +0 -38
- runnable-0.17.1/examples/03-parameters/passing_parameters_shell.py +0 -73
- runnable-0.17.1/examples/03-parameters/passing_parameters_shell.yaml +0 -51
- runnable-0.17.1/examples/03-parameters/static_parameters_non_python.py +0 -61
- runnable-0.17.1/examples/03-parameters/static_parameters_non_python.yaml +0 -46
- runnable-0.17.1/examples/03-parameters/static_parameters_python.py +0 -77
- runnable-0.17.1/examples/03-parameters/static_parameters_python.yaml +0 -33
- runnable-0.17.1/examples/04-catalog/catalog.py +0 -131
- runnable-0.17.1/examples/04-catalog/catalog.yaml +0 -115
- runnable-0.17.1/examples/06-parallel/nesting.py +0 -87
- runnable-0.17.1/examples/06-parallel/nesting.yaml +0 -50
- runnable-0.17.1/examples/06-parallel/parallel.py +0 -66
- runnable-0.17.1/examples/06-parallel/parallel.yaml +0 -45
- runnable-0.17.1/examples/07-map/custom_reducer.py +0 -129
- runnable-0.17.1/examples/07-map/custom_reducer.yaml +0 -73
- runnable-0.17.1/examples/07-map/map.py +0 -133
- runnable-0.17.1/examples/07-map/map.yaml +0 -74
- runnable-0.17.1/examples/08-mocking/default.yaml +0 -13
- runnable-0.17.1/examples/08-mocking/patching.yaml +0 -19
- runnable-0.17.1/examples/09-retry/config.yaml +0 -4
- runnable-0.17.1/examples/09-retry/python_tasks.py +0 -60
- runnable-0.17.1/examples/09-retry/python_tasks.yaml +0 -33
- runnable-0.17.1/examples/11-jobs/catalog.py +0 -23
- runnable-0.17.1/examples/11-jobs/catalog.yaml +0 -5
- runnable-0.17.1/examples/11-jobs/k8s-job.yaml +0 -41
- runnable-0.17.1/examples/11-jobs/local-container.yaml +0 -4
- runnable-0.17.1/examples/11-jobs/notebook.yaml +0 -3
- runnable-0.17.1/examples/11-jobs/passing_parameters_python.py +0 -47
- runnable-0.17.1/examples/11-jobs/python_parameters.yaml +0 -11
- runnable-0.17.1/examples/11-jobs/python_tasks.py +0 -44
- runnable-0.17.1/examples/11-jobs/python_tasks.yaml +0 -2
- runnable-0.17.1/examples/11-jobs/scripts.yaml +0 -20
- runnable-0.17.1/examples/Dockerfile.39 +0 -31
- runnable-0.17.1/examples/README.md +0 -93
- runnable-0.17.1/examples/common/functions.py +0 -166
- runnable-0.17.1/examples/common/initial_parameters.yaml +0 -8
- runnable-0.17.1/examples/common/process_chunk.ipynb +0 -70
- runnable-0.17.1/examples/common/read_files.ipynb +0 -43
- runnable-0.17.1/examples/common/read_parameters.ipynb +0 -69
- runnable-0.17.1/examples/common/simple_notebook.ipynb +0 -46
- runnable-0.17.1/examples/common/simple_notebook_mocked.ipynb +0 -46
- runnable-0.17.1/examples/common/write_parameters.ipynb +0 -68
- runnable-0.17.1/examples/comparisons/README.md +0 -174
- runnable-0.17.1/examples/comparisons/kedro/README.md +0 -1
- runnable-0.17.1/examples/comparisons/kfp/README.md +0 -1
- runnable-0.17.1/examples/comparisons/metaflow/main.py +0 -135
- runnable-0.17.1/examples/comparisons/metaflow/parameters.json +0 -46
- runnable-0.17.1/examples/comparisons/runnable/main.py +0 -291
- runnable-0.17.1/examples/comparisons/runnable/runnable_params.yaml +0 -41
- runnable-0.17.1/examples/comparisons/source.py +0 -202
- runnable-0.17.1/examples/configs/argo-config-full.yaml +0 -50
- runnable-0.17.1/examples/configs/argo-config.yaml +0 -18
- runnable-0.17.1/examples/configs/chunked-fs-run_log.yaml +0 -2
- runnable-0.17.1/examples/configs/default.yaml +0 -11
- runnable-0.17.1/examples/configs/dotenv.yaml +0 -4
- runnable-0.17.1/examples/configs/in-memory.yaml +0 -14
- runnable-0.17.1/examples/configs/local-container.yaml +0 -7
- runnable-0.17.1/examples/configs/mocked-config-debug.yaml +0 -12
- runnable-0.17.1/examples/configs/mocked-config-simple.yaml +0 -8
- runnable-0.17.1/examples/configs/mocked-config-unittest.yaml +0 -12
- runnable-0.17.1/examples/configs/mocked-config.yaml +0 -12
- runnable-0.17.1/examples/configs/mocked_map_parameters.yaml +0 -7
- runnable-0.17.1/examples/configs/retry-config.yaml +0 -10
- runnable-0.17.1/examples/executors/argo-map-sequential.yaml +0 -42
- runnable-0.17.1/examples/executors/local-container-override.yaml +0 -23
- runnable-0.17.1/examples/executors/step_overrides_container.py +0 -53
- runnable-0.17.1/examples/executors/step_overrides_container.yaml +0 -35
- runnable-0.17.1/examples/generated-argo-pipeline.yaml +0 -175
- runnable-0.17.1/examples/iris_demo.py +0 -102
- runnable-0.17.1/examples/tutorials/mnist/baseline_comparison.py +0 -312
- runnable-0.17.1/examples/tutorials/mnist/hyper_parameter_tuning.py +0 -206
- runnable-0.17.1/examples/tutorials/mnist/modular_source.py +0 -171
- runnable-0.17.1/examples/tutorials/mnist/parameters.yaml +0 -36
- runnable-0.17.1/examples/tutorials/mnist/parameters_source.py +0 -173
- runnable-0.17.1/examples/tutorials/mnist/source.py +0 -80
- runnable-0.17.1/examples/tutorials/reddit_text_classification/parameters.yaml +0 -9
- runnable-0.17.1/examples/tutorials/reddit_text_classification/pipeline.py +0 -60
- runnable-0.17.1/examples/tutorials/reddit_text_classification/steps.py +0 -131
- runnable-0.17.1/extensions/catalog/pyproject.toml +0 -7
- runnable-0.17.1/extensions/job_executor/pyproject.toml +0 -7
- runnable-0.17.1/extensions/nodes/pyproject.toml +0 -7
- runnable-0.17.1/extensions/pipeline_executor/pyproject.toml +0 -7
- runnable-0.17.1/extensions/run_log_store/pyproject.toml +0 -7
- runnable-0.17.1/extensions/secrets/__init__.py +0 -0
- runnable-0.17.1/extensions/secrets/pyproject.toml +0 -7
- runnable-0.17.1/mkdocs.yml +0 -140
- runnable-0.17.1/tests/__init__.py +0 -0
- runnable-0.17.1/tests/conftest.py +0 -11
- runnable-0.17.1/tests/extensions/__init__.py +0 -0
- runnable-0.17.1/tests/extensions/catalog/test_catalog_extension.py +0 -52
- runnable-0.17.1/tests/extensions/catalog/test_file_system.py +0 -312
- runnable-0.17.1/tests/extensions/pipeline_executor/test_argo_executor.py +0 -138
- runnable-0.17.1/tests/extensions/pipeline_executor/test_generic_executor.py +0 -558
- runnable-0.17.1/tests/extensions/pipeline_executor/test_local_executor.py +0 -14
- runnable-0.17.1/tests/extensions/run_log_store/__init__.py +0 -0
- runnable-0.17.1/tests/extensions/run_log_store/test_file_system.py +0 -155
- runnable-0.17.1/tests/extensions/secrets/test_dotenv.py +0 -17
- runnable-0.17.1/tests/extensions/test_node_extensions.py +0 -265
- runnable-0.17.1/tests/runnable/test_catalog.py +0 -61
- runnable-0.17.1/tests/runnable/test_datastore.py +0 -551
- runnable-0.17.1/tests/runnable/test_executor.py +0 -30
- runnable-0.17.1/tests/runnable/test_graph.py +0 -451
- runnable-0.17.1/tests/runnable/test_nodes.py +0 -439
- runnable-0.17.1/tests/runnable/test_parmeters.py +0 -131
- runnable-0.17.1/tests/runnable/test_sdk.py +0 -37
- runnable-0.17.1/tests/runnable/test_secrets.py +0 -33
- runnable-0.17.1/tests/runnable/test_utils.py +0 -453
- runnable-0.17.1/tests/test_examples.py +0 -210
- runnable-0.17.1/tox.ini +0 -19
- runnable-0.17.1/uv.lock +0 -2441
- {runnable-0.17.1 → runnable-0.19.0}/.gitignore +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/LICENSE +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/README.md +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/extensions/README.md +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/extensions/__init__.py +0 -0
- /runnable-0.17.1/CONTRIBUTING.md → /runnable-0.19.0/extensions/catalog/README.md +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/extensions/catalog/file_system.py +0 -0
- /runnable-0.17.1/docs/architecture/yaml.md → /runnable-0.19.0/extensions/job_executor/README.md +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/extensions/job_executor/__init__.py +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/extensions/job_executor/k8s_job_spec.yaml +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/extensions/job_executor/local.py +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/extensions/job_executor/local_container.py +0 -0
- /runnable-0.17.1/docs/configurations/executors/retry.md → /runnable-0.19.0/extensions/nodes/README.md +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/extensions/nodes/nodes.py +0 -0
- /runnable-0.17.1/docs/tutorial/dynamic-looping.md → /runnable-0.19.0/extensions/pipeline_executor/README.md +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/extensions/pipeline_executor/__init__.py +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/extensions/pipeline_executor/argo.py +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/extensions/pipeline_executor/argo_specification.yaml +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/extensions/pipeline_executor/local.py +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/extensions/pipeline_executor/mocked.py +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/extensions/pipeline_executor/retry.py +0 -0
- /runnable-0.17.1/docs/tutorial/modular-dags.md → /runnable-0.19.0/extensions/run_log_store/README.md +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/extensions/run_log_store/__init__.py +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/extensions/run_log_store/chunked_fs.py +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/extensions/run_log_store/db/implementation_FF.py +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/extensions/run_log_store/db/integration_FF.py +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/extensions/run_log_store/file_system.py +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/extensions/run_log_store/generic_chunked.py +0 -0
- /runnable-0.17.1/docs/tutorial/modular-notebooks.md → /runnable-0.19.0/extensions/secrets/README.md +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/extensions/secrets/dotenv.py +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/runnable/cli.py +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/runnable/context.py +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/runnable/datastore.py +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/runnable/defaults.py +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/runnable/exceptions.py +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/runnable/graph.py +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/runnable/names.py +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/runnable/nodes.py +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/runnable/pickler.py +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/runnable/sdk.py +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/runnable/secrets.py +0 -0
- {runnable-0.17.1 → runnable-0.19.0}/runnable/tasks.py +0 -0
@@ -1,23 +1,17 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: runnable
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.19.0
|
4
4
|
Summary: Add your description here
|
5
5
|
Author-email: "Vammi, Vijay" <vijay.vammi@astrazeneca.com>
|
6
6
|
License-File: LICENSE
|
7
7
|
Requires-Python: >=3.10
|
8
|
-
Requires-Dist: catalog
|
9
8
|
Requires-Dist: click-plugins>=1.1.1
|
10
9
|
Requires-Dist: click<=8.1.3
|
11
10
|
Requires-Dist: dill>=0.3.9
|
12
|
-
Requires-Dist: job-executor
|
13
|
-
Requires-Dist: nodes
|
14
|
-
Requires-Dist: pipeline-executor
|
15
11
|
Requires-Dist: pydantic>=2.10.3
|
16
12
|
Requires-Dist: python-dotenv>=1.0.1
|
17
13
|
Requires-Dist: rich>=13.9.4
|
18
14
|
Requires-Dist: ruamel-yaml>=0.18.6
|
19
|
-
Requires-Dist: run-log-store
|
20
|
-
Requires-Dist: secrets
|
21
15
|
Requires-Dist: setuptools>=75.6.0
|
22
16
|
Requires-Dist: stevedore>=5.4.0
|
23
17
|
Requires-Dist: typer>=0.15.1
|
@@ -0,0 +1,14 @@
|
|
1
|
+
[project]
|
2
|
+
name = "catalog"
|
3
|
+
version = "0.0.0"
|
4
|
+
description = "Add your description here"
|
5
|
+
readme = "README.md"
|
6
|
+
requires-python = ">=3.10"
|
7
|
+
dependencies = []
|
8
|
+
|
9
|
+
[build-system]
|
10
|
+
requires = ["hatchling"]
|
11
|
+
build-backend = "hatchling.build"
|
12
|
+
|
13
|
+
[tool.hatch.build.targets.wheel]
|
14
|
+
packages = ["."]
|
@@ -101,23 +101,40 @@ class HostPath(BaseModel):
|
|
101
101
|
path: str
|
102
102
|
|
103
103
|
|
104
|
-
class
|
104
|
+
class HostPathVolume(BaseModel):
|
105
105
|
name: str
|
106
106
|
host_path: HostPath
|
107
107
|
|
108
108
|
|
109
|
-
class
|
109
|
+
class PVCClaim(BaseModel):
|
110
|
+
claim_name: str
|
111
|
+
|
112
|
+
model_config = ConfigDict(
|
113
|
+
alias_generator=to_camel,
|
114
|
+
populate_by_name=True,
|
115
|
+
from_attributes=True,
|
116
|
+
)
|
117
|
+
|
118
|
+
|
119
|
+
class PVCVolume(BaseModel):
|
120
|
+
name: str
|
121
|
+
persistent_volume_claim: PVCClaim
|
122
|
+
|
123
|
+
|
124
|
+
class K8sTemplateSpec(BaseModel):
|
110
125
|
active_deadline_seconds: int = Field(default=60 * 60 * 2) # 2 hours
|
111
126
|
node_selector: Optional[dict[str, str]] = None
|
112
127
|
tolerations: Optional[list[dict[str, str]]] = None
|
113
|
-
volumes: Optional[list[
|
128
|
+
volumes: Optional[list[HostPathVolume | PVCVolume]] = Field(
|
129
|
+
default_factory=lambda: []
|
130
|
+
)
|
114
131
|
service_account_name: Optional[str] = "default"
|
115
132
|
restart_policy: RestartPolicy = RestartPolicy.NEVER
|
116
133
|
container: Container
|
117
134
|
|
118
135
|
|
119
|
-
class
|
120
|
-
spec:
|
136
|
+
class K8sTemplate(BaseModel):
|
137
|
+
spec: K8sTemplateSpec
|
121
138
|
metadata: Optional[ObjectMetaData] = None
|
122
139
|
|
123
140
|
|
@@ -125,32 +142,25 @@ class Spec(BaseModel):
|
|
125
142
|
active_deadline_seconds: Optional[int] = Field(default=60 * 60 * 2) # 2 hours
|
126
143
|
backoff_limit: int = 6
|
127
144
|
selector: Optional[LabelSelector] = None
|
128
|
-
template:
|
145
|
+
template: K8sTemplate
|
129
146
|
ttl_seconds_after_finished: Optional[int] = Field(default=60 * 60 * 24) # 24 hours
|
130
147
|
|
131
148
|
|
132
|
-
class
|
149
|
+
class GenericK8sJobExecutor(GenericJobExecutor):
|
133
150
|
service_name: str = "k8s-job"
|
134
151
|
config_path: Optional[str] = None
|
135
152
|
job_spec: Spec
|
136
153
|
mock: bool = False
|
137
|
-
|
138
|
-
# The location the mount of .run_log_store is mounted to in minikube
|
139
|
-
# ensure that minikube mount $HOME/workspace/runnable/.run_log_store:/volume/run_logs is executed first
|
140
|
-
# $HOME/workspace/runnable/.catalog:/volume/catalog
|
141
|
-
# Ensure that the docker build is done with eval $(minikube docker-env)
|
142
|
-
mini_k8s_run_log_location: str = Field(default="/volume/run_logs/")
|
143
|
-
mini_k8s_catalog_location: str = Field(default="/volume/catalog/")
|
154
|
+
namespace: str = Field(default="default")
|
144
155
|
|
145
156
|
_is_local: bool = PrivateAttr(default=False)
|
157
|
+
_volume_mounts: list[VolumeMount] = PrivateAttr(default_factory=lambda: [])
|
158
|
+
_volumes: list[HostPathVolume | PVCVolume] = PrivateAttr(default_factory=lambda: [])
|
146
159
|
|
147
160
|
_container_log_location: str = PrivateAttr(default="/tmp/run_logs/")
|
148
161
|
_container_catalog_location: str = PrivateAttr(default="/tmp/catalog/")
|
149
162
|
_container_secrets_location: str = PrivateAttr(default="/tmp/dotenv")
|
150
163
|
|
151
|
-
_volumes: list[Volume] = []
|
152
|
-
_volume_mounts: list[VolumeMount] = []
|
153
|
-
|
154
164
|
model_config = ConfigDict(
|
155
165
|
alias_generator=to_camel,
|
156
166
|
populate_by_name=True,
|
@@ -287,14 +297,17 @@ class K8sJobExecutor(GenericJobExecutor):
|
|
287
297
|
)
|
288
298
|
|
289
299
|
logger.info(f"Submitting job: {job.__dict__}")
|
300
|
+
if self.mock:
|
301
|
+
print(job.__dict__)
|
302
|
+
return
|
290
303
|
|
291
304
|
try:
|
292
305
|
k8s_batch = self._client.BatchV1Api()
|
293
306
|
response = k8s_batch.create_namespaced_job(
|
294
307
|
body=job,
|
295
|
-
namespace="default",
|
296
308
|
_preload_content=False,
|
297
309
|
pretty=True,
|
310
|
+
namespace=self.namespace,
|
298
311
|
)
|
299
312
|
logger.debug(f"Kubernetes job response: {response}")
|
300
313
|
except Exception as e:
|
@@ -302,6 +315,43 @@ class K8sJobExecutor(GenericJobExecutor):
|
|
302
315
|
print(e)
|
303
316
|
raise
|
304
317
|
|
318
|
+
def _create_volumes(self): ...
|
319
|
+
|
320
|
+
def _use_volumes(self):
|
321
|
+
match self._context.run_log_store.service_name:
|
322
|
+
case "file-system":
|
323
|
+
self._context.run_log_store.log_folder = self._container_log_location
|
324
|
+
case "chunked-fs":
|
325
|
+
self._context.run_log_store.log_folder = self._container_log_location
|
326
|
+
|
327
|
+
match self._context.catalog_handler.service_name:
|
328
|
+
case "file-system":
|
329
|
+
self._context.catalog_handler.catalog_location = (
|
330
|
+
self._container_catalog_location
|
331
|
+
)
|
332
|
+
|
333
|
+
|
334
|
+
class MiniK8sJobExecutor(GenericK8sJobExecutor):
|
335
|
+
service_name: str = "k8s-job"
|
336
|
+
config_path: Optional[str] = None
|
337
|
+
job_spec: Spec
|
338
|
+
mock: bool = False
|
339
|
+
|
340
|
+
# The location the mount of .run_log_store is mounted to in minikube
|
341
|
+
# ensure that minikube mount $HOME/workspace/runnable/.run_log_store:/volume/run_logs is executed first
|
342
|
+
# $HOME/workspace/runnable/.catalog:/volume/catalog
|
343
|
+
# Ensure that the docker build is done with eval $(minikube docker-env)
|
344
|
+
mini_k8s_run_log_location: str = Field(default="/volume/run_logs/")
|
345
|
+
mini_k8s_catalog_location: str = Field(default="/volume/catalog/")
|
346
|
+
|
347
|
+
_is_local: bool = PrivateAttr(default=False)
|
348
|
+
|
349
|
+
model_config = ConfigDict(
|
350
|
+
alias_generator=to_camel,
|
351
|
+
populate_by_name=True,
|
352
|
+
from_attributes=True,
|
353
|
+
)
|
354
|
+
|
305
355
|
def _create_volumes(self):
|
306
356
|
match self._context.run_log_store.service_name:
|
307
357
|
case "file-system":
|
@@ -311,7 +361,7 @@ class K8sJobExecutor(GenericJobExecutor):
|
|
311
361
|
# You then are creating a volume that is mounted to /tmp/run_logs in the container
|
312
362
|
# You are then referring to it.
|
313
363
|
# https://stackoverflow.com/questions/57411456/minikube-mounted-host-folders-are-not-working
|
314
|
-
|
364
|
+
HostPathVolume(
|
315
365
|
name="run-logs",
|
316
366
|
host_path=HostPath(path=self.mini_k8s_run_log_location),
|
317
367
|
)
|
@@ -323,7 +373,7 @@ class K8sJobExecutor(GenericJobExecutor):
|
|
323
373
|
)
|
324
374
|
case "chunked-fs":
|
325
375
|
self._volumes.append(
|
326
|
-
|
376
|
+
HostPathVolume(
|
327
377
|
name="run-logs",
|
328
378
|
host_path=HostPath(path=self.mini_k8s_run_log_location),
|
329
379
|
)
|
@@ -337,7 +387,7 @@ class K8sJobExecutor(GenericJobExecutor):
|
|
337
387
|
match self._context.catalog_handler.service_name:
|
338
388
|
case "file-system":
|
339
389
|
self._volumes.append(
|
340
|
-
|
390
|
+
HostPathVolume(
|
341
391
|
name="catalog",
|
342
392
|
host_path=HostPath(path=self.mini_k8s_catalog_location),
|
343
393
|
)
|
@@ -348,15 +398,87 @@ class K8sJobExecutor(GenericJobExecutor):
|
|
348
398
|
)
|
349
399
|
)
|
350
400
|
|
351
|
-
|
401
|
+
|
402
|
+
class K8sJobExecutor(GenericK8sJobExecutor):
|
403
|
+
service_name: str = "k8s-job"
|
404
|
+
config_path: Optional[str] = None
|
405
|
+
job_spec: Spec
|
406
|
+
mock: bool = False
|
407
|
+
pvc_claim_name: str
|
408
|
+
|
409
|
+
# change the spec to pull image if not present
|
410
|
+
def model_post_init(self, __context):
|
411
|
+
self.job_spec.template.spec.container.image_pull_policy = ImagePullPolicy.ALWAYS
|
412
|
+
|
413
|
+
_is_local: bool = PrivateAttr(default=False)
|
414
|
+
|
415
|
+
model_config = ConfigDict(
|
416
|
+
alias_generator=to_camel,
|
417
|
+
populate_by_name=True,
|
418
|
+
from_attributes=True,
|
419
|
+
)
|
420
|
+
|
421
|
+
def execute_job(self, job: BaseTaskType, catalog_settings=Optional[List[str]]):
|
422
|
+
self._use_volumes()
|
423
|
+
self._set_up_run_log()
|
424
|
+
|
425
|
+
job_log = self._context.run_log_store.create_job_log()
|
426
|
+
self._context.run_log_store.add_job_log(
|
427
|
+
run_id=self._context.run_id, job_log=job_log
|
428
|
+
)
|
429
|
+
|
430
|
+
job_log = self._context.run_log_store.get_job_log(run_id=self._context.run_id)
|
431
|
+
|
432
|
+
attempt_log = job.execute_command(
|
433
|
+
attempt_number=self.step_attempt_number,
|
434
|
+
mock=self.mock,
|
435
|
+
)
|
436
|
+
|
437
|
+
job_log.status = attempt_log.status
|
438
|
+
job_log.attempts.append(attempt_log)
|
439
|
+
|
440
|
+
data_catalogs_put: Optional[List[DataCatalog]] = self._sync_catalog(
|
441
|
+
catalog_settings=catalog_settings
|
442
|
+
)
|
443
|
+
logger.debug(f"data_catalogs_put: {data_catalogs_put}")
|
444
|
+
|
445
|
+
job_log.add_data_catalogs(data_catalogs_put or [])
|
446
|
+
|
447
|
+
console.print("Summary of job")
|
448
|
+
console.print(job_log.get_summary())
|
449
|
+
|
450
|
+
self._context.run_log_store.add_job_log(
|
451
|
+
run_id=self._context.run_id, job_log=job_log
|
452
|
+
)
|
453
|
+
|
454
|
+
def _create_volumes(self):
|
455
|
+
self._volumes.append(
|
456
|
+
PVCVolume(
|
457
|
+
name=self.pvc_claim_name,
|
458
|
+
persistent_volume_claim=PVCClaim(claim_name=self.pvc_claim_name),
|
459
|
+
)
|
460
|
+
)
|
352
461
|
match self._context.run_log_store.service_name:
|
353
462
|
case "file-system":
|
354
|
-
self.
|
463
|
+
self._volume_mounts.append(
|
464
|
+
VolumeMount(
|
465
|
+
name=self.pvc_claim_name,
|
466
|
+
mount_path=self._container_log_location,
|
467
|
+
)
|
468
|
+
)
|
355
469
|
case "chunked-fs":
|
356
|
-
self.
|
470
|
+
self._volume_mounts.append(
|
471
|
+
VolumeMount(
|
472
|
+
name=self.pvc_claim_name,
|
473
|
+
mount_path=self._container_log_location,
|
474
|
+
)
|
475
|
+
)
|
357
476
|
|
358
477
|
match self._context.catalog_handler.service_name:
|
359
478
|
case "file-system":
|
360
|
-
self.
|
361
|
-
|
479
|
+
self._volume_mounts.append(
|
480
|
+
VolumeMount(
|
481
|
+
name=self.pvc_claim_name,
|
482
|
+
mount_path=self._container_catalog_location,
|
483
|
+
)
|
362
484
|
)
|
@@ -0,0 +1,16 @@
|
|
1
|
+
[project]
|
2
|
+
name = "job_executor"
|
3
|
+
version = "0.0.0"
|
4
|
+
description = "Add your description here"
|
5
|
+
readme = "README.md"
|
6
|
+
requires-python = ">=3.10"
|
7
|
+
dependencies = []
|
8
|
+
|
9
|
+
|
10
|
+
[build-system]
|
11
|
+
requires = ["hatchling"]
|
12
|
+
build-backend = "hatchling.build"
|
13
|
+
|
14
|
+
|
15
|
+
[tool.hatch.build.targets.wheel]
|
16
|
+
packages = ["."]
|
@@ -0,0 +1,15 @@
|
|
1
|
+
[project]
|
2
|
+
name = "nodes"
|
3
|
+
version = "0.0.0"
|
4
|
+
description = "Add your description here"
|
5
|
+
readme = "README.md"
|
6
|
+
requires-python = ">=3.10"
|
7
|
+
dependencies = []
|
8
|
+
|
9
|
+
|
10
|
+
[build-system]
|
11
|
+
requires = ["hatchling"]
|
12
|
+
build-backend = "hatchling.build"
|
13
|
+
|
14
|
+
[tool.hatch.build.targets.wheel]
|
15
|
+
packages = ["."]
|
@@ -268,7 +268,6 @@ class LocalContainerExecutor(GenericPipelineExecutor):
|
|
268
268
|
f"Please provide a docker_image using executor_config of the step {node.name} or at global config"
|
269
269
|
)
|
270
270
|
|
271
|
-
# TODO: Should consider using getpass.getuser() when running the docker container? Volume permissions
|
272
271
|
container = client.containers.create(
|
273
272
|
image=docker_image,
|
274
273
|
command=command,
|
@@ -0,0 +1,16 @@
|
|
1
|
+
[project]
|
2
|
+
name = "pipeline_executor"
|
3
|
+
version = "0.0.0"
|
4
|
+
description = "Add your description here"
|
5
|
+
readme = "README.md"
|
6
|
+
requires-python = ">=3.10"
|
7
|
+
dependencies = []
|
8
|
+
|
9
|
+
|
10
|
+
[build-system]
|
11
|
+
requires = ["hatchling"]
|
12
|
+
build-backend = "hatchling.build"
|
13
|
+
|
14
|
+
|
15
|
+
[tool.hatch.build.targets.wheel]
|
16
|
+
packages = ["."]
|
@@ -0,0 +1,15 @@
|
|
1
|
+
[project]
|
2
|
+
name = "run_log_store"
|
3
|
+
version = "0.0.0"
|
4
|
+
description = "Extensions to run log store"
|
5
|
+
readme = "README.md"
|
6
|
+
requires-python = ">=3.10"
|
7
|
+
dependencies = []
|
8
|
+
|
9
|
+
|
10
|
+
[build-system]
|
11
|
+
requires = ["hatchling"]
|
12
|
+
build-backend = "hatchling.build"
|
13
|
+
|
14
|
+
[tool.hatch.build.targets.wheel]
|
15
|
+
packages = ["."]
|
@@ -0,0 +1,15 @@
|
|
1
|
+
[project]
|
2
|
+
name = "secrets"
|
3
|
+
version = "0.0.0"
|
4
|
+
description = "Extension to manage secrets"
|
5
|
+
readme = "README.md"
|
6
|
+
requires-python = ">=3.10"
|
7
|
+
dependencies = []
|
8
|
+
|
9
|
+
|
10
|
+
[build-system]
|
11
|
+
requires = ["hatchling"]
|
12
|
+
build-backend = "hatchling.build"
|
13
|
+
|
14
|
+
[tool.hatch.build.targets.wheel]
|
15
|
+
packages = ["."]
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[project]
|
2
2
|
name = "runnable"
|
3
|
-
version = "0.
|
3
|
+
version = "0.19.0"
|
4
4
|
description = "Add your description here"
|
5
5
|
readme = "README.md"
|
6
6
|
authors = [
|
@@ -18,17 +18,8 @@ dependencies = [
|
|
18
18
|
"setuptools>=75.6.0",
|
19
19
|
"python-dotenv>=1.0.1",
|
20
20
|
"typer>=0.15.1",
|
21
|
-
"nodes",
|
22
|
-
"secrets",
|
23
|
-
"catalog",
|
24
|
-
"run_log_store",
|
25
|
-
"pipeline_executor",
|
26
|
-
"job_executor",
|
27
21
|
]
|
28
22
|
|
29
|
-
[project.scripts]
|
30
|
-
runnable = 'runnable.cli:app'
|
31
|
-
|
32
23
|
[project.optional-dependencies]
|
33
24
|
docker = [
|
34
25
|
"docker>=7.1.0",
|
@@ -43,10 +34,6 @@ k8s = [
|
|
43
34
|
"kubernetes>=31.0.0",
|
44
35
|
]
|
45
36
|
|
46
|
-
[build-system]
|
47
|
-
requires = ["hatchling"]
|
48
|
-
build-backend = "hatchling.build"
|
49
|
-
|
50
37
|
[dependency-groups]
|
51
38
|
dev = [
|
52
39
|
"pytest-cov>=6.0.0",
|
@@ -68,7 +55,13 @@ release = [
|
|
68
55
|
]
|
69
56
|
|
70
57
|
[tool.uv.workspace]
|
71
|
-
members = ["extensions
|
58
|
+
members = ["extensions/catalog",
|
59
|
+
"extensions/job_executor",
|
60
|
+
"extensions/nodes",
|
61
|
+
"extensions/pipeline_executor",
|
62
|
+
"extensions/run_log_store",
|
63
|
+
"extensions/secrets",
|
64
|
+
]
|
72
65
|
|
73
66
|
[tool.uv.sources]
|
74
67
|
nodes = {workspace = true}
|
@@ -79,6 +72,22 @@ pipeline_executor = {workspace = true}
|
|
79
72
|
job_executor = {workspace = true}
|
80
73
|
|
81
74
|
|
75
|
+
[project.scripts]
|
76
|
+
runnable = 'runnable.cli:app'
|
77
|
+
|
78
|
+
[build-system]
|
79
|
+
requires = ["hatchling"]
|
80
|
+
build-backend = "hatchling.build"
|
81
|
+
|
82
|
+
[tool.hatch.build]
|
83
|
+
ignore-vcs = true
|
84
|
+
include = [
|
85
|
+
"/runnable",
|
86
|
+
"/extensions",
|
87
|
+
]
|
88
|
+
|
89
|
+
|
90
|
+
# Plugin systems
|
82
91
|
[project.entry-points.'pipeline_executor']
|
83
92
|
"local" = "extensions.pipeline_executor.local:LocalExecutor"
|
84
93
|
"local-container" = "extensions.pipeline_executor.local_container:LocalContainerExecutor"
|
@@ -89,6 +98,7 @@ job_executor = {workspace = true}
|
|
89
98
|
[project.entry-points.'job_executor']
|
90
99
|
"local" = "extensions.job_executor.local:LocalJobExecutor"
|
91
100
|
"local-container" = "extensions.job_executor.local_container:LocalContainerJobExecutor"
|
101
|
+
"mini-k8s-job" = "extensions.job_executor.k8s:MiniK8sJobExecutor"
|
92
102
|
"k8s-job" = "extensions.job_executor.k8s:K8sJobExecutor"
|
93
103
|
# "argo" = "extensions.pipeline_executor.argo:ArgoExecutor"
|
94
104
|
# "mocked" = "extensions.pipeline_executor.mocked:MockedExecutor"
|
@@ -127,6 +137,7 @@ file-system = "extensions.run_log_store.file_system:FileSystemRunLogstore"
|
|
127
137
|
"notebook" = "runnable.tasks:NotebookTaskType"
|
128
138
|
|
129
139
|
|
140
|
+
# Release configuration
|
130
141
|
[tool.semantic_release]
|
131
142
|
commit_parser = "angular"
|
132
143
|
major_on_zero = true
|
@@ -10,8 +10,6 @@ from runnable.datastore import DataCatalog
|
|
10
10
|
|
11
11
|
logger = logging.getLogger(defaults.LOGGER_NAME)
|
12
12
|
|
13
|
-
# TODO: Should ** be allowed as glob pattern as it can potentially copy everything to catalog
|
14
|
-
|
15
13
|
|
16
14
|
def is_catalog_out_of_sync(
|
17
15
|
catalog, synced_catalogs=Optional[List[DataCatalog]]
|
@@ -170,3 +168,4 @@ class DoNothingCatalog(BaseCatalog):
|
|
170
168
|
Does nothing
|
171
169
|
"""
|
172
170
|
logger.info("Using a do-nothing catalog, doing nothing while sync between runs")
|
171
|
+
logger.info("Using a do-nothing catalog, doing nothing while sync between runs")
|
@@ -16,9 +16,6 @@ from runnable.executor import BaseJobExecutor, BasePipelineExecutor
|
|
16
16
|
logger = logging.getLogger(defaults.LOGGER_NAME)
|
17
17
|
|
18
18
|
|
19
|
-
print("") # removes the buffer print
|
20
|
-
|
21
|
-
|
22
19
|
def get_default_configs() -> RunnableConfig:
|
23
20
|
"""
|
24
21
|
User can provide extensions as part of their code base, runnable-config.yaml provides the place to put them.
|
@@ -128,11 +125,10 @@ def prepare_configurations(
|
|
128
125
|
"job-executor", None
|
129
126
|
) # type: ignore
|
130
127
|
if not job_executor_config:
|
131
|
-
|
128
|
+
job_executor_config = cast(
|
132
129
|
ServiceConfig,
|
133
130
|
runnable_defaults.get("job-executor", defaults.DEFAULT_JOB_EXECUTOR),
|
134
131
|
)
|
135
|
-
|
136
132
|
assert job_executor_config, "Job executor is not provided"
|
137
133
|
configured_executor = utils.get_provider_by_name_and_type(
|
138
134
|
"job_executor", job_executor_config
|
@@ -11,9 +11,9 @@ import runnable.context as context
|
|
11
11
|
from runnable import defaults
|
12
12
|
from runnable.datastore import DataCatalog, JobLog, StepLog
|
13
13
|
from runnable.defaults import TypeMapVariable
|
14
|
-
from runnable.graph import Graph
|
15
14
|
|
16
15
|
if TYPE_CHECKING: # pragma: no cover
|
16
|
+
from runnable.graph import Graph
|
17
17
|
from runnable.nodes import BaseNode
|
18
18
|
from runnable.tasks import BaseTaskType
|
19
19
|
|
@@ -15,8 +15,6 @@ from runnable.utils import remove_prefix
|
|
15
15
|
|
16
16
|
logger = logging.getLogger(defaults.LOGGER_NAME)
|
17
17
|
|
18
|
-
# TODO: Revisit this, it might be a bit too complicated than required
|
19
|
-
|
20
18
|
|
21
19
|
def get_user_set_parameters(remove: bool = False) -> Dict[str, JsonParameter]:
|
22
20
|
"""
|
@@ -50,13 +48,6 @@ def get_user_set_parameters(remove: bool = False) -> Dict[str, JsonParameter]:
|
|
50
48
|
return parameters
|
51
49
|
|
52
50
|
|
53
|
-
def serialize_parameter_as_str(value: Any) -> str:
|
54
|
-
if isinstance(value, BaseModel):
|
55
|
-
return json.dumps(value.model_dump())
|
56
|
-
|
57
|
-
return json.dumps(value)
|
58
|
-
|
59
|
-
|
60
51
|
def filter_arguments_for_func(
|
61
52
|
func: Callable[..., Any],
|
62
53
|
params: Dict[str, Any],
|
@@ -17,7 +17,7 @@ from ruamel.yaml import YAML
|
|
17
17
|
from stevedore import driver
|
18
18
|
|
19
19
|
import runnable.context as context
|
20
|
-
from runnable import defaults, names
|
20
|
+
from runnable import console, defaults, names
|
21
21
|
from runnable.defaults import TypeMapVariable
|
22
22
|
|
23
23
|
if TYPE_CHECKING: # pragma: no cover
|
@@ -176,7 +176,7 @@ def is_a_git_repo() -> bool:
|
|
176
176
|
logger.info("Found the code to be git versioned")
|
177
177
|
return True
|
178
178
|
except BaseException: # pylint: disable=W0702
|
179
|
-
|
179
|
+
console.print("Not a git repo", style="bold red")
|
180
180
|
|
181
181
|
return False
|
182
182
|
|
@@ -195,27 +195,7 @@ def get_current_code_commit() -> Union[str, None]:
|
|
195
195
|
logger.info("Found the git commit to be: %s", label)
|
196
196
|
return label
|
197
197
|
except BaseException: # pylint: disable=W0702
|
198
|
-
|
199
|
-
raise
|
200
|
-
|
201
|
-
|
202
|
-
def archive_git_tracked(name: str):
|
203
|
-
"""Generate a git archive of the tracked files.
|
204
|
-
|
205
|
-
Args:
|
206
|
-
name (str): The name to give the archive
|
207
|
-
|
208
|
-
Raises:
|
209
|
-
Exception: If its not a git repo
|
210
|
-
"""
|
211
|
-
command = f"git archive -v -o {name}.tar.gz --format=tar.gz HEAD"
|
212
|
-
|
213
|
-
if not is_a_git_repo():
|
214
|
-
raise Exception("Not a git repo")
|
215
|
-
try:
|
216
|
-
subprocess.check_output(command.split()).strip().decode("utf-8")
|
217
|
-
except BaseException: # pylint: disable=W0702
|
218
|
-
logger.exception("Error archiving repo")
|
198
|
+
console.print("Not a git repo, error getting hash", style="bold red")
|
219
199
|
raise
|
220
200
|
|
221
201
|
|
@@ -234,7 +214,7 @@ def is_git_clean() -> Tuple[bool, Union[None, str]]:
|
|
234
214
|
return True, None
|
235
215
|
return False, label
|
236
216
|
except BaseException: # pylint: disable=W0702
|
237
|
-
|
217
|
+
console.print("Not a git repo, not clean", style="bold red")
|
238
218
|
|
239
219
|
return False, None
|
240
220
|
|
@@ -253,7 +233,7 @@ def get_git_remote() -> Union[str, None]:
|
|
253
233
|
logger.info("Found the git remote to be: %s", label)
|
254
234
|
return label
|
255
235
|
except BaseException: # pylint: disable=W0702
|
256
|
-
|
236
|
+
console.print("Not a git repo, no remote", style="bold red")
|
257
237
|
raise
|
258
238
|
|
259
239
|
|
runnable-0.17.1/.dockerignore
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
name: docs
|
2
|
-
on:
|
3
|
-
push:
|
4
|
-
branches:
|
5
|
-
- main
|
6
|
-
|
7
|
-
jobs:
|
8
|
-
deploy:
|
9
|
-
runs-on: ubuntu-latest
|
10
|
-
steps:
|
11
|
-
- uses: actions/checkout@v2
|
12
|
-
- name: Install uv
|
13
|
-
run: curl -LsSf https://astral.sh/uv/install.sh | sh
|
14
|
-
- name: "Set up Python"
|
15
|
-
run: uv python install
|
16
|
-
- run: |
|
17
|
-
uv sync --only-group docs
|
18
|
-
uv run mkdocs gh-deploy --force
|