Skip to content

Comments

setup default recipe pack for rad init, rad env commands and rad deploy env.bicep#11212

Draft
nithyatsu wants to merge 12 commits intoradius-project:mainfrom
nithyatsu:setupkubepackdeploy
Draft

setup default recipe pack for rad init, rad env commands and rad deploy env.bicep#11212
nithyatsu wants to merge 12 commits intoradius-project:mainfrom
nithyatsu:setupkubepackdeploy

Conversation

@nithyatsu
Copy link
Contributor

@nithyatsu nithyatsu commented Feb 10, 2026

Description

rad init

  • uses Radius.Core API
  • creates singleton recipe packs in the default resource group scope (not the workspace scope) and links their IDs to the

rad env create --preview

  • adds recipe packs when creating a new Radius.Core environment, automatically creates singleton recipe packs in the default scope (if needed) and attaches them to the environment.

rad env update

  • on update, inspects existing recipe packs on the environment, detects conflicts, and ensures any missing singletons are created (as needed in default scope) and linked. conflicts are reported.

rad deploy

  • before deploying, scans the compiled ARM template for all Radius.Core/environments.
    For each environment found, inspects existing recipe packs, checks for conflicts, creates (as needed) missing singletons in the default scope, and injects their IDs into the template's .properties.recipePacks so the environment is deployed with full recipe pack coverage.

Type of change

  • This pull request fixes a bug in Radius and has an approved issue (issue link required).
  • This pull request adds or changes features of Radius and has an approved issue (issue link required).
  • This pull request is a minor refactor, code cleanup, test improvement, or other maintenance task and doesn't change the functionality of Radius (issue link optional).

Fixes: #11091

Contributor checklist

Please verify that the PR meets the following requirements, where applicable:

  • An overview of proposed schema changes is included in a linked GitHub issue.
    • Yes
    • Not applicable
  • A design document PR is created in the design-notes repository, if new APIs are being introduced.
    • Yes
    • Not applicable
  • The design document has been reviewed and approved by Radius maintainers/approvers.
    • Yes
    • Not applicable
  • A PR for the samples repository is created, if existing samples are affected by the changes in this PR.
    • Yes
    • Not applicable
  • A PR for the documentation repository is created, if the changes in this PR affect the documentation or any user facing updates are made.
    • Yes
    • Not applicable
  • A PR for the recipes repository is created, if existing recipes are affected by the changes in this PR.
    • Yes
    • Not applicable

@nithyatsu nithyatsu requested a deployment to external-contributor-approval February 10, 2026 15:54 — with GitHub Actions Waiting
@nithyatsu nithyatsu changed the title Setupkubepackdeploy setup default recipe pack for rad init, rad env commands and rad deploy env.bicep Feb 10, 2026
@nithyatsu nithyatsu temporarily deployed to external-contributor-approval February 10, 2026 18:41 — with GitHub Actions Inactive
@nithyatsu nithyatsu marked this pull request as ready for review February 10, 2026 18:42
@nithyatsu nithyatsu requested review from a team as code owners February 10, 2026 18:42
@nithyatsu nithyatsu requested a deployment to external-contributor-approval February 10, 2026 19:08 — with GitHub Actions Waiting
@nithyatsu nithyatsu temporarily deployed to external-contributor-approval February 10, 2026 19:32 — with GitHub Actions Inactive
@nithyatsu nithyatsu temporarily deployed to external-contributor-approval February 10, 2026 19:36 — with GitHub Actions Inactive
@nithyatsu nithyatsu temporarily deployed to external-contributor-approval February 10, 2026 20:26 — with GitHub Actions Inactive
@nithyatsu nithyatsu temporarily deployed to external-contributor-approval February 10, 2026 21:12 — with GitHub Actions Inactive
@nithyatsu nithyatsu temporarily deployed to external-contributor-approval February 10, 2026 21:16 — with GitHub Actions Inactive
@nithyatsu nithyatsu temporarily deployed to external-contributor-approval February 10, 2026 21:31 — with GitHub Actions Inactive
@nithyatsu nithyatsu temporarily deployed to external-contributor-approval February 10, 2026 22:00 — with GitHub Actions Inactive
@nithyatsu nithyatsu temporarily deployed to external-contributor-approval February 11, 2026 03:56 — with GitHub Actions Inactive
@radius-functional-tests
Copy link

