Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 40 additions & 10 deletions src/google/adk/cli/cli_deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import subprocess
import sys
import traceback
from typing import Any
from typing import Callable
from typing import Final
from typing import Literal
from typing import Optional
Expand Down Expand Up @@ -620,6 +622,38 @@ def _get_service_option_by_adk_version(
return ' '.join(options)


def _get_ignore_patterns_func(
agent_folder: str,
) -> Callable[[Any, list[str]], set[str]]:
"""Returns a shutil.ignore_patterns function with combined patterns from .gitignore, .gcloudignore and .ae_ignore."""
# The local dev UI writes its session database under .adk/, which can grow
# large enough to fail a deployment.
patterns = {'.adk'}

for filename in ['.gitignore', '.gcloudignore', '.ae_ignore']:
filepath = os.path.join(agent_folder, filename)
if os.path.exists(filepath):
click.echo(f'Reading ignore patterns from {filename}...')
try:
with open(filepath, 'r') as f:
for line in f:
line = line.strip()
if line and not line.startswith('#'):
# If it ends with /, remove it for fnmatch compatibility
if line.endswith('/'):
line = line[:-1]
# Strip leading / from root-anchored patterns; shutil.ignore_patterns
# matches basenames via fnmatch, so '/venv' would match nothing.
if line.startswith('/'):
line = line[1:]
if line:
patterns.add(line)
except Exception as e:
click.secho(f'Warning: Failed to read {filename}: {e}', fg='yellow')

return shutil.ignore_patterns(*patterns)


def to_cloud_run(
*,
agent_folder: str,
Expand Down Expand Up @@ -696,7 +730,8 @@ def to_cloud_run(
# copy agent source code
click.echo('Copying agent source code...')
agent_src_path = os.path.join(temp_folder, 'agents', app_name)
shutil.copytree(agent_folder, agent_src_path)
ignore_func = _get_ignore_patterns_func(agent_folder)
shutil.copytree(agent_folder, agent_src_path, ignore=ignore_func)
requirements_txt_path = os.path.join(agent_src_path, 'requirements.txt')
install_agent_deps = (
f'RUN pip install -r "/app/agents/{app_name}/requirements.txt"'
Expand Down Expand Up @@ -948,18 +983,12 @@ def to_agent_engine(

try:
click.echo(f'Staging all files in: {agent_src_path}')
ignore_patterns = None
ae_ignore_path = os.path.join(agent_folder, '.ae_ignore')
if os.path.exists(ae_ignore_path):
click.echo(f'Ignoring files matching the patterns in {ae_ignore_path}')
with open(ae_ignore_path, 'r') as f:
patterns = [pattern.strip() for pattern in f.readlines()]
ignore_patterns = shutil.ignore_patterns(*patterns)
ignore_func = _get_ignore_patterns_func(agent_folder)
click.echo('Copying agent source code...')
shutil.copytree(
agent_folder,
agent_src_path,
ignore=ignore_patterns,
ignore=ignore_func,
dirs_exist_ok=True,
)
click.echo('Copying agent source code complete.')
Expand Down Expand Up @@ -1254,7 +1283,8 @@ def to_gke(
# copy agent source code
click.echo(' - Copying agent source code...')
agent_src_path = os.path.join(temp_folder, 'agents', app_name)
shutil.copytree(agent_folder, agent_src_path)
ignore_func = _get_ignore_patterns_func(agent_folder)
shutil.copytree(agent_folder, agent_src_path, ignore=ignore_func)
requirements_txt_path = os.path.join(agent_src_path, 'requirements.txt')
install_agent_deps = (
f'RUN pip install -r "/app/agents/{app_name}/requirements.txt"'
Expand Down
Loading
Loading