Skip to content

feat: add deployment mode/recipe selection#2135

Merged
lionello merged 12 commits into
mainfrom
lio/pulumi-config
Jul 7, 2026
Merged

feat: add deployment mode/recipe selection#2135
lionello merged 12 commits into
mainfrom
lio/pulumi-config

Conversation

@lionello

@lionello lionello commented May 29, 2026

Copy link
Copy Markdown
Member

Description

Linked Issues

Fixes https://github.com/DefangLabs/defang-global/issues/75

Checklist

  • I have performed a self-review of my code
  • I have added appropriate tests
  • I have updated the Defang CLI docs and/or README to reflect my changes, if necessary

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features
    • Added a “recipe” CLI (list, show, activate, deactivate).
    • Deployments, previews, and estimates now use and display the selected recipe, including recipe-aware DEFANG_MODE on stacks; non-defang providers prompt for recipe selection.
    • Provider selection now supports Azure when credentials are detected.
  • Bug Fixes
    • Fixed the stack wizard flow to correctly complete on success.
  • Tests
    • Updated coverage to use recipe-based modes and the new flows.

@coderabbitai

coderabbitai Bot commented May 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Introduces Recipe type with String/Set/Parse/Mode/FromMode methods; deprecates Mode type; migrates stack Parameters/ListItem to Recipe; adds recipe prompting in wizard for non-Defang providers; adds Fabric client recipe CRUD methods and gRPC wrappers; registers recipe CLI command with list/show/activate/deactivate subcommands; updates validation, estimate, and ComposeUp to thread Recipe; persists Recipe in stack and deployment records and BYOC payloads; updates agent tool interfaces and implementations to Recipe; updates ~130 test cases.

Changes

Recipe type and workflow migration