radius-functional-tests bot commented Feb 11, 2026

Radius functional test overview

🔍 Go to test action run

Click here to see the test run details
Name Value
Repository nithyatsu/radius
Commit ref b684d7a
Unique ID funce49674cc7f
Image tag pr-funce49674cc7f
  • gotestsum 1.13.0
  • KinD: v0.29.0
  • Dapr: 1.14.4
  • Azure KeyVault CSI driver: 1.4.2
  • Azure Workload identity webhook: 1.3.0
  • Bicep recipe location ghcr.io/radius-project/dev/test/testrecipes/test-bicep-recipes/<name>:pr-funce49674cc7f
  • Terraform recipe location http://tf-module-server.radius-test-tf-module-server.svc.cluster.local/<name>.zip (in cluster)
  • applications-rp test image location: ghcr.io/radius-project/dev/applications-rp:pr-funce49674cc7f
  • dynamic-rp test image location: ghcr.io/radius-project/dev/dynamic-rp:pr-funce49674cc7f
  • controller test image location: ghcr.io/radius-project/dev/controller:pr-funce49674cc7f
  • ucp test image location: ghcr.io/radius-project/dev/ucpd:pr-funce49674cc7f
  • deployment-engine test image location: ghcr.io/radius-project/deployment-engine:latest

Test Status

⌛ Building Radius and pushing container images for functional tests...
✅ Container images build succeeded
⌛ Publishing Bicep Recipes for functional tests...
✅ Recipe publishing succeeded
⌛ Starting corerp-cloud functional tests...
⌛ Starting ucp-cloud functional tests...
✅ ucp-cloud functional tests succeeded
✅ corerp-cloud functional tests succeeded

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Updates the Radius CLI to ensure default (singleton) recipe packs exist in the fixed default scope and are linked automatically during rad init, rad env create/update (preview), and rad deploy when deploying Radius.Core/environments.

Changes:

  • Introduces pkg/cli/recipepack utilities for creating/inspecting singleton recipe packs and detecting conflicts.
  • Updates CLI flows (rad init, rad env create/update --preview, rad deploy) to create missing singleton packs in /planes/radius/local/resourceGroups/default and attach/inject their IDs.
  • Extends Radius.Core test client fakes and adds unit tests around recipe pack inspection/injection behavior.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
test/functional-portable/cli/noncloud/testdata/corerp-recipe-pack-test.bicep Updates functional test recipe pack contents.
test/functional-portable/cli/noncloud/cli_test.go Removes dev-recipe functional test that directly called radinit internals.
pkg/cli/test_client_factory/radius_core.go Adds fake server behaviors for env/recipe pack create/update and conflict simulation.
pkg/cli/recipepack/recipepack.go New shared recipe pack/singleton utilities used across commands.
pkg/cli/recipepack/recipepack_test.go New unit tests for recipe pack utilities (coverage/conflicts/extraction).
pkg/cli/cmd/utils.go Adds PopulateRecipePackClients helper for multi-scope recipe pack inspection.
pkg/cli/cmd/utils_test.go Adds tests for PopulateRecipePackClients.
pkg/cli/cmd/radinit/options.go / options_test.go Switches workspace environment IDs to Radius.Core/environments.
pkg/cli/cmd/radinit/init.go / init_test.go Wires Radius.Core client factories into rad init tests and expectations.
pkg/cli/cmd/radinit/environment.go Creates Radius.Core environments and links singleton recipe packs in default scope.
pkg/cli/cmd/env/create/preview/create.go / create_test.go Creates environments with default-scope singleton recipe packs (preview).
pkg/cli/cmd/env/update/preview/update.go / update_test.go Inspects packs, detects conflicts, ensures missing singletons (preview).
pkg/cli/cmd/deploy/deploy.go / deploy_test.go Injects missing singleton recipe pack IDs into templates before deploy.

