modal 0.73.105__tar.gz → 0.73.107__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.
- {modal-0.73.105 → modal-0.73.107}/PKG-INFO +1 -1
- {modal-0.73.105 → modal-0.73.107}/modal/_functions.py +2 -1
- modal-0.73.107/modal/_utils/git_utils.py +72 -0
- {modal-0.73.105 → modal-0.73.107}/modal/client.pyi +2 -2
- {modal-0.73.105 → modal-0.73.107}/modal/runner.py +22 -2
- {modal-0.73.105 → modal-0.73.107}/modal/runner.pyi +1 -0
- {modal-0.73.105 → modal-0.73.107}/modal.egg-info/PKG-INFO +1 -1
- {modal-0.73.105 → modal-0.73.107}/modal.egg-info/SOURCES.txt +1 -0
- {modal-0.73.105 → modal-0.73.107}/modal_proto/api.proto +13 -0
- {modal-0.73.105 → modal-0.73.107}/modal_proto/api_pb2.py +834 -824
- {modal-0.73.105 → modal-0.73.107}/modal_proto/api_pb2.pyi +50 -2
- {modal-0.73.105 → modal-0.73.107}/modal_version/_version_generated.py +1 -1
- {modal-0.73.105 → modal-0.73.107}/LICENSE +0 -0
- {modal-0.73.105 → modal-0.73.107}/README.md +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/__init__.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/__main__.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_clustered_functions.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_clustered_functions.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_container_entrypoint.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_ipython.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_location.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_object.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_output.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_partial_function.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_proxy_tunnel.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_pty.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_resolver.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_resources.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_runtime/__init__.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_runtime/asgi.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_runtime/container_io_manager.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_runtime/container_io_manager.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_runtime/execution_context.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_runtime/execution_context.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_runtime/gpu_memory_snapshot.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_runtime/telemetry.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_runtime/user_code_imports.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_serialization.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_traceback.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_tunnel.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_tunnel.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_utils/__init__.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_utils/app_utils.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_utils/async_utils.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_utils/blob_utils.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_utils/bytes_io_segment_payload.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_utils/deprecation.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_utils/docker_utils.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_utils/function_utils.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_utils/grpc_testing.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_utils/grpc_utils.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_utils/hash_utils.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_utils/http_utils.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_utils/logger.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_utils/mount_utils.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_utils/name_utils.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_utils/package_utils.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_utils/pattern_utils.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_utils/shell_utils.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_vendor/__init__.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_vendor/cloudpickle.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_vendor/tblib.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/_watcher.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/app.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/app.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/call_graph.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/cli/__init__.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/cli/_download.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/cli/_traceback.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/cli/app.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/cli/config.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/cli/container.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/cli/dict.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/cli/entry_point.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/cli/environment.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/cli/import_refs.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/cli/launch.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/cli/network_file_system.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/cli/profile.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/cli/programs/__init__.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/cli/programs/run_jupyter.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/cli/programs/vscode.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/cli/queues.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/cli/run.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/cli/secret.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/cli/token.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/cli/utils.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/cli/volume.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/client.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/cloud_bucket_mount.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/cloud_bucket_mount.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/cls.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/cls.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/config.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/container_process.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/container_process.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/dict.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/dict.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/environments.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/environments.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/exception.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/experimental.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/experimental.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/extensions/__init__.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/extensions/ipython.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/file_io.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/file_io.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/file_pattern_matcher.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/functions.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/functions.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/gpu.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/image.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/image.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/io_streams.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/io_streams.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/mount.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/mount.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/network_file_system.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/network_file_system.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/object.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/object.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/output.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/parallel_map.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/parallel_map.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/partial_function.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/partial_function.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/proxy.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/proxy.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/py.typed +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/queue.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/queue.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/requirements/2023.12.312.txt +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/requirements/2023.12.txt +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/requirements/2024.04.txt +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/requirements/2024.10.txt +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/requirements/PREVIEW.txt +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/requirements/README.md +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/requirements/base-images.json +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/retries.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/running_app.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/sandbox.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/sandbox.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/schedule.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/scheduler_placement.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/secret.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/secret.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/serving.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/serving.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/snapshot.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/snapshot.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/stream_type.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/token_flow.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/token_flow.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/volume.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal/volume.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal.egg-info/dependency_links.txt +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal.egg-info/entry_points.txt +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal.egg-info/requires.txt +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal.egg-info/top_level.txt +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal_docs/__init__.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal_docs/gen_cli_docs.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal_docs/gen_reference_docs.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal_docs/mdmd/__init__.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal_docs/mdmd/mdmd.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal_docs/mdmd/signatures.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal_proto/__init__.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal_proto/api_grpc.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal_proto/api_pb2_grpc.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal_proto/api_pb2_grpc.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal_proto/modal_api_grpc.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal_proto/modal_options_grpc.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal_proto/options.proto +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal_proto/options_grpc.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal_proto/options_pb2.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal_proto/options_pb2.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal_proto/options_pb2_grpc.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal_proto/options_pb2_grpc.pyi +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal_proto/py.typed +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal_version/__init__.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/modal_version/__main__.py +0 -0
- {modal-0.73.105 → modal-0.73.107}/pyproject.toml +0 -0
- {modal-0.73.105 → modal-0.73.107}/setup.cfg +0 -0
@@ -245,7 +245,8 @@ class _Invocation:
|
|
245
245
|
or not ctx.retry_policy
|
246
246
|
or ctx.retry_policy.retries == 0
|
247
247
|
or ctx.function_call_invocation_type != api_pb2.FUNCTION_CALL_INVOCATION_TYPE_SYNC
|
248
|
-
|
248
|
+
# TODO: Eventually we want to honor this flag. For now, we ignore it.
|
249
|
+
# or not ctx.sync_client_retries_enabled
|
249
250
|
):
|
250
251
|
return await self._get_single_output()
|
251
252
|
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# Copyright Modal Labs 2025
|
2
|
+
import asyncio
|
3
|
+
from typing import Optional
|
4
|
+
|
5
|
+
from modal.config import logger
|
6
|
+
from modal_proto import api_pb2
|
7
|
+
|
8
|
+
|
9
|
+
async def run_command_fallible(args: list[str]) -> Optional[str]:
|
10
|
+
try:
|
11
|
+
process = await asyncio.create_subprocess_exec(
|
12
|
+
*args, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
|
13
|
+
)
|
14
|
+
stdout_bytes, _ = await process.communicate()
|
15
|
+
|
16
|
+
if process.returncode != 0:
|
17
|
+
logger.debug(f"Command {args} exited with code {process.returncode}")
|
18
|
+
return None
|
19
|
+
|
20
|
+
return stdout_bytes.decode("utf-8").strip()
|
21
|
+
|
22
|
+
except Exception as e:
|
23
|
+
logger.debug(f"Command {args} failed", exc_info=e)
|
24
|
+
return None
|
25
|
+
|
26
|
+
|
27
|
+
async def get_git_commit_info() -> Optional[api_pb2.CommitInfo]:
|
28
|
+
"""Collect git information about the current repository asynchronously."""
|
29
|
+
git_info: api_pb2.CommitInfo = api_pb2.CommitInfo(vcs="git")
|
30
|
+
|
31
|
+
commands = [
|
32
|
+
# Get commit hash, timestamp, author name, and author email
|
33
|
+
["git", "log", "-1", "--format=%H%n%ct%n%an%n%ae", "HEAD"],
|
34
|
+
# Get branch name
|
35
|
+
["git", "rev-parse", "--abbrev-ref", "HEAD"],
|
36
|
+
# Check if working directory is dirty
|
37
|
+
["git", "status", "--porcelain"],
|
38
|
+
["git", "remote", "get-url", "origin"],
|
39
|
+
]
|
40
|
+
|
41
|
+
tasks = (run_command_fallible(cmd) for cmd in commands)
|
42
|
+
(log_info, branch, status, origin_url) = await asyncio.gather(*tasks)
|
43
|
+
|
44
|
+
if not branch:
|
45
|
+
return None
|
46
|
+
|
47
|
+
git_info.branch = branch
|
48
|
+
|
49
|
+
if not log_info:
|
50
|
+
return None
|
51
|
+
|
52
|
+
info_lines = log_info.split("\n")
|
53
|
+
if len(info_lines) < 4:
|
54
|
+
# If we didn't get all expected lines, bail
|
55
|
+
logger.debug(f"Log info returned only {len(info_lines)} lines")
|
56
|
+
return None
|
57
|
+
|
58
|
+
try:
|
59
|
+
git_info.commit_hash = info_lines[0]
|
60
|
+
git_info.commit_timestamp = int(info_lines[1])
|
61
|
+
git_info.author_name = info_lines[2]
|
62
|
+
git_info.author_email = info_lines[3]
|
63
|
+
except (ValueError, IndexError):
|
64
|
+
logger.debug(f"Failed to parse git log info: {log_info}")
|
65
|
+
return None
|
66
|
+
|
67
|
+
git_info.dirty = bool(status)
|
68
|
+
|
69
|
+
if origin_url:
|
70
|
+
git_info.repo_url = origin_url
|
71
|
+
|
72
|
+
return git_info
|
@@ -31,7 +31,7 @@ class _Client:
|
|
31
31
|
server_url: str,
|
32
32
|
client_type: int,
|
33
33
|
credentials: typing.Optional[tuple[str, str]],
|
34
|
-
version: str = "0.73.
|
34
|
+
version: str = "0.73.107",
|
35
35
|
): ...
|
36
36
|
def is_closed(self) -> bool: ...
|
37
37
|
@property
|
@@ -93,7 +93,7 @@ class Client:
|
|
93
93
|
server_url: str,
|
94
94
|
client_type: int,
|
95
95
|
credentials: typing.Optional[tuple[str, str]],
|
96
|
-
version: str = "0.73.
|
96
|
+
version: str = "0.73.107",
|
97
97
|
): ...
|
98
98
|
def is_closed(self) -> bool: ...
|
99
99
|
@property
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright Modal Labs
|
1
|
+
# Copyright Modal Labs 2025
|
2
2
|
import asyncio
|
3
3
|
import dataclasses
|
4
4
|
import os
|
@@ -23,6 +23,7 @@ from ._runtime.execution_context import is_local
|
|
23
23
|
from ._traceback import print_server_warnings, traceback_contains_remote_call
|
24
24
|
from ._utils.async_utils import TaskContext, gather_cancel_on_exc, synchronize_api
|
25
25
|
from ._utils.deprecation import deprecation_error
|
26
|
+
from ._utils.git_utils import get_git_commit_info
|
26
27
|
from ._utils.grpc_utils import retry_transient_errors
|
27
28
|
from ._utils.name_utils import check_object_name, is_valid_tag
|
28
29
|
from .client import HEARTBEAT_INTERVAL, HEARTBEAT_TIMEOUT, _Client
|
@@ -182,6 +183,7 @@ async def _publish_app(
|
|
182
183
|
classes: dict[str, _Cls],
|
183
184
|
name: str = "", # Only relevant for deployments
|
184
185
|
tag: str = "", # Only relevant for deployments
|
186
|
+
commit_info: Optional[api_pb2.CommitInfo] = None, # Git commit information
|
185
187
|
) -> tuple[str, list[api_pb2.Warning]]:
|
186
188
|
"""Wrapper for AppPublish RPC."""
|
187
189
|
|
@@ -195,7 +197,9 @@ async def _publish_app(
|
|
195
197
|
function_ids=running_app.function_ids,
|
196
198
|
class_ids=running_app.class_ids,
|
197
199
|
definition_ids=definition_ids,
|
200
|
+
commit_info=commit_info,
|
198
201
|
)
|
202
|
+
|
199
203
|
try:
|
200
204
|
response = await retry_transient_errors(client.stub.AppPublish, request)
|
201
205
|
except GRPCError as exc:
|
@@ -521,6 +525,9 @@ async def _deploy_app(
|
|
521
525
|
|
522
526
|
t0 = time.time()
|
523
527
|
|
528
|
+
# Get git information to track deployment history
|
529
|
+
commit_info_task = asyncio.create_task(get_git_commit_info())
|
530
|
+
|
524
531
|
running_app: RunningApp = await _init_local_app_from_name(
|
525
532
|
client, name, namespace, environment_name=environment_name
|
526
533
|
)
|
@@ -542,8 +549,21 @@ async def _deploy_app(
|
|
542
549
|
environment_name=environment_name,
|
543
550
|
)
|
544
551
|
|
552
|
+
commit_info = None
|
553
|
+
try:
|
554
|
+
commit_info = await commit_info_task
|
555
|
+
except Exception as e:
|
556
|
+
logger.debug("Failed to get git commit info", exc_info=e)
|
557
|
+
|
545
558
|
app_url, warnings = await _publish_app(
|
546
|
-
client,
|
559
|
+
client,
|
560
|
+
running_app,
|
561
|
+
api_pb2.APP_STATE_DEPLOYED,
|
562
|
+
app._functions,
|
563
|
+
app._classes,
|
564
|
+
name,
|
565
|
+
tag,
|
566
|
+
commit_info,
|
547
567
|
)
|
548
568
|
except Exception as e:
|
549
569
|
# Note that AppClientDisconnect only stops the app if it's still initializing, and is a no-op otherwise.
|
@@ -41,6 +41,7 @@ async def _publish_app(
|
|
41
41
|
classes: dict[str, modal.cls._Cls],
|
42
42
|
name: str = "",
|
43
43
|
tag: str = "",
|
44
|
+
commit_info: typing.Optional[modal_proto.api_pb2.CommitInfo] = None,
|
44
45
|
) -> tuple[str, list[modal_proto.api_pb2.Warning]]: ...
|
45
46
|
async def _disconnect(client: modal.client._Client, app_id: str, reason: int, exc_str: str = "") -> None: ...
|
46
47
|
async def _status_based_disconnect(
|
@@ -108,6 +108,7 @@ modal/_utils/bytes_io_segment_payload.py
|
|
108
108
|
modal/_utils/deprecation.py
|
109
109
|
modal/_utils/docker_utils.py
|
110
110
|
modal/_utils/function_utils.py
|
111
|
+
modal/_utils/git_utils.py
|
111
112
|
modal/_utils/grpc_testing.py
|
112
113
|
modal/_utils/grpc_utils.py
|
113
114
|
modal/_utils/hash_utils.py
|
@@ -309,6 +309,7 @@ message AppDeploymentHistory {
|
|
309
309
|
string tag = 6;
|
310
310
|
uint32 rollback_version = 7;
|
311
311
|
bool rollback_allowed = 8;
|
312
|
+
optional CommitInfo commit_info = 10;
|
312
313
|
}
|
313
314
|
|
314
315
|
message AppDeploymentHistoryRequest {
|
@@ -419,6 +420,7 @@ message AppPublishRequest {
|
|
419
420
|
map<string, string> definition_ids = 7; // function_id -> definition_id
|
420
421
|
uint32 rollback_version = 8; // Unused by client, but used internally
|
421
422
|
string client_version = 9; // Unused by client, but used internally
|
423
|
+
CommitInfo commit_info = 10; // Git information for deployment tracking
|
422
424
|
}
|
423
425
|
|
424
426
|
message AppPublishResponse {
|
@@ -745,6 +747,17 @@ message CloudBucketMount {
|
|
745
747
|
optional string oidc_auth_role_arn = 9;
|
746
748
|
}
|
747
749
|
|
750
|
+
message CommitInfo {
|
751
|
+
string vcs = 1; // Only git is supported for now
|
752
|
+
string branch = 2;
|
753
|
+
string commit_hash = 3;
|
754
|
+
int64 commit_timestamp = 4;
|
755
|
+
bool dirty = 5;
|
756
|
+
string author_name = 6;
|
757
|
+
string author_email = 7;
|
758
|
+
string repo_url = 8;
|
759
|
+
}
|
760
|
+
|
748
761
|
message ContainerArguments { // This is used to pass data from the worker to the container
|
749
762
|
string task_id = 1;
|
750
763
|
string function_id = 2;
|