agent-starter-pack 0.11.1__py3-none-any.whl → 0.12.0__py3-none-any.whl
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.
- {agent_starter_pack-0.11.1.dist-info → agent_starter_pack-0.12.0.dist-info}/METADATA +1 -1
- {agent_starter_pack-0.11.1.dist-info → agent_starter_pack-0.12.0.dist-info}/RECORD +45 -70
- agents/adk_base/app/__init__.py +17 -0
- agents/adk_base/notebooks/adk_app_testing.ipynb +4 -1
- agents/adk_base/tests/integration/test_agent.py +1 -1
- agents/agentic_rag/app/__init__.py +17 -0
- agents/agentic_rag/app/agent.py +2 -2
- agents/agentic_rag/notebooks/adk_app_testing.ipynb +4 -1
- agents/agentic_rag/tests/integration/test_agent.py +2 -2
- agents/crewai_coding_crew/tests/integration/test_agent.py +1 -1
- agents/langgraph_base_react/tests/integration/test_agent.py +1 -1
- agents/live_api/tests/unit/test_server.py +6 -6
- llm.txt +15 -4
- src/base_template/Makefile +5 -5
- src/base_template/README.md +4 -4
- src/base_template/deployment/terraform/dev/variables.tf +3 -2
- src/base_template/deployment/terraform/iam.tf +10 -34
- src/base_template/deployment/terraform/variables.tf +3 -3
- src/base_template/deployment/terraform/{% if cookiecutter.cicd_runner == 'google_cloud_build' %}build_triggers.tf{% else %}unused_build_triggers.tf{% endif %} +2 -2
- src/base_template/pyproject.toml +2 -2
- src/base_template/{% if cookiecutter.cicd_runner == 'github_actions' %}.github{% else %}unused_github{% endif %}/workflows/deploy-to-prod.yaml +1 -1
- src/base_template/{% if cookiecutter.cicd_runner == 'github_actions' %}.github{% else %}unused_github{% endif %}/workflows/pr_checks.yaml +1 -1
- src/base_template/{% if cookiecutter.cicd_runner == 'github_actions' %}.github{% else %}unused_github{% endif %}/workflows/staging.yaml +2 -2
- src/base_template/{% if cookiecutter.cicd_runner == 'google_cloud_build' %}.cloudbuild{% else %}unused_.cloudbuild{% endif %}/deploy-to-prod.yaml +1 -1
- src/base_template/{% if cookiecutter.cicd_runner == 'google_cloud_build' %}.cloudbuild{% else %}unused_.cloudbuild{% endif %}/staging.yaml +1 -1
- src/cli/commands/create.py +25 -2
- src/cli/commands/enhance.py +94 -15
- src/cli/commands/list.py +1 -1
- src/cli/commands/setup_cicd.py +50 -41
- src/cli/utils/remote_template.py +1 -1
- src/cli/utils/template.py +120 -41
- src/deployment_targets/agent_engine/tests/integration/test_agent_engine_app.py +3 -3
- src/deployment_targets/agent_engine/{app → {{cookiecutter.agent_directory}}}/agent_engine_app.py +10 -10
- src/deployment_targets/cloud_run/Dockerfile +2 -2
- src/deployment_targets/cloud_run/tests/integration/test_server_e2e.py +3 -3
- src/deployment_targets/cloud_run/tests/load_test/README.md +1 -1
- src/deployment_targets/cloud_run/tests/load_test/load_test.py +2 -2
- {agents/live_api/app → src/deployment_targets/cloud_run/{{cookiecutter.agent_directory}}}/server.py +186 -7
- src/resources/docs/adk-cheatsheet.md +3 -3
- src/base_template/app/__init__.py +0 -3
- src/deployment_targets/cloud_run/app/server.py +0 -206
- src/frontends/adk_gemini_fullstack/frontend/components.json +0 -21
- src/frontends/adk_gemini_fullstack/frontend/eslint.config.js +0 -28
- src/frontends/adk_gemini_fullstack/frontend/index.html +0 -12
- src/frontends/adk_gemini_fullstack/frontend/package-lock.json +0 -6105
- src/frontends/adk_gemini_fullstack/frontend/package.json +0 -47
- src/frontends/adk_gemini_fullstack/frontend/src/App.tsx +0 -564
- src/frontends/adk_gemini_fullstack/frontend/src/components/ActivityTimeline.tsx +0 -244
- src/frontends/adk_gemini_fullstack/frontend/src/components/ChatMessagesView.tsx +0 -420
- src/frontends/adk_gemini_fullstack/frontend/src/components/InputForm.tsx +0 -60
- src/frontends/adk_gemini_fullstack/frontend/src/components/WelcomeScreen.tsx +0 -56
- src/frontends/adk_gemini_fullstack/frontend/src/components/ui/badge.tsx +0 -46
- src/frontends/adk_gemini_fullstack/frontend/src/components/ui/button.tsx +0 -59
- src/frontends/adk_gemini_fullstack/frontend/src/components/ui/card.tsx +0 -92
- src/frontends/adk_gemini_fullstack/frontend/src/components/ui/input.tsx +0 -21
- src/frontends/adk_gemini_fullstack/frontend/src/components/ui/scroll-area.tsx +0 -56
- src/frontends/adk_gemini_fullstack/frontend/src/components/ui/select.tsx +0 -183
- src/frontends/adk_gemini_fullstack/frontend/src/components/ui/tabs.tsx +0 -64
- src/frontends/adk_gemini_fullstack/frontend/src/components/ui/textarea.tsx +0 -18
- src/frontends/adk_gemini_fullstack/frontend/src/global.css +0 -154
- src/frontends/adk_gemini_fullstack/frontend/src/main.tsx +0 -13
- src/frontends/adk_gemini_fullstack/frontend/src/utils.ts +0 -7
- src/frontends/adk_gemini_fullstack/frontend/src/vite-env.d.ts +0 -1
- src/frontends/adk_gemini_fullstack/frontend/tsconfig.json +0 -28
- src/frontends/adk_gemini_fullstack/frontend/tsconfig.node.json +0 -24
- src/frontends/adk_gemini_fullstack/frontend/vite.config.ts +0 -41
- {agent_starter_pack-0.11.1.dist-info → agent_starter_pack-0.12.0.dist-info}/WHEEL +0 -0
- {agent_starter_pack-0.11.1.dist-info → agent_starter_pack-0.12.0.dist-info}/entry_points.txt +0 -0
- {agent_starter_pack-0.11.1.dist-info → agent_starter_pack-0.12.0.dist-info}/licenses/LICENSE +0 -0
- /src/base_template/{app → {{cookiecutter.agent_directory}}}/utils/gcs.py +0 -0
- /src/base_template/{app → {{cookiecutter.agent_directory}}}/utils/tracing.py +0 -0
- /src/base_template/{app → {{cookiecutter.agent_directory}}}/utils/typing.py +0 -0
@@ -29,7 +29,7 @@ resource "google_cloudbuild_trigger" "pr_checks" {
|
|
29
29
|
|
30
30
|
filename = ".cloudbuild/pr_checks.yaml"
|
31
31
|
included_files = [
|
32
|
-
"
|
32
|
+
"{{cookiecutter.agent_directory}}/**",
|
33
33
|
"data_ingestion/**",
|
34
34
|
"tests/**",
|
35
35
|
"deployment/**",
|
@@ -64,7 +64,7 @@ resource "google_cloudbuild_trigger" "cd_pipeline" {
|
|
64
64
|
|
65
65
|
filename = ".cloudbuild/staging.yaml"
|
66
66
|
included_files = [
|
67
|
-
"
|
67
|
+
"{{cookiecutter.agent_directory}}/**",
|
68
68
|
"data_ingestion/**",
|
69
69
|
"tests/**",
|
70
70
|
"deployment/**",
|
src/base_template/pyproject.toml
CHANGED
@@ -75,7 +75,7 @@ select = [
|
|
75
75
|
ignore = ["E501", "C901"] # ignore line too long, too complex
|
76
76
|
|
77
77
|
[tool.ruff.lint.isort]
|
78
|
-
known-first-party = ["
|
78
|
+
known-first-party = ["{{cookiecutter.agent_directory}}", "frontend"]
|
79
79
|
|
80
80
|
[tool.mypy]
|
81
81
|
disallow_untyped_calls = true
|
@@ -113,4 +113,4 @@ pythonpath = "."
|
|
113
113
|
asyncio_default_fixture_loop_scope = "function"
|
114
114
|
|
115
115
|
[tool.hatch.build.targets.wheel]
|
116
|
-
packages = ["
|
116
|
+
packages = ["{{cookiecutter.agent_directory}}","frontend"]
|
@@ -108,7 +108,7 @@ jobs:
|
|
108
108
|
- name: Deploy to Production (Agent Engine)
|
109
109
|
run: |
|
110
110
|
uv export --no-hashes --no-sources --no-header --no-dev --no-emit-project --no-annotate --locked > .requirements.txt
|
111
|
-
uv run
|
111
|
+
uv run {{cookiecutter.agent_directory}}/agent_engine_app.py \
|
112
112
|
--project {% raw %}${{ vars.PROD_PROJECT_ID }}{% endraw %} \
|
113
113
|
--location {% raw %}${{ vars.REGION }}{% endraw %} \
|
114
114
|
--service-account {% raw %}${{ vars.APP_SA_EMAIL_PROD }}{% endraw %} \
|
@@ -19,7 +19,7 @@ on:
|
|
19
19
|
branches:
|
20
20
|
- main
|
21
21
|
paths:
|
22
|
-
- '
|
22
|
+
- '{{cookiecutter.agent_directory}}/**'
|
23
23
|
- 'data_ingestion/**'
|
24
24
|
- 'tests/**'
|
25
25
|
- 'deployment/**'
|
@@ -119,7 +119,7 @@ jobs:
|
|
119
119
|
- name: Deploy to Staging (Agent Engine)
|
120
120
|
run: |
|
121
121
|
uv export --no-hashes --no-sources --no-header --no-dev --no-emit-project --no-annotate --locked > .requirements.txt
|
122
|
-
uv run
|
122
|
+
uv run {{cookiecutter.agent_directory}}/agent_engine_app.py \
|
123
123
|
--project {% raw %}${{ vars.STAGING_PROJECT_ID }}{% endraw %} \
|
124
124
|
--location {% raw %}${{ vars.REGION }}{% endraw %} \
|
125
125
|
--service-account {% raw %}${{ vars.APP_SA_EMAIL_STAGING }}{% endraw %} \
|
@@ -74,7 +74,7 @@ steps:
|
|
74
74
|
- "-c"
|
75
75
|
- |
|
76
76
|
uv export --no-hashes --no-sources --no-header --no-dev --no-emit-project --no-annotate --locked > .requirements.txt
|
77
|
-
uv run
|
77
|
+
uv run {{cookiecutter.agent_directory}}/agent_engine_app.py \
|
78
78
|
--project ${_PROD_PROJECT_ID} \
|
79
79
|
--location ${_REGION} \
|
80
80
|
--service-account ${_APP_SA_EMAIL_PROD} \
|
@@ -108,7 +108,7 @@ steps:
|
|
108
108
|
- "-c"
|
109
109
|
- |
|
110
110
|
uv export --no-hashes --no-sources --no-header --no-dev --no-emit-project --no-annotate --locked > .requirements.txt
|
111
|
-
uv run
|
111
|
+
uv run {{cookiecutter.agent_directory}}/agent_engine_app.py \
|
112
112
|
--project ${_STAGING_PROJECT_ID} \
|
113
113
|
--location ${_REGION} \
|
114
114
|
--service-account ${_APP_SA_EMAIL_STAGING} \
|
src/cli/commands/create.py
CHANGED
@@ -19,10 +19,10 @@ import pathlib
|
|
19
19
|
import shutil
|
20
20
|
import subprocess
|
21
21
|
import tempfile
|
22
|
+
import tomllib
|
22
23
|
from collections.abc import Callable
|
23
24
|
|
24
25
|
import click
|
25
|
-
import tomllib
|
26
26
|
from click.core import ParameterSource
|
27
27
|
from rich.console import Console
|
28
28
|
from rich.prompt import IntPrompt, Prompt
|
@@ -101,6 +101,11 @@ def shared_template_options(f: Callable) -> Callable:
|
|
101
101
|
type=click.Choice(["agent_engine", "cloud_run"]),
|
102
102
|
help="Deployment target name",
|
103
103
|
)(f)
|
104
|
+
f = click.option(
|
105
|
+
"--agent-directory",
|
106
|
+
"-dir",
|
107
|
+
help="Name of the agent directory (overrides template default)",
|
108
|
+
)(f)
|
104
109
|
return f
|
105
110
|
|
106
111
|
|
@@ -232,8 +237,10 @@ def create(
|
|
232
237
|
region: str,
|
233
238
|
skip_checks: bool,
|
234
239
|
in_folder: bool,
|
240
|
+
agent_directory: str | None,
|
235
241
|
base_template: str | None = None,
|
236
242
|
skip_welcome: bool = False,
|
243
|
+
cli_overrides: dict | None = None,
|
237
244
|
) -> None:
|
238
245
|
"""Create GCP-based AI agent projects from templates."""
|
239
246
|
try:
|
@@ -434,6 +441,14 @@ def create(
|
|
434
441
|
/ ".template"
|
435
442
|
)
|
436
443
|
config = load_template_config(template_path)
|
444
|
+
|
445
|
+
# Apply CLI overrides for local templates if provided (e.g., from enhance command)
|
446
|
+
if cli_overrides:
|
447
|
+
config = merge_template_configs(config, cli_overrides)
|
448
|
+
if debug:
|
449
|
+
logging.debug(
|
450
|
+
f"Applied CLI overrides to local template config: {cli_overrides}"
|
451
|
+
)
|
437
452
|
# Data ingestion and datastore selection
|
438
453
|
if include_data_ingestion or datastore:
|
439
454
|
include_data_ingestion = True
|
@@ -610,6 +625,13 @@ def create(
|
|
610
625
|
if debug:
|
611
626
|
logging.debug(f"Output directory: {destination_dir}")
|
612
627
|
|
628
|
+
# Construct CLI overrides for template processing
|
629
|
+
final_cli_overrides = cli_overrides or {}
|
630
|
+
if agent_directory:
|
631
|
+
if "settings" not in final_cli_overrides:
|
632
|
+
final_cli_overrides["settings"] = {}
|
633
|
+
final_cli_overrides["settings"]["agent_directory"] = agent_directory
|
634
|
+
|
613
635
|
try:
|
614
636
|
# Process template (handles both local and remote templates)
|
615
637
|
process_template(
|
@@ -623,8 +645,9 @@ def create(
|
|
623
645
|
session_type=final_session_type,
|
624
646
|
output_dir=destination_dir,
|
625
647
|
remote_template_path=template_source_path,
|
626
|
-
remote_config=config
|
648
|
+
remote_config=config,
|
627
649
|
in_folder=in_folder,
|
650
|
+
cli_overrides=final_cli_overrides,
|
628
651
|
)
|
629
652
|
|
630
653
|
# Replace region in all files if a different region was specified
|
src/cli/commands/enhance.py
CHANGED
@@ -13,6 +13,7 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
15
|
import pathlib
|
16
|
+
from typing import Any
|
16
17
|
|
17
18
|
import click
|
18
19
|
from rich.console import Console
|
@@ -48,7 +49,7 @@ def display_base_template_selection(current_base: str) -> str:
|
|
48
49
|
choice_num = 1
|
49
50
|
current_choice = None
|
50
51
|
|
51
|
-
for
|
52
|
+
for agent in agents.values():
|
52
53
|
template_choices[choice_num] = agent["name"]
|
53
54
|
current_indicator = " (current)" if agent["name"] == current_base else ""
|
54
55
|
console.print(
|
@@ -89,6 +90,10 @@ def display_base_template_selection(current_base: str) -> str:
|
|
89
90
|
"--base-template",
|
90
91
|
help="Base template to inherit from (e.g., adk_base, langgraph_base_react, agentic_rag)",
|
91
92
|
)
|
93
|
+
@click.option(
|
94
|
+
"--agent-directory",
|
95
|
+
help="Custom directory name for agent files (default: 'app' or auto-detected from pyproject.toml)",
|
96
|
+
)
|
92
97
|
@shared_template_options
|
93
98
|
@handle_cli_error
|
94
99
|
def enhance(
|
@@ -105,6 +110,7 @@ def enhance(
|
|
105
110
|
region: str,
|
106
111
|
skip_checks: bool,
|
107
112
|
base_template: str | None,
|
113
|
+
agent_directory: str | None,
|
108
114
|
) -> None:
|
109
115
|
"""Enhance your existing project with AI agent capabilities.
|
110
116
|
|
@@ -113,7 +119,8 @@ def enhance(
|
|
113
119
|
creating a new project directory.
|
114
120
|
|
115
121
|
For best compatibility, your project should follow the agent-starter-pack structure
|
116
|
-
with agent code organized in an
|
122
|
+
with agent code organized in an agent directory (default: /app, configurable via
|
123
|
+
--agent-directory).
|
117
124
|
|
118
125
|
TEMPLATE_PATH can be:
|
119
126
|
- A local directory path (e.g., . for current directory)
|
@@ -191,10 +198,13 @@ def enhance(
|
|
191
198
|
load_remote_template_config,
|
192
199
|
)
|
193
200
|
|
194
|
-
# Prepare CLI overrides for base template
|
195
|
-
cli_overrides = {}
|
201
|
+
# Prepare CLI overrides for base template and agent directory
|
202
|
+
cli_overrides: dict[str, Any] = {}
|
196
203
|
if base_template:
|
197
204
|
cli_overrides["base_template"] = base_template
|
205
|
+
if agent_directory:
|
206
|
+
cli_overrides["settings"] = cli_overrides.get("settings", {})
|
207
|
+
cli_overrides["settings"]["agent_directory"] = agent_directory
|
198
208
|
|
199
209
|
# Load config from current directory for inheritance info
|
200
210
|
current_dir = pathlib.Path.cwd()
|
@@ -209,6 +219,10 @@ def enhance(
|
|
209
219
|
if selected_base_template != original_base_template_name:
|
210
220
|
# Update CLI overrides with the selected base template
|
211
221
|
cli_overrides["base_template"] = selected_base_template
|
222
|
+
# Preserve agent_directory override if it was set
|
223
|
+
if agent_directory:
|
224
|
+
cli_overrides["settings"] = cli_overrides.get("settings", {})
|
225
|
+
cli_overrides["settings"]["agent_directory"] = agent_directory
|
212
226
|
base_template = selected_base_template
|
213
227
|
console.print(
|
214
228
|
f"✅ Selected base template: [cyan]{selected_base_template}[/cyan]"
|
@@ -232,9 +246,53 @@ def enhance(
|
|
232
246
|
# Validate project structure when using current directory template
|
233
247
|
if template_path == pathlib.Path("."):
|
234
248
|
current_dir = pathlib.Path.cwd()
|
235
|
-
app_folder = current_dir / "app"
|
236
249
|
|
237
|
-
|
250
|
+
# Determine agent directory: CLI param > pyproject.toml detection > default
|
251
|
+
detected_agent_directory = "app" # default
|
252
|
+
if not agent_directory: # Only try to detect if not provided via CLI
|
253
|
+
pyproject_path = current_dir / "pyproject.toml"
|
254
|
+
if pyproject_path.exists():
|
255
|
+
try:
|
256
|
+
import tomllib
|
257
|
+
|
258
|
+
with open(pyproject_path, "rb") as f:
|
259
|
+
pyproject_data = tomllib.load(f)
|
260
|
+
packages = (
|
261
|
+
pyproject_data.get("tool", {})
|
262
|
+
.get("hatch", {})
|
263
|
+
.get("build", {})
|
264
|
+
.get("targets", {})
|
265
|
+
.get("wheel", {})
|
266
|
+
.get("packages", [])
|
267
|
+
)
|
268
|
+
if packages:
|
269
|
+
# Find the first package that isn't 'frontend'
|
270
|
+
for pkg in packages:
|
271
|
+
if pkg != "frontend":
|
272
|
+
detected_agent_directory = pkg
|
273
|
+
break
|
274
|
+
except Exception as e:
|
275
|
+
if debug:
|
276
|
+
console.print(
|
277
|
+
f"[dim]Could not auto-detect agent directory: {e}[/dim]"
|
278
|
+
)
|
279
|
+
pass # Fall back to default
|
280
|
+
|
281
|
+
final_agent_directory = agent_directory or detected_agent_directory
|
282
|
+
|
283
|
+
# Show info about agent directory selection
|
284
|
+
if agent_directory:
|
285
|
+
console.print(
|
286
|
+
f"ℹ️ Using CLI-specified agent directory: [cyan]{agent_directory}[/cyan]"
|
287
|
+
)
|
288
|
+
elif detected_agent_directory != "app":
|
289
|
+
console.print(
|
290
|
+
f"ℹ️ Auto-detected agent directory: [cyan]{detected_agent_directory}[/cyan]"
|
291
|
+
)
|
292
|
+
|
293
|
+
agent_folder = current_dir / final_agent_directory
|
294
|
+
|
295
|
+
if not agent_folder.exists() or not agent_folder.is_dir():
|
238
296
|
console.print()
|
239
297
|
console.print(
|
240
298
|
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
@@ -245,42 +303,61 @@ def enhance(
|
|
245
303
|
)
|
246
304
|
console.print()
|
247
305
|
console.print(
|
248
|
-
"📁 [bold]Expected Structure:[/bold] [cyan]/
|
306
|
+
f"📁 [bold]Expected Structure:[/bold] [cyan]/{final_agent_directory}[/cyan] folder containing your agent code"
|
249
307
|
)
|
250
308
|
console.print(f"📍 [bold]Current Directory:[/bold] {current_dir}")
|
251
|
-
console.print(
|
309
|
+
console.print(
|
310
|
+
f"❌ [bold red]Missing:[/bold red] /{final_agent_directory} folder"
|
311
|
+
)
|
252
312
|
console.print()
|
253
313
|
console.print(
|
254
|
-
"
|
255
|
-
" your agent code should be organized in
|
314
|
+
f"The enhance command can still proceed, but for best compatibility"
|
315
|
+
f" your agent code should be organized in a /{final_agent_directory} folder structure."
|
256
316
|
)
|
257
317
|
console.print()
|
258
318
|
|
259
319
|
# Ask for confirmation after showing the structure warning
|
320
|
+
console.print("💡 Options:")
|
260
321
|
console.print(
|
261
|
-
"
|
322
|
+
f" • Create a /{final_agent_directory} folder and move your agent code there"
|
262
323
|
)
|
324
|
+
if final_agent_directory == "app":
|
325
|
+
console.print(
|
326
|
+
" • Use [cyan]--agent-directory <custom_name>[/cyan] if your agent code is in a different directory"
|
327
|
+
)
|
328
|
+
else:
|
329
|
+
console.print(
|
330
|
+
" • Use [cyan]--agent-directory <custom_name>[/cyan] to specify your existing agent directory"
|
331
|
+
)
|
263
332
|
console.print()
|
264
333
|
|
265
334
|
if not auto_approve:
|
266
335
|
if not click.confirm(
|
267
|
-
"Continue with enhancement despite missing /
|
336
|
+
f"Continue with enhancement despite missing /{final_agent_directory} folder?",
|
268
337
|
default=True,
|
269
338
|
):
|
270
339
|
console.print("✋ [yellow]Enhancement cancelled.[/yellow]")
|
271
340
|
return
|
272
341
|
else:
|
273
342
|
# Check for common agent files
|
274
|
-
agent_py =
|
343
|
+
agent_py = agent_folder / "agent.py"
|
275
344
|
if agent_py.exists():
|
276
345
|
console.print(
|
277
|
-
"Detected existing agent structure with [cyan]/
|
346
|
+
f"Detected existing agent structure with [cyan]/{final_agent_directory}/agent.py[/cyan]"
|
278
347
|
)
|
279
348
|
else:
|
280
349
|
console.print(
|
281
|
-
"ℹ️ [blue]Found /
|
350
|
+
f"ℹ️ [blue]Found /{final_agent_directory} folder[/blue] - ensure your agent code is properly organized within it, including an agent.py file"
|
282
351
|
)
|
283
352
|
|
353
|
+
# Prepare CLI overrides to pass to create command
|
354
|
+
final_cli_overrides: dict[str, Any] = {}
|
355
|
+
if base_template:
|
356
|
+
final_cli_overrides["base_template"] = base_template
|
357
|
+
if agent_directory:
|
358
|
+
final_cli_overrides["settings"] = final_cli_overrides.get("settings", {})
|
359
|
+
final_cli_overrides["settings"]["agent_directory"] = agent_directory
|
360
|
+
|
284
361
|
# Call the create command with in-folder mode enabled
|
285
362
|
ctx.invoke(
|
286
363
|
create,
|
@@ -297,6 +374,8 @@ def enhance(
|
|
297
374
|
region=region,
|
298
375
|
skip_checks=skip_checks,
|
299
376
|
in_folder=True, # Always use in-folder mode for enhance
|
377
|
+
agent_directory=agent_directory,
|
300
378
|
base_template=base_template,
|
301
379
|
skip_welcome=True, # Skip welcome message since enhance shows its own
|
380
|
+
cli_overrides=final_cli_overrides if final_cli_overrides else None,
|
302
381
|
)
|
src/cli/commands/list.py
CHANGED
src/cli/commands/setup_cicd.py
CHANGED
@@ -48,7 +48,7 @@ def display_intro_message() -> None:
|
|
48
48
|
"This command helps set up a basic CI/CD pipeline for development and testing purposes."
|
49
49
|
)
|
50
50
|
console.print("It will:")
|
51
|
-
console.print("- Create a GitHub repository and connect it to
|
51
|
+
console.print("- Create a GitHub repository and connect it to your CI/CD runner")
|
52
52
|
console.print("- Set up development environment infrastructure")
|
53
53
|
console.print("- Configure basic CI/CD triggers for PR checks and deployments")
|
54
54
|
console.print(
|
@@ -218,6 +218,34 @@ def validate_working_directory() -> None:
|
|
218
218
|
)
|
219
219
|
|
220
220
|
|
221
|
+
def detect_region_from_terraform_vars() -> str | None:
|
222
|
+
"""Detect region from Terraform vars file.
|
223
|
+
|
224
|
+
Returns:
|
225
|
+
str | None: The detected region, or None if not found or is default
|
226
|
+
"""
|
227
|
+
try:
|
228
|
+
tf_vars_path = Path("deployment/terraform/vars/env.tfvars")
|
229
|
+
if not tf_vars_path.exists():
|
230
|
+
return None
|
231
|
+
|
232
|
+
with open(tf_vars_path, encoding="utf-8") as f:
|
233
|
+
content = f.read()
|
234
|
+
|
235
|
+
# Look for region = "value" pattern
|
236
|
+
region_match = re.search(r'region\s*=\s*"([^"]+)"', content)
|
237
|
+
if region_match:
|
238
|
+
detected_region = region_match.group(1)
|
239
|
+
# Don't auto-detect if it's the default value
|
240
|
+
if detected_region != "us-central1":
|
241
|
+
return detected_region
|
242
|
+
|
243
|
+
return None
|
244
|
+
except Exception:
|
245
|
+
# If any error occurs, return None to use default
|
246
|
+
return None
|
247
|
+
|
248
|
+
|
221
249
|
def update_build_triggers(tf_dir: Path) -> None:
|
222
250
|
"""Update build triggers configuration."""
|
223
251
|
build_triggers_path = tf_dir / "build_triggers.tf"
|
@@ -427,7 +455,9 @@ console = Console()
|
|
427
455
|
@click.option(
|
428
456
|
"--cicd-project", help="CICD project ID (defaults to prod project if not specified)"
|
429
457
|
)
|
430
|
-
@click.option(
|
458
|
+
@click.option(
|
459
|
+
"--region", help="GCP region (auto-detects from Terraform vars if not specified)"
|
460
|
+
)
|
431
461
|
@click.option("--repository-name", help="Repository name (optional)")
|
432
462
|
@click.option(
|
433
463
|
"--repository-owner",
|
@@ -468,7 +498,7 @@ def setup_cicd(
|
|
468
498
|
staging_project: str | None,
|
469
499
|
prod_project: str | None,
|
470
500
|
cicd_project: str | None,
|
471
|
-
region: str,
|
501
|
+
region: str | None,
|
472
502
|
repository_name: str | None,
|
473
503
|
repository_owner: str | None,
|
474
504
|
host_connection_name: str | None,
|
@@ -502,23 +532,24 @@ def setup_cicd(
|
|
502
532
|
cicd_project = prod_project
|
503
533
|
console.print(f"Using production project '{prod_project}' for CI/CD resources")
|
504
534
|
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
535
|
+
# Auto-detect region if not provided
|
536
|
+
if region is None:
|
537
|
+
detected_region = detect_region_from_terraform_vars()
|
538
|
+
if detected_region:
|
539
|
+
region = detected_region
|
540
|
+
console.print(f"Auto-detected region from Terraform vars: {region}")
|
541
|
+
else:
|
542
|
+
region = "us-central1"
|
543
|
+
console.print(f"Using default region: {region}")
|
544
|
+
else:
|
545
|
+
console.print(f"Using provided region: {region}")
|
510
546
|
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
console.print("- Set up development environment infrastructure")
|
518
|
-
console.print("- Configure basic CI/CD triggers for PR checks and deployments")
|
519
|
-
console.print(
|
520
|
-
"- Configure remote Terraform state in GCS (use --local-state to use local state instead)"
|
521
|
-
)
|
547
|
+
# Auto-detect CI/CD runner based on Terraform files (moved earlier)
|
548
|
+
tf_dir = Path("deployment/terraform")
|
549
|
+
is_github_actions = (tf_dir / "wif.tf").exists() and (tf_dir / "github.tf").exists()
|
550
|
+
cicd_runner = "github_actions" if is_github_actions else "google_cloud_build"
|
551
|
+
|
552
|
+
display_intro_message()
|
522
553
|
|
523
554
|
console.print("\n⚡ Production Setup Note:", style="bold yellow")
|
524
555
|
console.print(
|
@@ -537,28 +568,6 @@ def setup_cicd(
|
|
537
568
|
console.print("\n🛑 Setup cancelled by user", style="bold yellow")
|
538
569
|
return
|
539
570
|
|
540
|
-
console.print(
|
541
|
-
"This command helps set up a basic CI/CD pipeline for development and testing purposes."
|
542
|
-
)
|
543
|
-
console.print("It will:")
|
544
|
-
console.print("- Create a GitHub repository and connect it to Cloud Build")
|
545
|
-
console.print("- Set up development environment infrastructure")
|
546
|
-
console.print("- Configure basic CI/CD triggers for PR checks and deployments")
|
547
|
-
console.print(
|
548
|
-
"- Configure remote Terraform state in GCS (use --local-state to use local state instead)"
|
549
|
-
)
|
550
|
-
|
551
|
-
console.print("\n⚡ Production Setup Note:", style="bold yellow")
|
552
|
-
console.print(
|
553
|
-
"For production deployments and maximum flexibility, we recommend following"
|
554
|
-
)
|
555
|
-
console.print("the manual setup instructions in deployment/README.md")
|
556
|
-
console.print("This will give you more control over:")
|
557
|
-
console.print("- Security configurations")
|
558
|
-
console.print("- Custom deployment workflows")
|
559
|
-
console.print("- Environment-specific settings")
|
560
|
-
console.print("- Advanced CI/CD pipeline customization\n")
|
561
|
-
|
562
571
|
if debug:
|
563
572
|
logging.basicConfig(level=logging.DEBUG)
|
564
573
|
console.print("> Debug mode enabled")
|
src/cli/utils/remote_template.py
CHANGED