Layer / File(s) Summary
Recipe type definition and mode deprecation
src/pkg/modes/recipe.go, src/pkg/modes/mode.go, src/pkg/modes/mode_test.go, src/protos/io/defang/v1/fabric.proto
Introduces Recipe type with String, Set, ParseRecipe, Type, Mode, FromMode methods and constants (RecipeUnspecified, RecipeAffordable, RecipeBalanced, RecipeHighAvailability). Deprecates Mode type and AllDeploymentModes function. Reworks mode tests to use local constants. Marks proto DeployRequest.mode field as deprecated.
Stack state models and Recipe serialization
src/pkg/stacks/stacks.go, src/pkg/stacks/stacks_test.go, src/pkg/stacks/manager.go, src/pkg/session/session.go, src/pkg/stacks/manager_test.go, src/pkg/session/session_test.go
Changes Parameters.Mode and ListItem.Mode from modes.Mode to modes.Recipe. Updates ToMap/paramsFromMap to parse/serialize DEFANG_MODE via Recipe. Manager uses RecipeUnspecified sentinel and derives params via modes.FromMode. Session uses RecipeUnspecified for mode override. Updates all test fixtures and assertions.
Stack wizard and CLI parameter collection
src/pkg/stacks/wizard.go, src/pkg/stacks/selector_test.go, src/pkg/stacks/wizard_test.go, src/cmd/cli/command/stack.go, src/cmd/cli/command/stack_test.go
Wizard adds modes import and elicits recipe via RequestEnum for non-Defang providers. Selector tests expect Mode in Parameters. Wizard and selector tests include recipe selection mock interactions. Stack command prompt return path explicitly returns nil on success. Stack command tests verify recipe constants.
Fabric client recipe CRUD methods
src/pkg/cli/client/client.go, src/pkg/cli/client/grpc.go, src/pkg/cli/client/mock.go, src/pkg/cli/client/provider.go
Adds GetRecipe, ListRecipes, PutRecipe to FabricClient interface. Implements gRPC wrappers using connect.NewRequest and getMsg. Extends MockFabricClient with Recipe field and mock GetRecipe (returns field if set, otherwise constructs response with Active=true). Adds Recipe field to DeployRequest.
Recipe CLI command group and helpers
src/cmd/cli/command/commands.go, src/cmd/cli/command/recipe.go, src/pkg/cli/recipeShow.go, src/pkg/cli/recipeList.go, src/pkg/cli/recipeActivate.go
Registers top-level recipe command with list/show/activate/deactivate subcommands requiring authNeededAlways. Implements RecipeShow (fetches and prints Pulumi config), RecipeList (tables recipe names and active status), RecipeActivate (toggles Active flag and persists). Batch operations aggregate errors via errors.Join.
CLI defaults and estimation command
src/cmd/cli/command/globals.go, src/cmd/cli/command/estimate.go, src/cmd/cli/command/globals_test.go, src/cmd/cli/command/estimate_test.go
Updates globals to use RecipeUnspecified sentinel. Estimate command defaults to RecipeAffordable. Adds Azure provider description and detection. Updates test expectations.
Validation and estimate function migration
src/pkg/cli/compose/validation.go, src/pkg/cli/estimate.go, src/pkg/cli/compose/validation_test.go, src/pkg/cli/preview_test.go
Migrates ValidateProject/validateService to accept modes.Recipe. Updates HA check to RecipeHighAvailability. Threads Recipe through RunEstimate/GeneratePreview/PrintEstimate. GeneratePreview calls fabric.GetRecipe to fetch recipe metadata.
ComposeUp recipe threading and deployment
src/pkg/cli/composeUp.go, src/cmd/cli/command/compose.go, src/pkg/cli/composeUp_test.go, src/pkg/cli/composeUp_dockerfile_test.go
ComposeUpParams.Mode changed to modes.Recipe. Threads recipe through validation, compatibility check (via recipe.Mode()), and request construction. Fetches recipe metadata via Fabric.GetRecipe. Sets DeployRequest.Mode from recipe.Mode().Value() and DeployRequest.Recipe from response. Persists both Mode and Recipe in history.
Deployment and stack persistence
src/pkg/cli/stacks.go, src/pkg/cli/stacks_test.go, src/pkg/cli/common.go
SetDefaultStack derives Stack.Mode from stack.Mode.Mode().Value() and populates Stack.Recipe.Name. putDeploymentParams adds Recipe field. Wires Recipe into PutStackRequest and PutDeploymentRequest payloads.
BYOC provider deployment payloads
src/pkg/cli/client/byoc/aws/byoc.go, src/pkg/cli/client/byoc/azure/byoc.go, src/pkg/cli/client/byoc/do/byoc.go, src/pkg/cli/client/byoc/gcp/byoc.go
Adds Recipe field from DeployRequest into marshaled ProjectUpdate payloads for AWS, Azure, DigitalOcean, and GCP CD job uploads.
Agent tool interface and Recipe adoption
src/pkg/agent/tools/interfaces.go, src/pkg/agent/tools/default_tool_cli.go, src/pkg/agent/tools/estimate.go, src/pkg/agent/tools/estimate_test.go, src/pkg/agent/tools/create_aws_stack.go, src/pkg/agent/tools/create_azure_stack.go, src/pkg/agent/tools/create_gcp_stack.go, src/pkg/agent/tools/services_test.go, src/pkg/agent/tools/select_stack_test.go, src/pkg/agent/tools/current_stack_test.go, src/pkg/agent/tools/deploy.go
CLIInterface updates RunEstimate/PrintEstimate signatures to modes.Recipe. HandleEstimateTool parses mode via modes.ParseRecipe. Stack creation tools use modes.ParseRecipe directly without explicit error handling. Mock/test doubles updated to Recipe signatures. Test assertions use Recipe constants.
Test robustness improvements
src/pkg/cli/tail_test.go, src/pkg/clouds/aws/secrets.go
fileToStringArray adds scanner.Err() check with test failure on scan errors. AWS secrets.PutSecret sets Intelligent-Tiering parameter tier with documentation.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~80 minutes