Comment on lines +178 to +195
// if err != nil {
// return nil, fmt.Errorf("failed to get recipe pack %q: %w", name, err)
// }
// if resp.Properties != nil && resp.Properties.Recipes != nil {
// for resourceType := range resp.Properties.Recipes {
// typeToPackNames[resourceType] = append(typeToPackNames[resourceType], name)
// }
// }
// }
// conflicts := make(map[string][]string)
// for resourceType, packs := range typeToPackNames {
// if len(packs) > 1 {
// conflicts[resourceType] = packs
// }
// }
// return conflicts, nil
// }

Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

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

pkg/cli/recipepack/recipepack.go contains large blocks of commented-out, duplicate implementations (CollectResourceTypesFromRecipePacks / DetectResourceTypeConflicts). This dead code makes the new package harder to maintain and risks divergence from the real implementations; delete these blocks if they’re no longer needed or move them to version control history/docs.

Suggested change
// if err != nil {
// return nil, fmt.Errorf("failed to get recipe pack %q: %w", name, err)
// }
// if resp.Properties != nil && resp.Properties.Recipes != nil {
// for resourceType := range resp.Properties.Recipes {
// typeToPackNames[resourceType] = append(typeToPackNames[resourceType], name)
// }
// }
// }
// conflicts := make(map[string][]string)
// for resourceType, packs := range typeToPackNames {
// if len(packs) > 1 {
// conflicts[resourceType] = packs
// }
// }
// return conflicts, nil
// }

Copilot uses AI. Check for mistakes.

// Extract symbolic name from patterns like:
// [reference('mypack').id]
// [resourceId('Radius.Core/recipePacks', 'name')]
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

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

findReferencedRecipePackNames()’s comment mentions parsing [resourceId('Radius.Core/recipePacks', 'name')], but extractSymbolicNameFromExpression() only handles reference('...') expressions. Either implement resourceId parsing or remove it from the comment to avoid misleading future changes.

Suggested change
// [resourceId('Radius.Core/recipePacks', 'name')]

