Fix custom recipe pack reconciliation on repeat deploys - #12742
Conversation
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
There was a problem hiding this comment.
Pull request overview
This PR updates the Repo Radius deploy workflow’s custom recipe-pack reconciliation so repeat deploys (including redeploys after state restore) deterministically attach only the recipe packs authored by the repo while preserving any recipe packs already attached to the environment.
Changes:
- Update
apply-custom-recipe-packsto derive recipe-pack identities from compiled Bicep output and attach only authored packs (plus existing attached packs). - Add a composite-action regression test suite and wire it into
make test. - Update Repo Radius workflow documentation to reflect the new reconciliation behavior and test coverage.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
eng/design-notes/environments/2026-06-repo-radius-deploy-workflow.md |
Updates design notes to describe authored-pack identity discovery and the new focused test target. |
build/test.mk |
Adds test-apply-custom-recipe-packs and includes it in the main test target prerequisites. |
.github/extension/README.md |
Updates step-by-step workflow docs to reflect the new authored-pack reconciliation approach. |
.github/extension/actions/apply-custom-recipe-packs/apply-custom-recipe-packs_test.sh |
Adds regression coverage for first deploy, restored-state redeploy, preservation of existing packs, and failure modes. |
.github/extension/actions/apply-custom-recipe-packs/action.yml |
Changes the action to compile Bicep and resolve/attach the authored recipe packs rather than diffing global pack listings. |
Suppressed comments (1)
.github/extension/actions/apply-custom-recipe-packs/apply-custom-recipe-packs_test.sh:279
- The multi-pack fixture here models
resourcesas an object keyed by resource name, butbicep buildoften emitsresourcesas an array (languageVersion 1.x). Without an array-shaped fixture, the tests won't catch a regression where array output breaks pack discovery. Use an array fixture for this scenario to cover that output shape.
write_compiled_template '{
"custom": {
"type": "Radius.Core/recipePacks@2025-08-01-preview",
"name": "custom"
},
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #12742 +/- ##
=======================================
Coverage 59.89% 59.90%
=======================================
Files 775 775
Lines 46302 46302
=======================================
+ Hits 27734 27737 +3
+ Misses 18568 18565 -3 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
nicolejms
left a comment
There was a problem hiding this comment.
Two non-blocking observations on the discovery/attach path. Neither should hold up the merge — the fix itself is correct and the redeploy path is well covered. The first one would benefit from a regression test to pin the intended contract.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Signed-off-by: sk593 <shruthikumar@microsoft.com>
A conditionally-declared Radius.Core/recipePacks resource cannot be resolved deterministically: a runtime condition may skip it at deploy time, yet a same-named pack in restored control-plane state would still be resolved by name and wrongly attached. Reject such resources before deploying, alongside the existing dynamic-name rejection, and document the literal-name constraint. Add a regression case and update the design note. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Signed-off-by: sk593 <shruthikumar@microsoft.com>
Radius extensibility resources compile the resource name to .properties.name, not a top-level .name; the discovery jq read .name and would resolve every authored pack to null, failing the action on real deploys. Read .properties.name (with a top-level .name fallback) and fix the test fixtures, which previously used an unrealistic top-level name and hid the defect. Verified against templates compiled by the Radius bicep binary. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Signed-off-by: sk593 <shruthikumar@microsoft.com>
Relax the recipe-pack discovery jq to accept both object-keyed (languageVersion 2.0) and array-shaped (languageVersion 1.x) bicep build output, and add an array-shaped regression fixture. Radius extensibility templates always emit the object form, but accepting both removes any dependence on the compiled layout. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Signed-off-by: sk593 <shruthikumar@microsoft.com>
Exclude existing recipe-pack references from authored-pack discovery, add regression coverage, and document the contract. Remove the unreachable empty pack-list guard now that authored pack discovery requires at least one resolvable pack. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Signed-off-by: sk593 <shruthikumar@microsoft.com>
f645b93 to
cbe2129
Compare
…ve-custom-recipe-pack Signed-off-by: sk593 <shruthikumar@microsoft.com> # Conflicts: # build/test.mk
…ve-custom-recipe-pack Signed-off-by: sk593 <shruthikumar@microsoft.com> # Conflicts: # build/test.mk
Radius functional test overviewClick here to see the test run details
Test Status⌛ Building Radius and pushing container images for functional tests... |
….1 (#12831) Patch release `v0.60.1` for channel `0.60`. ## Backported PRs Listed in cherry-pick (topological) order. **Gap filler** = not requested for the patch, but included because it touched the same region of a shared file between `release/0.60` and a requested commit. Without it the cherry-pick has no common merge base and conflicts. | # | Commit | PR | Role | | --- | --- | --- | --- | | 1 | `6882b5fdf` | #12640 | Requested | | 2 | `af0443809` | #12721 | Requested | | 3 | `7c6de043d` | #12733 | **Gap filler** — `.github/workflows/codeql.yml` | | 4 | `ca7b5a3e7` | #12728 | Requested | | 5 | `2eac7c1f1` | #12702 | Requested | | 6 | `b4ebe2f28` | #12751 | Requested | | 7 | `e30a2594d` | #12727 | Requested | | 8 | `3c7dfecd6` | #12769 | **Gap filler** — `.github/workflows/codeql.yml` | | 9 | `787b6ca1a` | #12765 | **Gap filler** — `build/test.mk` | | 10 | `f84184955` | #12775 | Requested | | 11 | `415d5b9c2` | #12779 | Requested | | 12 | `a1d976013` | #12782 | Requested | | 13 | `14a21bd0d` | #12786 | **Gap filler** — `build/test.mk` | | 14 | `a87146c77` | #12764 | **Gap filler** — `build/test.mk` | | 15 | `073ca3cfa` | #12758 | Requested | | 16 | `5e1f94c13` | #12785 | **Gap filler** — `pkg/cli/cmd/install/kubernetes/kubernetes.go` | | 17 | `1fd650af5` | #12742 | Requested | | 18 | `19376c3f3` | #12829 | Requested | Five of the six gap fillers are CI/test-only. #12785 is not: it adds a Helm `control-plane-readiness` Job, a `pre-upgrade wait-for-control-plane` command, UCP readiness probes, and a NetworkPolicy change. It is required for #12829 to apply. ## Validation Full chain dry-run cherry-picked onto `release/0.60` with zero conflicts. `go build ./...` clean; `pkg/cli/cmd/install/kubernetes`, `cmd/pre-upgrade/cmd`, `pkg/cli/...`, `pkg/graph/...`, and `test/validation` all pass. --------- Signed-off-by: Dariusz Porowski <3431813+DariuszPorowski@users.noreply.github.com>
## Summary - derive custom recipe-pack identities from the compiled authored Bicep instead of a global before/after list diff - preserve existing environment recipe packs while attaching only the exact authored packs on first and restored-state redeploys - add composite-action regression coverage and update the Repo Radius workflow documentation ## Testing - `make test-apply-custom-recipe-packs` - `shellcheck .github/extension/actions/apply-custom-recipe-packs/apply-custom-recipe-packs_test.sh` Resolves radius-project/ai-extensions#323 --------- Signed-off-by: sk593 <shruthikumar@microsoft.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> (cherry picked from commit 1fd650a) Signed-off-by: Dariusz Porowski <3431813+DariuszPorowski@users.noreply.github.com>
….1 (#12831) Patch release `v0.60.1` for channel `0.60`. ## Backported PRs Listed in cherry-pick (topological) order. **Gap filler** = not requested for the patch, but included because it touched the same region of a shared file between `release/0.60` and a requested commit. Without it the cherry-pick has no common merge base and conflicts. | # | Commit | PR | Role | | --- | --- | --- | --- | | 1 | `6882b5fdf` | #12640 | Requested | | 2 | `af0443809` | #12721 | Requested | | 3 | `7c6de043d` | #12733 | **Gap filler** — `.github/workflows/codeql.yml` | | 4 | `ca7b5a3e7` | #12728 | Requested | | 5 | `2eac7c1f1` | #12702 | Requested | | 6 | `b4ebe2f28` | #12751 | Requested | | 7 | `e30a2594d` | #12727 | Requested | | 8 | `3c7dfecd6` | #12769 | **Gap filler** — `.github/workflows/codeql.yml` | | 9 | `787b6ca1a` | #12765 | **Gap filler** — `build/test.mk` | | 10 | `f84184955` | #12775 | Requested | | 11 | `415d5b9c2` | #12779 | Requested | | 12 | `a1d976013` | #12782 | Requested | | 13 | `14a21bd0d` | #12786 | **Gap filler** — `build/test.mk` | | 14 | `a87146c77` | #12764 | **Gap filler** — `build/test.mk` | | 15 | `073ca3cfa` | #12758 | Requested | | 16 | `5e1f94c13` | #12785 | **Gap filler** — `pkg/cli/cmd/install/kubernetes/kubernetes.go` | | 17 | `1fd650af5` | #12742 | Requested | | 18 | `19376c3f3` | #12829 | Requested | Five of the six gap fillers are CI/test-only. #12785 is not: it adds a Helm `control-plane-readiness` Job, a `pre-upgrade wait-for-control-plane` command, UCP readiness probes, and a NetworkPolicy change. It is required for #12829 to apply. ## Validation Full chain dry-run cherry-picked onto `release/0.60` with zero conflicts. `go build ./...` clean; `pkg/cli/cmd/install/kubernetes`, `cmd/pre-upgrade/cmd`, `pkg/cli/...`, `pkg/graph/...`, and `test/validation` all pass. --------- Signed-off-by: Dariusz Porowski <3431813+DariuszPorowski@users.noreply.github.com> (cherry picked from commit e5938bf) Signed-off-by: Dariusz Porowski <3431813+DariuszPorowski@users.noreply.github.com>
## Summary - derive custom recipe-pack identities from the compiled authored Bicep instead of a global before/after list diff - preserve existing environment recipe packs while attaching only the exact authored packs on first and restored-state redeploys - add composite-action regression coverage and update the Repo Radius workflow documentation ## Testing - `make test-apply-custom-recipe-packs` - `shellcheck .github/extension/actions/apply-custom-recipe-packs/apply-custom-recipe-packs_test.sh` Resolves radius-project/ai-extensions#323 --------- Signed-off-by: sk593 <shruthikumar@microsoft.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> (cherry picked from commit 1fd650a) Signed-off-by: Dariusz Porowski <3431813+DariuszPorowski@users.noreply.github.com>
….1 (#12831) Patch release `v0.60.1` for channel `0.60`. ## Backported PRs Listed in cherry-pick (topological) order. **Gap filler** = not requested for the patch, but included because it touched the same region of a shared file between `release/0.60` and a requested commit. Without it the cherry-pick has no common merge base and conflicts. | # | Commit | PR | Role | | --- | --- | --- | --- | | 1 | `6882b5fdf` | #12640 | Requested | | 2 | `af0443809` | #12721 | Requested | | 3 | `7c6de043d` | #12733 | **Gap filler** — `.github/workflows/codeql.yml` | | 4 | `ca7b5a3e7` | #12728 | Requested | | 5 | `2eac7c1f1` | #12702 | Requested | | 6 | `b4ebe2f28` | #12751 | Requested | | 7 | `e30a2594d` | #12727 | Requested | | 8 | `3c7dfecd6` | #12769 | **Gap filler** — `.github/workflows/codeql.yml` | | 9 | `787b6ca1a` | #12765 | **Gap filler** — `build/test.mk` | | 10 | `f84184955` | #12775 | Requested | | 11 | `415d5b9c2` | #12779 | Requested | | 12 | `a1d976013` | #12782 | Requested | | 13 | `14a21bd0d` | #12786 | **Gap filler** — `build/test.mk` | | 14 | `a87146c77` | #12764 | **Gap filler** — `build/test.mk` | | 15 | `073ca3cfa` | #12758 | Requested | | 16 | `5e1f94c13` | #12785 | **Gap filler** — `pkg/cli/cmd/install/kubernetes/kubernetes.go` | | 17 | `1fd650af5` | #12742 | Requested | | 18 | `19376c3f3` | #12829 | Requested | Five of the six gap fillers are CI/test-only. #12785 is not: it adds a Helm `control-plane-readiness` Job, a `pre-upgrade wait-for-control-plane` command, UCP readiness probes, and a NetworkPolicy change. It is required for #12829 to apply. ## Validation Full chain dry-run cherry-picked onto `release/0.60` with zero conflicts. `go build ./...` clean; `pkg/cli/cmd/install/kubernetes`, `cmd/pre-upgrade/cmd`, `pkg/cli/...`, `pkg/graph/...`, and `test/validation` all pass. --------- Signed-off-by: Dariusz Porowski <3431813+DariuszPorowski@users.noreply.github.com> (cherry picked from commit e5938bf) Signed-off-by: Dariusz Porowski <3431813+DariuszPorowski@users.noreply.github.com>
Summary
Testing
make test-apply-custom-recipe-packsshellcheck .github/extension/actions/apply-custom-recipe-packs/apply-custom-recipe-packs_test.shResolves radius-project/ai-extensions#323