Possibly related PRs

  • DefangLabs/defang#2131: The recipe CRUD client methods and usage in this PR depend directly on the gRPC Recipe message types and service methods added in that PR.
  • DefangLabs/defang#1780: The PutStackRequest RPC wiring and stack persistence flow that this PR extends with Recipe field is foundational to the changes.
  • DefangLabs/defang#1713: Both PRs modify the stack wizard flow in src/pkg/stacks/wizard.go—this PR adds recipe-mode elicitation while the related PR refactors wizard wiring.

Suggested labels

go, high

Suggested reviewers

  • edwardrf
  • jordanstephens

A recipe is born from modes now past,
With Affordable, Balanced dreams that last,
Wizard asks, "which flavor shall we choose?"
Stack and deploy in recipe's shoes,
Chef's delight! 🐇✨ A migration so vast!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.06% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly matches the main change: introducing recipe-based deployment mode selection across the CLI and deployment flow.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch lio/pulumi-config

Comment @coderabbitai help to get the list of available commands.

@lionello lionello requested a review from edwardrf June 2, 2026 15:27
@lionello lionello marked this pull request as ready for review June 2, 2026 23:05
@lionello lionello requested a review from jordanstephens as a code owner June 2, 2026 23:05

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
src/cmd/cli/command/estimate.go (1)

88-100: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove the duplicate Azure case.

case pkg.AzureInEnv() != "" already exists at Lines 92-93, so the second occurrence at Lines 98-99 is unreachable dead code. Either drop it or correct it if a different provider was intended.

🧹 Proposed cleanup
 	case pkg.GcpInEnv() != "":
 		defaultOption = client.ProviderGCP.String()
-	case pkg.AzureInEnv() != "":
-		defaultOption = client.ProviderAzure.String()
 	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/cmd/cli/command/estimate.go` around lines 88 - 100, The switch in
estimate.go contains a duplicate Azure branch, making the later case
unreachable. Remove the repeated pkg.AzureInEnv() check from the default option
selection, or replace it with the intended provider case if another environment
was meant; verify the logic in the provider selection block around defaultOption
so each provider is handled only once.
src/pkg/agent/tools/create_aws_stack.go (1)

20-31: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Validate params.Mode instead of silently accepting unknown values
src/pkg/agent/tools/create_aws_stack.go uses modes.ParseRecipe(params.Mode) inline (no error handling). In src/pkg/modes/recipe.go, ParseRecipe(str string) Recipe has no error return; it uppercases the input, maps only a few legacy aliases, and otherwise falls through to return Recipe(upper) for unrecognized strings. This removes the prior “invalid mode” error behavior from modes.Parse. Restore explicit validation/error handling (or ensure unknown recipes are rejected downstream) before persisting/using the stack.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pkg/agent/tools/create_aws_stack.go` around lines 20 - 31,
HandleCreateAWSStackTool currently calls modes.ParseRecipe(params.Mode) with no
validation; restore explicit validation by parsing the mode then checking it
against the known/allowed Recipe values (e.g., via a new or existing validator
like modes.IsValid/knownRecipes or by updating modes.ParseRecipe to return an
error). If the parsed Recipe is not one of the recognized recipes, return a
descriptive error from HandleCreateAWSStackTool instead of persisting the stack;
otherwise proceed to build newStack (referencing newStack and modes.ParseRecipe)
and call createAndLoadStack as before.
src/pkg/cli/common.go (1)