Copilot uses AI. Check for mistakes.
Comment on lines +150 to +156
for _, packIDStr := range packIDs {
// This is the bicep reference for id, and cannot be invalid.
packID, _ := resources.Parse(packIDStr)
scope := packID.RootScope()
if _, exists := clientsByScope[scope]; exists {
continue
}
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

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

PopulateRecipePackClients ignores errors from resources.Parse. If packIDs contains an invalid ID (or an ARM expression that slipped through), Parse will return an error and packID.RootScope() will default to "/", causing an incorrect client to be created (or overwriting clientsByScope["/"]). Handle the error (skip invalid IDs like InspectRecipePacks does, or return a validation error) instead of discarding it.

Copilot uses AI. Check for mistakes.
Comment on lines +150 to +163
t.Run("no-op for empty packIDs", func(t *testing.T) {
clientsByScope := map[string]*v20250801preview.RecipePacksClient{
scope: {}, // placeholder client
}

err := PopulateRecipePackClients(context.Background(), &workspaces.Workspace{Scope: scope}, clientsByScope, nil)
require.NoError(t, err)
require.Len(t, clientsByScope, 1)
})

t.Run("skips packs whose scope is already in the map", func(t *testing.T) {
clientsByScope := map[string]*v20250801preview.RecipePacksClient{
scope: {},
}
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

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

The test initializes a map[string]*RecipePacksClient with scope: {}. {} is not a valid value for a pointer type and will not compile; use &v20250801preview.RecipePacksClient{} (or another non-nil placeholder) instead.

Copilot uses AI. Check for mistakes.
Comment on lines 748 to 750
if _, exists := coveredTypes[resourceType]; !exists {
coveredTypes[resourceType] = packName
}
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

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

When merging resource-type coverage from template-defined recipe packs (ARM expression references), conflicts are not detected if a resource type is already covered by a literal pack (or by another template-defined pack). This can allow environments to be deployed with two packs providing the same resource type without raising a conflict. Track pack lists per resource type for both sources and surface conflicts consistently.

Suggested change
if _, exists := coveredTypes[resourceType]; !exists {
coveredTypes[resourceType] = packName
}
if existingPack, exists := coveredTypes[resourceType]; exists {
if existingPack != packName {
return fmt.Errorf("resource type %q is provided by multiple recipe packs: %q and %q", resourceType, existingPack, packName)
}
}
coveredTypes[resourceType] = packName

Copilot uses AI. Check for mistakes.
Comment on lines 138 to 141
// Run implements create-or-update semantics. If the environment does not exist, it creates
// a new one with all singleton recipe packs for core resource types. If the environment
// already exists, it checks the existing recipe packs and fills in any missing singletons
// for core resource types, detecting conflicts along the way.
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

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

The Run() doc comment says this command “checks the existing recipe packs … detecting conflicts”, but the implementation always calls runCreate(), which unconditionally sets RecipePacks to the singleton set and does not inspect existing environment state. Update the comment to match current behavior or implement the described create-or-update/conflict logic.

Suggested change
// Run implements create-or-update semantics. If the environment does not exist, it creates
// a new one with all singleton recipe packs for core resource types. If the environment
// already exists, it checks the existing recipe packs and fills in any missing singletons
// for core resource types, detecting conflicts along the way.
// Run creates a new environment with all singleton recipe packs for core resource types.
// It does not inspect existing environment state or perform conflict detection.

Copilot uses AI. Check for mistakes.
@nithyatsu nithyatsu marked this pull request as draft February 19, 2026 19:04
Signed-off-by: nithyatsu <nithyasu@microsoft.com>
Signed-off-by: nithyatsu <nithyasu@microsoft.com>

rad init implementation

Signed-off-by: nithyatsu <nithyasu@microsoft.com>

name default pack

Signed-off-by: nithyatsu <nithyasu@microsoft.com>

add tests

Signed-off-by: nithyatsu <nithyasu@microsoft.com>

wip

Signed-off-by: nithyatsu <nithyasu@microsoft.com>

rad init cahnges

Signed-off-by: nithyatsu <nithyasu@microsoft.com>

wip

Signed-off-by: nithyatsu <nithyasu@microsoft.com>

wip

Signed-off-by: nithyatsu <nithyasu@microsoft.com>

wip

Signed-off-by: nithyatsu <nithyasu@microsoft.com>

renames

Signed-off-by: nithyatsu <nithyasu@microsoft.com>

create upadtes

Signed-off-by: nithyatsu <nithyasu@microsoft.com>

update

Signed-off-by: nithyatsu <nithyasu@microsoft.com>

wip

Signed-off-by: nithyatsu <nithyasu@microsoft.com>

deploy changes

Signed-off-by: nithyatsu <nithyasu@microsoft.com>

wip

Signed-off-by: nithyatsu <nithyasu@microsoft.com>

wip

Signed-off-by: nithyatsu <nithyasu@microsoft.com>

wip

Signed-off-by: nithyatsu <nithyasu@microsoft.com>

refactor + comments

Signed-off-by: nithyatsu <nithyasu@microsoft.com>

deploy fix

Signed-off-by: nithyatsu <nithyasu@microsoft.com>

fix

Signed-off-by: nithyatsu <nithyasu@microsoft.com>

remove dev recipe test

Signed-off-by: nithyatsu <nithyasu@microsoft.com>

wip

Signed-off-by: nithyatsu <nithyasu@microsoft.com>

ci: retrigger

ci: retrigger

ci: retrigger
Signed-off-by: nithyatsu <nithyasu@microsoft.com>
Signed-off-by: nithyatsu <nithyasu@microsoft.com>
Signed-off-by: nithyatsu <nithyasu@microsoft.com>
Signed-off-by: nithyatsu <nithyasu@microsoft.com>
Signed-off-by: nithyatsu <nithyasu@microsoft.com>
Signed-off-by: nithyatsu <nithyasu@microsoft.com>
Signed-off-by: nithyatsu <nithyasu@microsoft.com>
Signed-off-by: nithyatsu <nithyasu@microsoft.com>
Signed-off-by: nithyatsu <nithyasu@microsoft.com>
Signed-off-by: nithyatsu <nithyasu@microsoft.com>
@nithyatsu nithyatsu requested a deployment to external-contributor-approval February 19, 2026 23:39 — with GitHub Actions Waiting
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.

update rad init

1 participant