56-124: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Drop putDeploymentParams.Recipe in putDeploymentAndStack (common.go)

  • src/pkg/cli/common.go defines putDeploymentParams.Recipe, but putDeploymentAndStack never reads it and never sets Stack.Recipe / Deployment.Recipe in the PutStackRequest and PutDeploymentRequest.
  • src/pkg/cli/composeUp.go does populate Recipe: deployRequest.Recipe, and the protobufs (io.defang.v1.Stack / io.defang.v1.Deployment) include a recipe field (with mode marked deprecated), so wiring req.Recipe through would prevent losing recipe metadata in the stored deployment/stack.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pkg/cli/common.go` around lines 56 - 124, putDeploymentAndStack currently
ignores putDeploymentParams.Recipe so recipe metadata is never saved; update the
function to pass req.Recipe into both the Stack and Deployment in the
PutStackRequest and PutDeploymentRequest (set Stack.Recipe = req.Recipe and
Deployment.Recipe = req.Recipe), ensuring the same recipe populated by
composeUp.go (deployRequest.Recipe) is persisted; locate these fields in
putDeploymentAndStack and add the Recipe assignments to the created
defangv1.Stack and defangv1.Deployment objects.
🧹 Nitpick comments (3)
src/cmd/cli/command/recipe.go (2)

76-93: 💤 Low value

Rename variable for consistency.

The variable is named recipeUnarchiveCmd but represents the activate command. Consider renaming to recipeActivateCmd for consistency with the function name and command semantics.

♻️ Proposed change
-	var recipeUnarchiveCmd = &cobra.Command{
+	var recipeActivateCmd = &cobra.Command{
 		Use:         "activate [RECIPE_NAME...]",
 		Aliases:     []string{"restore", "enable", "undelete", "unarchive"},
 		Annotations: authNeededAlways,
 		Args:        cobra.MinimumNArgs(1),
 		Short:       "Activates a recipe in the current workspace",
 		RunE: func(cmd *cobra.Command, args []string) error {
 			ctx := cmd.Context()
 			var errs []error
 			for _, name := range args {
 				errs = append(errs, cli.RecipeActivate(ctx, global.Client, name, true))
 			}
 			return errors.Join(errs...)
 		},
 	}
-	return recipeUnarchiveCmd
+	return recipeActivateCmd
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/cmd/cli/command/recipe.go` around lines 76 - 93, The local variable
recipeUnarchiveCmd in makeRecipeActivateCmd should be renamed to
recipeActivateCmd to match the function/command semantics; update its
declaration and the final return statement to use recipeActivateCmd, and ensure
any internal references (the cobra.Command literal and its RunE closure) remain
unchanged so only the variable identifier is renamed.

58-73: 💤 Low value

Rename variable for consistency.

The variable is named recipeArchiveCmd but represents the deactivate command. Consider renaming to recipeDeactivateCmd for consistency with the function name and command semantics.

♻️ Proposed change
-	var recipeArchiveCmd = &cobra.Command{
+	var recipeDeactivateCmd = &cobra.Command{
 		Use:         "deactivate [RECIPE_NAME...]",
 		Aliases:     []string{"remove", "rm", "delete", "del", "disable", "archive"},
 		Annotations: authNeededAlways,
 		Args:        cobra.MinimumNArgs(1),
 		Short:       "Deactivates a recipe in the current workspace",
 		RunE: func(cmd *cobra.Command, args []string) error {
 			ctx := cmd.Context()
 			var errs []error
 			for _, name := range args {
 				errs = append(errs, cli.RecipeActivate(ctx, global.Client, name, false))
 			}
 			return errors.Join(errs...)
 		},
 	}
-	return recipeArchiveCmd
+	return recipeDeactivateCmd
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/cmd/cli/command/recipe.go` around lines 58 - 73, The variable
recipeArchiveCmd is misnamed for the deactivate command; rename it to
recipeDeactivateCmd and update its declaration, any references (including the
return statement) to use recipeDeactivateCmd so the symbol matches the command
semantics and the function name; ensure the variable name change is applied
consistently within this function block (the cobra.Command variable and the
final return).
src/pkg/cli/composeUp.go (1)

138-140: 💤 Low value

Clarify the recipe override and simplify mode conversion.

After the compatibility check, if newMode is not ModeUnspecified, you override the user-provided recipe with a new one derived from the mode via modes.FromMode(newMode.Value()). This pattern has two concerns:

  1. Redundant conversion: newMode is already a modes.Mode, so calling .Value() to get defangv1.DeploymentMode and then passing it back to FromMode is a round-trip. Consider storing a direct Mode-to-Recipe mapping or checking if modes.FromMode(newMode) is valid (without the .Value() step).

  2. Potential information loss: If the original recipe carries any custom configuration beyond just the mode name, this override discards it. The subsequent GetRecipe call fetches backend config by name, but clarify in a comment whether user-provided recipe details (if any exist) are intentionally replaced by the compatibility-derived mode.

♻️ Optional: simplify or document the override

Document the intent:

 if newMode != modes.ModeUnspecified {
+    // Replace recipe with mode-based one to enforce compatibility;
+    // backend GetRecipe will supply full config.
     recipe = modes.FromMode(newMode.Value())
 }

Or refactor if a direct conversion exists:

-recipe = modes.FromMode(newMode.Value())
+recipe = modes.RecipeFromMode(newMode) // if such a helper exists
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pkg/cli/composeUp.go` around lines 138 - 140, The current override
replaces the entire user-provided recipe by calling recipe =
modes.FromMode(newMode.Value()), which both does a redundant .Value() round-trip
and discards any custom recipe fields; change this to directly convert the
modes.Mode without .Value() (e.g., call modes.FromMode(newMode) or use a small
Mode->Recipe mapping) and when applying the result only override the recipe's
mode/name (not the whole recipe) so user-specified configuration is preserved;
also add a short comment near newMode, recipe, modes.FromMode and GetRecipe
clarifying that only the mode/name is being canonicalized for compatibility, not
wholesale replacement of user recipe data.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/cmd/cli/command/recipe.go`:
- Line 11: Rename the incorrectly named variable stackCmd to recipeCmd so the
command variable reflects its purpose; find the declaration "var stackCmd =
&cobra.Command{", rename the identifier to "recipeCmd" everywhere it is
referenced (including any uses in init/register functions) and ensure any
related help/usage text remains unchanged.

In `@src/pkg/cli/composeUp.go`:
- Around line 143-155: The deploy request mixes the local recipe.Mode() and the
backend-fetched rresp.Recipe, which can produce conflicting Mode values; after
calling fabric.GetRecipe (GetRecipe) check that rresp.Recipe is non-nil and that
rresp.Recipe.Mode equals recipe.Mode().Value(), and if they differ return an
error indicating the mismatch, or else set deployRequest.DeployRequest.Mode from
the fetched rresp.Recipe.Mode so both deployRequest.Mode and Recipe
(rresp.Recipe) use the same source of truth; update the code paths that build
the deployRequest (the DeployRequest struct and any early return) accordingly.

In `@src/pkg/cli/recipeShow.go`:
- Around line 13-19: resp.Recipe may be nil after fabric.GetRecipe; before
accessing resp.Recipe.PulumiConfig in recipeShow.go, add a nil-guard: check that
resp != nil && resp.Recipe != nil and handle the nil case (return a clear error
from the surrounding function or print a “recipe not found” message) instead of
dereferencing; update the code around the GetRecipe call and the subsequent
term.Println usage to avoid a panic and return the appropriate error when Recipe
is nil.

In `@src/pkg/modes/recipe.go`:
- Around line 22-39: The Set method currently accepts any string and ParseRecipe
returns Recipe(upper) for unknown inputs, letting typos become ModeUnspecified
downstream; update ParseRecipe to validate against known constants
(RecipeAffordable, RecipeBalanced, RecipeHighAvailability, etc.) and have
Recipe.Set call ParseRecipe and return a descriptive error when the input is
unrecognized (instead of nil), or alternatively provide a separate
ParseRecipeAllowFreeForm used only by the agent; ensure Recipe.Mode() still maps
properly but that CLI pflag.Value parsing and DEFANG_MODE reading fail fast on
invalid values.

In `@src/pkg/stacks/stacks.go`:
- Around line 72-80: modes.ParseRecipe currently uppercases and maps aliases but
returns Recipe(upper) for unknown inputs, allowing invalid modes to slip
through; update ParseRecipe to validate the uppercased value against known
recipes and return modes.RecipeUnspecified for any unrecognized string (while
preserving case-insensitive matching and legacy alias mapping), add a unit test
that calls modes.ParseRecipe with an invalid value and asserts
RecipeUnspecified, and ensure callers (e.g., the Parameters construction in
stacks.go where recipe is set) continue to treat RecipeUnspecified as the
sentinel for unspecified/invalid mode.

---

Outside diff comments:
In `@src/cmd/cli/command/estimate.go`:
- Around line 88-100: The switch in estimate.go contains a duplicate Azure
branch, making the later case unreachable. Remove the repeated pkg.AzureInEnv()
check from the default option selection, or replace it with the intended
provider case if another environment was meant; verify the logic in the provider
selection block around defaultOption so each provider is handled only once.

In `@src/pkg/agent/tools/create_aws_stack.go`:
- Around line 20-31: HandleCreateAWSStackTool currently calls
modes.ParseRecipe(params.Mode) with no validation; restore explicit validation
by parsing the mode then checking it against the known/allowed Recipe values
(e.g., via a new or existing validator like modes.IsValid/knownRecipes or by
updating modes.ParseRecipe to return an error). If the parsed Recipe is not one
of the recognized recipes, return a descriptive error from
HandleCreateAWSStackTool instead of persisting the stack; otherwise proceed to
build newStack (referencing newStack and modes.ParseRecipe) and call
createAndLoadStack as before.

In `@src/pkg/cli/common.go`:
- Around line 56-124: putDeploymentAndStack currently ignores
putDeploymentParams.Recipe so recipe metadata is never saved; update the
function to pass req.Recipe into both the Stack and Deployment in the
PutStackRequest and PutDeploymentRequest (set Stack.Recipe = req.Recipe and
Deployment.Recipe = req.Recipe), ensuring the same recipe populated by
composeUp.go (deployRequest.Recipe) is persisted; locate these fields in
putDeploymentAndStack and add the Recipe assignments to the created
defangv1.Stack and defangv1.Deployment objects.

---

Nitpick comments:
In `@src/cmd/cli/command/recipe.go`:
- Around line 76-93: The local variable recipeUnarchiveCmd in
makeRecipeActivateCmd should be renamed to recipeActivateCmd to match the
function/command semantics; update its declaration and the final return
statement to use recipeActivateCmd, and ensure any internal references (the
cobra.Command literal and its RunE closure) remain unchanged so only the
variable identifier is renamed.
- Around line 58-73: The variable recipeArchiveCmd is misnamed for the
deactivate command; rename it to recipeDeactivateCmd and update its declaration,
any references (including the return statement) to use recipeDeactivateCmd so
the symbol matches the command semantics and the function name; ensure the
variable name change is applied consistently within this function block (the
cobra.Command variable and the final return).

In `@src/pkg/cli/composeUp.go`:
- Around line 138-140: The current override replaces the entire user-provided
recipe by calling recipe = modes.FromMode(newMode.Value()), which both does a
redundant .Value() round-trip and discards any custom recipe fields; change this
to directly convert the modes.Mode without .Value() (e.g., call
modes.FromMode(newMode) or use a small Mode->Recipe mapping) and when applying
the result only override the recipe's mode/name (not the whole recipe) so
user-specified configuration is preserved; also add a short comment near
newMode, recipe, modes.FromMode and GetRecipe clarifying that only the mode/name
is being canonicalized for compatibility, not wholesale replacement of user
recipe data.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b363f9dc-d3d7-47e2-b66a-eeefa9d62564

📥 Commits

Reviewing files that changed from the base of the PR and between 3dfee36 and 10f9f4c.

📒 Files selected for processing (54)
  • src/cmd/cli/command/commands.go
  • src/cmd/cli/command/compose.go
  • src/cmd/cli/command/estimate.go
  • src/cmd/cli/command/estimate_test.go
  • src/cmd/cli/command/globals.go
  • src/cmd/cli/command/globals_test.go
  • src/cmd/cli/command/recipe.go
  • src/cmd/cli/command/stack.go
  • src/cmd/cli/command/stack_test.go
  • src/pkg/agent/tools/create_aws_stack.go
  • src/pkg/agent/tools/create_azure_stack.go
  • src/pkg/agent/tools/create_gcp_stack.go
  • src/pkg/agent/tools/current_stack_test.go
  • src/pkg/agent/tools/default_tool_cli.go
  • src/pkg/agent/tools/deploy.go
  • src/pkg/agent/tools/estimate.go
  • src/pkg/agent/tools/estimate_test.go
  • src/pkg/agent/tools/interfaces.go
  • src/pkg/agent/tools/select_stack_test.go
  • src/pkg/agent/tools/services_test.go
  • src/pkg/cli/client/byoc/aws/byoc.go
  • src/pkg/cli/client/byoc/azure/byoc.go
  • src/pkg/cli/client/byoc/do/byoc.go
  • src/pkg/cli/client/byoc/gcp/byoc.go
  • src/pkg/cli/client/client.go
  • src/pkg/cli/client/grpc.go
  • src/pkg/cli/client/mock.go
  • src/pkg/cli/client/provider.go
  • src/pkg/cli/common.go
  • src/pkg/cli/compose/validation.go
  • src/pkg/cli/compose/validation_test.go
  • src/pkg/cli/composeUp.go
  • src/pkg/cli/composeUp_dockerfile_test.go
  • src/pkg/cli/composeUp_test.go
  • src/pkg/cli/estimate.go
  • src/pkg/cli/preview_test.go
  • src/pkg/cli/recipeActivate.go
  • src/pkg/cli/recipeList.go
  • src/pkg/cli/recipeShow.go
  • src/pkg/cli/stacks.go
  • src/pkg/cli/stacks_test.go
  • src/pkg/cli/tail_test.go
  • src/pkg/modes/mode.go
  • src/pkg/modes/mode_test.go
  • src/pkg/modes/recipe.go
  • src/pkg/session/session.go
  • src/pkg/session/session_test.go
  • src/pkg/stacks/manager.go
  • src/pkg/stacks/manager_test.go
  • src/pkg/stacks/selector_test.go
  • src/pkg/stacks/stacks.go
  • src/pkg/stacks/stacks_test.go
  • src/pkg/stacks/wizard.go
  • src/pkg/stacks/wizard_test.go
💤 Files with no reviewable changes (1)
  • src/cmd/cli/command/stack.go

Comment thread src/cmd/cli/command/recipe.go Outdated
Comment thread src/pkg/cli/composeUp.go
Comment thread src/pkg/cli/recipeShow.go
Comment thread src/pkg/modes/recipe.go
Comment thread src/pkg/stacks/stacks.go Outdated
Comment thread src/pkg/agent/tools/create_aws_stack.go Outdated
Comment thread src/pkg/cli/estimate.go Outdated
Comment thread src/pkg/cli/recipeActivate.go Outdated
@lionello lionello force-pushed the lio/pulumi-config branch from d01b0c0 to 84e734f Compare June 19, 2026 19:43
@lionello lionello self-assigned this Jun 24, 2026
@lionello lionello changed the title feat: add deployment mode selection to parameter collection feat: add deployment mode/recipe selection Jun 24, 2026
@lionello lionello force-pushed the lio/pulumi-config branch from 3b5f3d5 to 0be7716 Compare June 25, 2026 18:21
lionello added 11 commits July 6, 2026 16:15
…ures

- Updated all instances of Mode to Recipe in ComposeUpParams across tests and implementation files.
- Adjusted related test cases to reflect the new parameter name.
- Modified stacks and session management to accommodate the Recipe parameter instead of Mode.
- Ensured backward compatibility by handling legacy aliases in recipe parsing.
- Updated protobuf definitions to deprecate Mode in favor of Recipe.
@lionello lionello force-pushed the lio/pulumi-config branch from 0be7716 to e204ff1 Compare July 7, 2026 00:15
@lionello lionello merged commit 7743553 into main Jul 7, 2026
6 checks passed
@lionello lionello deleted the lio/pulumi-config branch July 7, 2026 18:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants