Skip to content

Add deploy workflow - #12250

Closed
sk593 wants to merge 9 commits into
mainfrom
add-deploy-workflow
Closed

sk593 wants to merge 9 commits into
mainfrom
add-deploy-workflow

Conversation

@sk593

@sk593 sk593 commented Jun 25, 2026 •

Copy link
Copy Markdown
Contributor

Description

Adds the Repo Radius deploy workflow — an auto-generated GitHub Actions workflow that deploys a Radius application against a user's existing AKS/EKS cluster, plus its contract documentation and the radius-deploy skill that drives it.

The workflow stands up an ephemeral k3d Radius control plane on the runner, points it at the user's external target cluster via the chart's targetCluster seam, restores persisted state, runs rad deploy on .radius/app.bicep, then persists state again and tears the ephemeral cluster down.

How the workflow works

  1. Authenticate via OIDC — azure/login and/or aws-actions/configure-aws-credentials; no long-lived cloud secrets are stored.
  2. Connect to the target cluster — fetches a kubeconfig for the user's AKS/EKS cluster into RADIUS_TARGET_KUBECONFIG (EKS uses a static bearer-token kubeconfig).
  3. Stand up the control plane — installs k3d, the rad CLI (edge), and Terraform, then installs Radius with --set global.targetCluster.enabled=true, --set database.enabled=true (durable state), and --set dynamicrp.buildkit.enabled=true (in-pod image builds).
  4. Project cloud OIDC tokens into the Radius pods and register the cloud identity with rad credential register.
  5. Restore state (rad startup) — restores the control-plane PostgreSQL databases and Terraform recipe-state Secrets from the radius-state git orphan branch (no-op on first run).
  6. Register resource types + recipe pack — clones resource-types-contrib, registers Radius.Compute/containerImages, and creates the environment with a provider-specific Terraform recipe pack.
  7. Deploy the application — runs rad deploy .radius/app.bicep with the image parameter (defaults to the commit SHA) and the optional password parameter from RADIUS_DB_PASSWORD.
  8. Persist state (rad shutdown, if: always()) — backs the databases and Terraform state up to the radius-state branch even on failure.
  9. Tear down — deletes the ephemeral radius-cp cluster; on failure, logs are uploaded as the radius-logs artifact.

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).
  • This pull request is a design document and only includes files in the eng/design-notes directory.

Fixes: #12118

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 is added or updated under eng/design-notes/ in this 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 resource-types-contrib is created, if resource types or recipes are affected by the changes in this PR.
    • Yes
    • Not applicable
  • A PR for dashboard is created, if the Radius Dashboard is 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

@github-actions

github-actions Bot commented Jun 25, 2026 •

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

OpenSSF Scorecard

PackageVersionScoreDetails
actions/actions/checkout df4cb1c069e1874edd31b4311f1884172cec0e10 🟢 7
Details
CheckScoreReason
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Code-Review🟢 10all changesets reviewed
Maintained🟢 1018 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Binary-Artifacts🟢 10no binaries found in the repo
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Packaging⚠️ -1packaging workflow not detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Pinned-Dependencies⚠️ 3dependency not pinned by hash detected -- score normalized to 3
Signed-Releases⚠️ -1no releases found
Security-Policy🟢 9security policy file detected
SAST🟢 10SAST tool is run on all commits
Branch-Protection🟢 6branch protection is not maximal on development and all release branches

Scanned Files

  • .github/workflows/functional-test-noncloud.yaml

Comment thread .github/extension/radius-deploy.yml Outdated
@github-actions

github-actions Bot commented Jun 25, 2026 •

Copy link
Copy Markdown

Unit Tests

    2 files  ± 0    452 suites  +2   7m 27s ⏱️ -7s
5 679 tests +88  5 677 ✅ +88  2 💤 ±0  0 ❌ ±0 
6 876 runs  +88  6 874 ✅ +88  2 💤 ±0  0 ❌ ±0 

Results for commit 8ac11a8. ± Comparison against base commit 62b741f.

This pull request removes 33 and adds 121 tests. Note that renamed tests count towards both.
github.com/radius-project/radius/pkg/corerp/api/v20250801preview ‑ TestBicepConfig_ConvertFrom_TwoEntriesAreDistinct
github.com/radius-project/radius/pkg/corerp/api/v20250801preview ‑ TestBicepConfig_ConvertFrom_Wrong_Type
github.com/radius-project/radius/pkg/corerp/api/v20250801preview ‑ TestBicepConfig_ConvertTo_AwsIrsa
github.com/radius-project/radius/pkg/corerp/api/v20250801preview ‑ TestBicepConfig_ConvertTo_AzureWI
github.com/radius-project/radius/pkg/corerp/api/v20250801preview ‑ TestBicepConfig_ConvertTo_BasicAuth
github.com/radius-project/radius/pkg/corerp/api/v20250801preview ‑ TestBicepConfig_ConvertTo_EmptyRegistryAuthentications
github.com/radius-project/radius/pkg/corerp/api/v20250801preview ‑ TestBicepConfig_ConvertTo_NilEntrySkipped
github.com/radius-project/radius/pkg/corerp/api/v20250801preview ‑ TestBicepConfig_RoundTrip_Identity
github.com/radius-project/radius/pkg/corerp/api/v20250801preview ‑ TestTerraformConfig_ConvertFrom_Wrong_Type
github.com/radius-project/radius/pkg/corerp/api/v20250801preview ‑ TestTerraformConfig_ConvertTo_Both
…
github.com/radius-project/radius/pkg/armrpc/api/v1 ‑ TestFromARMRequest_PrefersURLWhenRefererResourceDiffers
github.com/radius-project/radius/pkg/armrpc/api/v1 ‑ TestFromARMRequest_PrefersURLWhenRefererResourceDiffers/referer_for_a_different_resource_uses_url
github.com/radius-project/radius/pkg/armrpc/api/v1 ‑ TestFromARMRequest_PrefersURLWhenRefererResourceDiffers/referer_for_same_resource_preserves_original_casing
github.com/radius-project/radius/pkg/armrpc/api/v1 ‑ TestFromARMRequest_PrefersURLWhenRefererResourceDiffers/referer_omitted_uses_url
github.com/radius-project/radius/pkg/armrpc/api/v1 ‑ TestFromARMRequest_PrefersURLWhenRefererResourceDiffers/url_routing_prefix_is_not_treated_as_a_different_resource
github.com/radius-project/radius/pkg/cli/deployment ‑ Test_defaultContainerName
github.com/radius-project/radius/pkg/cli/deployment ‑ Test_defaultContainerName/legacy_pod_uses_the_radius_resource_label_as_the_container_name
github.com/radius-project/radius/pkg/cli/deployment ‑ Test_defaultContainerName/preview_pod_with_a_single_container_uses_that_container_name
github.com/radius-project/radius/pkg/cli/deployment ‑ Test_defaultContainerName/preview_pod_with_multiple_containers_returns_empty_so_caller_requires_--container
github.com/radius-project/radius/pkg/cli/deployment ‑ Test_defaultContainerName/preview_pod_with_no_containers_returns_empty
…

♻️ This comment has been updated with latest results.

@codecov

codecov Bot commented Jun 25, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 53.03%. Comparing base (62b741f) to head (8ac11a8).
⚠️ Report is 26 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #12250      +/-   ##
==========================================
+ Coverage   52.87%   53.03%   +0.16%     
==========================================
  Files         751      755       +4     
  Lines       48353    48793     +440     
==========================================
+ Hits        25566    25879     +313     
- Misses      20387    20479      +92     
- Partials     2400     2435      +35     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@sk593 sk593 added the pr:standard Ongoing maintenance, minor improvements, documentation updates, and routine development work label Jun 25, 2026
sk593 added 4 commits June 25, 2026 15:38
Signed-off-by: sk593 <shruthikumar@microsoft.com>
Signed-off-by: sk593 <shruthikumar@microsoft.com>
Signed-off-by: Shruthi Kumar <shruthikumar2401@gmail.com>
Signed-off-by: sk593 <shruthikumar@microsoft.com>
@sylvainsf

Copy link
Copy Markdown
Contributor

Review: PR #12250 — Add deploy workflow

Reviewer: @sylvainsf · Against: Repo Radius feature spec (#12078, Investments 3 & 4) and issue #12118

Summary

Strong real-world deploy workflow — the recipe-pack/environment model, the
container-image build path, and the OIDC credential handling are more complete
than the earlier draft, and it absorbed the full end-to-end statestore test
(install → deploy → rad shutdown → teardown → reinstall → rad startup →
cross-deploy) and its CI leg unchanged. The main concern is drift from the
standardized Investment 3 contract
: this is a deploy-only workflow, not the
general radius_commands engine the spec defines, and it’s missing the
per-command output artifacts and a design note. One hardcoded personal ref must
change before merge.

What’s good (keep as-is)

  • Recipe pack + Radius.Core/environments generated and deployed, with
    provider-gated recipes (AWS RDS vs Azure Flexible Server). This is the shape
    ongoing projects need.
  • Container image build path — dynamicrp.buildkit.enabled=true, oras,
    traefik disabled, in-pod BuildKit + GHCR push secret, containerImages recipe
    and local Bicep extension.
  • Credential model — rad credential register aws irsa / azure wi plus
    projected OIDC token files. For AWS this is more faithful to the real code path
    (UCP AWS proxy + Terraform provider read the IRSA token file) than env-var
    injection. Prefer this approach.
  • radius-deploy skill and SHA-pinned actions.

Blocking

1. Hardcoded personal recipe ref

.github/extension/radius-deploy.yml (Azure mySQL recipe, ~line 410):

source: 'git::$REPO//Data/mySqlDatabases/recipes/azure/terraform?ref=sk593/add-azure-mysql-recipe'

Pinned to a personal in-flight branch — it will break once that branch
moves/merges. Replace with the stable ref ($REF / main) before merge.

Spec gaps (Investment 3 contract)

2. Dispatch contract: image instead of radius_commands

The spec (Step 3, Investment 3) defines the inputs as environment +
radius_commands — a single command string or a JSON array, executed in
order, stopping on first failure. This workflow exposes environment + image
and hardcodes rad deploy .radius/app.bicep, so it’s deploy-only: app graph
and multi-command flows can’t be expressed, and frontends can’t drive arbitrary
rad commands through the documented seam.

3. No per-command output artifacts

Spec Step 5 / Investment 3 require each command’s output to be uploaded as an
artifact so a frontend can poll results incrementally. This workflow only
uploads radius-logs on failure — there’s no success-path radius-output.

4. No eng/design-note

Nicole has asked for a technical design note for this feature. The PR ships the
skill + README but no durable design doc under
eng/design-notes/environments/. (One was drafted for the earlier workflow PR
and can be ported.)

Non-blocking / review-worthy

  • Mutates the user’s source in place — sed -i injects
    extension radiusCompute into .radius/app.bicep. Side-effecting on a
    user-owned file during deploy is surprising; consider working on a copy or
    guarding it.
  • Demo-specific cruft — log collection hardcodes default-todo-list-app and
    the dbsecret name. Harmless but worth genericizing.
  • rad credential register reintroduced — deliberately, and I think
    correctly for the IRSA/WI token-file model, but note it diverges from spec note
    SN29 (“no need for rad credential commands”). Worth a one-line rationale in
    the README so the divergence is intentional and documented.

Recommendation

  1. Keep this PR’s credential model, recipe pack, image-build path, and skill.
  2. Add the radius_commands dispatch contract (single-string-or-JSON-array,
    ordered, stop-on-first-failure) + per-command radius-output artifact.
  3. Add the eng/design-note (required by Nicole).
  4. Replace the sk593/add-azure-mysql-recipe ref.
  5. Test + CI leg are already settled (identical to the earlier draft) — no action.

Note: gaps #2 (the radius_commands contract, added alongside image so
the default deploy is unchanged), #3 (per-command radius-output artifact), and
#4 (the design note) are addressed in #12264, opened against this branch.
#1 (the hardcoded recipe ref) and the non-blocking items are left for you.

…12264)

# Description

Adds onto #12250 the two items the Repo Radius feature spec requires for
Investment 3 that aren't in the deploy workflow yet: the
**`radius_commands`
dispatch contract** and a **technical design note**. Targets the
`add-deploy-workflow` branch so it folds into #12250.

## What this adds

### `radius_commands` dispatch input (additive — `image` unchanged)

The feature spec (Step 3, Investment 3) defines the workflow's dispatch
contract as
`environment` + `radius_commands`: a single `rad` command string, or a
JSON array of
command strings run in order (the `rad` prefix omitted), so a frontend
can drive
arbitrary `rad` commands — not only a single deploy.

This adds `radius_commands` as an **optional** input alongside the
existing `image`:

- When `radius_commands` is set, the workflow runs each command in
order, stops on
the first failure, and uploads each command's output as the
`radius-output`
  artifact for incremental frontend polling (spec Step 5).
- When it's empty, the workflow runs its existing default `rad deploy`
of
`.radius/app.bicep` with the `image`/`password` parameters — **current
behavior is
  unchanged**.

This keeps the convenient single-deploy path while making the documented
multi-command contract available to frontends (Copilot app, CLI, etc.).

### Technical design note

`eng/design-notes/environments/2026-06-repo-radius-deploy-workflow.md` —
the design
doc Nicole requires for this feature. It documents Investments 3 & 4:
the dispatch
contract, the `RADIUS_TARGET_KUBECONFIG` seam, the UCP-credential +
projected-OIDC-
token model (AWS IRSA / Azure WI), state persistence, and the
recipe-pack /
image-build flow as implemented in #12250.

## Notes

- Co-authored design note (sk593 + sylvainsf) reflecting the #12250
implementation,
  not the earlier prototype.
- The `radius-output` artifact uses the same SHA-pinned
`upload-artifact` already in
  the workflow.

## Type of change

- This pull request adds or changes features of Radius and has an
approved issue (issue link required).

Related: #12118
Builds on: #12250

## Contributor checklist

- An overview of proposed schema changes is included in a linked GitHub
issue.
    - [ ] Yes
    - [x] Not applicable
- A design document is added or updated under `eng/design-notes/` in
this repository, if new APIs are being introduced.
    - [x] Yes
    - [ ] Not applicable
- The design document has been reviewed and approved by Radius
maintainers/approvers.
    - [ ] Yes
    - [x] Not applicable
- A PR for
[resource-types-contrib](https://github.com/radius-project/resource-types-contrib/)
is created, if resource types or recipes are affected by the changes in
this PR.
    - [ ] Yes
    - [x] Not applicable
- A PR for [dashboard](https://github.com/radius-project/dashboard/) is
created, if the Radius Dashboard is affected by the changes in this PR.
    - [ ] Yes
    - [x] Not applicable
- A PR for the [documentation
repository](https://github.com/radius-project/docs) is created, if the
changes in this PR affect the documentation or any user facing updates
are made.
    - [ ] Yes
    - [x] Not applicable

---------

Signed-off-by: Sylvain Niles <sylvainniles@microsoft.com>
@sylvainsf sylvainsf mentioned this pull request Jun 30, 2026
6 of 12 tasks
Signed-off-by: sk593 <shruthikumar@microsoft.com>
Comment on lines +26 to +47
run: |
git clone --depth 1 --branch "$RESOURCE_TYPES_CONTRIB_REF" "$RESOURCE_TYPES_CONTRIB_REPO" /tmp/resource-types-contrib

for TYPE_YAML in \
Compute/containerImages/containerImages.yaml; do
if [ -f "/tmp/resource-types-contrib/$TYPE_YAML" ]; then
echo "Registering $TYPE_YAML..."
rad resource-type create -f "/tmp/resource-types-contrib/$TYPE_YAML" || \
(echo "Retrying after 5s..." && sleep 5 && rad resource-type create -f "/tmp/resource-types-contrib/$TYPE_YAML")
else
echo "Skipping $TYPE_YAML (not found)"
fi
done
echo "✅ Resource types registered"

# Build a local Bicep extension from the containerImages type definition.
CONTAINER_IMAGES_YAML="/tmp/resource-types-contrib/Compute/containerImages/containerImages.yaml"
if [ -f "$CONTAINER_IMAGES_YAML" ]; then
echo "Building local Bicep extension for containerImages..."
rad bicep publish-extension -f "$CONTAINER_IMAGES_YAML" --target ./radiuscompute.tgz --force
echo "✅ radiuscompute.tgz built"
fi
Comment on lines +106 to +276
run: |
# pipefail so a failed `rad` whose output is piped through `tee` is detected
# via PIPESTATUS rather than masked by tee's exit code.
set -o pipefail
mkdir -p /tmp/radius-output
RESULT_FILE=/tmp/radius-output/rad-commands-result.json

# Ensure the radiusCompute extension is imported for Radius.Compute/containerImages.
# Without it, the Bicep compiler routes Radius.Compute types to Azure ARM instead of UCP.
if ! grep -q 'extension radiusCompute' "$APP_FILE" 2>/dev/null; then
echo "Injecting 'extension radiusCompute' into $APP_FILE"
sed -i '/^extension radius$/a extension radiusCompute' "$APP_FILE" 2>/dev/null || true
fi


# Aggregate result accumulators. The result is written by a trap on EXIT so
# the combined `rad-commands-result` artifact is complete even when a command
# fails and the step exits early.
COMMANDS_JSON='[]'
OVERALL_OUTCOME="succeeded"
OVERALL_EXIT=0
REQUESTED=0
RAN=0

write_result() {
jq -n \
--arg outcome "$OVERALL_OUTCOME" \
--argjson exitCode "$OVERALL_EXIT" \
--arg environment "$ENVIRONMENT" \
--argjson requested "$REQUESTED" \
--argjson ran "$RAN" \
--argjson commands "$COMMANDS_JSON" \
'{schemaVersion:"1.0", outcome:$outcome, exitCode:$exitCode, environment:$environment, commandsRequested:$requested, commandsRan:$ran, commands:$commands}' \
> "$RESULT_FILE"
}
trap write_result EXIT

# Allowed-command set. Each command's leading verb must be in this list, so
# commands that do not fit the ephemeral, per-run model — managing or
# upgrading a control plane, switching workspaces, or changing install state —
# cannot run. Validation happens before any command runs, so a disallowed
# command fails fast (exit 2) without deploying anything.
ALLOWED_VERBS="deploy app resource env recipe group credential resource-type version bicep"
is_allowed() {
local verb="${1%% *}"
case " $ALLOWED_VERBS " in *" $verb "*) return 0 ;; *) return 1 ;; esac
}

# Record one command's result into the combined artifact. Keeps live console
# output via tee while capturing it for the artifact.
record() {
local index="$1"; shift
local display="$1"; shift
local outfile code
outfile=$(mktemp)
echo "::group::rad $display"
"$@" 2>&1 | tee "$outfile"
code=${PIPESTATUS[0]}
echo "::endgroup::"
RAN=$((RAN + 1))
COMMANDS_JSON=$(jq \
--argjson index "$index" \
--arg cmd "$display" \
--argjson code "$code" \
--arg outcome "$([ "$code" -eq 0 ] && echo succeeded || echo failed)" \
--rawfile out "$outfile" \
'. + [{index:$index, command:$cmd, outcome:$outcome, exitCode:$code, output:$out}]' \
<<<"$COMMANDS_JSON")
rm -f "$outfile"
return "$code"
}

if [ -n "${RAD_COMMANDS//[[:space:]]/}" ]; then
# Caller-supplied commands: a single command string or a JSON array, run in
# order with the `rad` prefix omitted.
if printf '%s' "$RAD_COMMANDS" | jq -e 'type == "array"' >/dev/null 2>&1; then
mapfile -t COMMANDS < <(printf '%s' "$RAD_COMMANDS" | jq -r '.[]')
else
COMMANDS=("$RAD_COMMANDS")
fi

# Drop blank entries and validate every command before running any of them.
CLEAN=()
for cmd in "${COMMANDS[@]}"; do
[ -z "${cmd//[[:space:]]/}" ] && continue
CLEAN+=("$cmd")
done
REQUESTED=${#CLEAN[@]}

for cmd in "${CLEAN[@]}"; do
if ! is_allowed "$cmd"; then
OVERALL_OUTCOME="disallowed_command"
OVERALL_EXIT=2
COMMANDS_JSON=$(jq --arg cmd "$cmd" \
'. + [{command:$cmd, outcome:"disallowed", exitCode:2, errorMessage:"Command leading verb is not in the allowed-command set."}]' \
<<<"$COMMANDS_JSON")
echo "Disallowed command: rad $cmd" >&2
exit 2
fi
done

idx=0
for cmd in "${CLEAN[@]}"; do
verb="${cmd%% *}"
if [ "$verb" = "deploy" ]; then
# For deploy commands, append the image and the secret application
# parameters. Build an argv array so secret values with special
# characters are never word-split, and keep them out of the
# recorded command string (only the non-secret `$cmd` is recorded).
# shellcheck disable=SC2086
read -ra CMD_ARGV <<< "$cmd"
EXTRA_PARAMS=()
if [ -n "$APP_IMAGE" ]; then
EXTRA_PARAMS+=(--parameters "image=$APP_IMAGE")
fi
if [ -n "${RADIUS_DEPLOY_PARAMS//[[:space:]]/}" ]; then
while IFS= read -r _pname; do
[ -z "$_pname" ] && continue
_pval=$(printf '%s' "$RADIUS_DEPLOY_PARAMS" | jq -r --arg k "$_pname" '.[$k]')
EXTRA_PARAMS+=(--parameters "$_pname=$_pval")
done < <(printf '%s' "$RADIUS_DEPLOY_PARAMS" | jq -r 'keys_unsorted[]')
fi
if ! record "$idx" "$cmd" rad "${CMD_ARGV[@]}" "${EXTRA_PARAMS[@]}"; then
OVERALL_OUTCOME="command_failed"
OVERALL_EXIT=1
echo "Command failed: rad $cmd" >&2
exit 1
fi
else
# Intentional word-split: the command string carries its own args.
# shellcheck disable=SC2086
if ! record "$idx" "$cmd" rad $cmd; then
OVERALL_OUTCOME="command_failed"
OVERALL_EXIT=1
echo "Command failed: rad $cmd" >&2
exit 1
fi
fi
idx=$((idx + 1))
done
echo "✅ Radius commands complete."
else
# Default behavior: deploy the app bicep. Build the parameters as an array
# so values with special characters are not mangled by the shell.
REQUESTED=1
DEPLOY_PARAMS=()
if [ -n "$APP_IMAGE" ]; then
DEPLOY_PARAMS+=(--parameters "image=$APP_IMAGE")
fi
# Expand the application parameters JSON ({"name":"value", …}) into
# --parameters name=value pairs. Each value is read back from the JSON
# by key with jq so embedded '=', spaces, or newlines are preserved and
# never re-split by the shell.
if [ -n "${RADIUS_DEPLOY_PARAMS//[[:space:]]/}" ]; then
while IFS= read -r _pname; do
[ -z "$_pname" ] && continue
_pval=$(printf '%s' "$RADIUS_DEPLOY_PARAMS" | jq -r --arg k "$_pname" '.[$k]')
DEPLOY_PARAMS+=(--parameters "$_pname=$_pval")
done < <(printf '%s' "$RADIUS_DEPLOY_PARAMS" | jq -r 'keys_unsorted[]')
fi
# The recorded command string omits the parameters so secret values are
# not written into the result artifact.
if ! record 0 "deploy $APP_FILE --environment $ENVIRONMENT" \
rad deploy "$APP_FILE" --environment "$ENVIRONMENT" "${DEPLOY_PARAMS[@]}"; then
OVERALL_OUTCOME="command_failed"
OVERALL_EXIT=1
echo "Deployment failed" >&2
exit 1
fi
echo "✅ Deployment complete."
fi
run: |
k3d cluster create radius-cp \
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume "${{ github.workspace }}/:/app/demo" \
sk593 added a commit to radius-project/ai-extensions that referenced this pull request Jul 6, 2026
Replace the two monolithic deploy templates (deploy-azure.yml/deploy-aws.yml)
with the dispatcher + thin provider workflow structure from
radius-project/radius#12250:

- run-rad-commands.yml: unified dispatcher (the only file dispatched). Owns the
  dispatch contract and workflow_run chain off "Radius - Verify Credentials",
  detects the provider from environment vars, and calls the matching reusable
  provider workflow.
- run-rad-commands-azure.yml / run-rad-commands-aws.yml: reusable (workflow_call)
  provider workflows holding only cloud-specific steps; provider-agnostic phases
  are composite actions referenced from radius-project/radius at a pinned ref
  ({{RADIUS_REF}} = add-deploy-workflow until #12250 merges).

Generator now emits all three files (deploy.ts returns a filename->YAML map,
filling ENV/APP_FILE/RADIUS_REF); the canvas commits all three under
.github/workflows/ and removes the legacy radius-deploy.yml so it does not
double-trigger. Dispatch and run-monitoring now target run-rad-commands.yml.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
sk593 added a commit to radius-project/ai-extensions that referenced this pull request Jul 6, 2026
Replace the two monolithic deploy templates (deploy-azure.yml/deploy-aws.yml)
with the dispatcher + thin provider workflow structure from
radius-project/radius#12250:

- run-rad-commands.yml: unified dispatcher (the only file dispatched). Owns the
  dispatch contract and workflow_run chain off "Radius - Verify Credentials",
  detects the provider from environment vars, and calls the matching reusable
  provider workflow.
- run-rad-commands-azure.yml / run-rad-commands-aws.yml: reusable (workflow_call)
  provider workflows holding only cloud-specific steps; provider-agnostic phases
  are composite actions referenced from radius-project/radius at a pinned ref
  ({{RADIUS_REF}} = add-deploy-workflow until #12250 merges).

Generator now emits all three files (deploy.ts returns a filename->YAML map,
filling ENV/APP_FILE/RADIUS_REF); the canvas commits all three under
.github/workflows/ and removes the legacy radius-deploy.yml so it does not
double-trigger. Dispatch and run-monitoring now target run-rad-commands.yml.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
sk593 and others added 3 commits July 8, 2026 10:56
…12343)

## Summary

`Radius.Compute/containerImages` now ships with the published Radius
Bicep extension and its type is registered on the control plane by
Radius itself. The deploy workflow therefore no longer needs to register
the type or wire up a local Bicep extension at deploy time.

## Changes

- **Delete the `register-resource-types` composite action.** Its only
job was to clone `resource-types-contrib`, `rad resource-type create`
the `containerImages` type, and build a local `radiuscompute.tgz` Bicep
extension — all now redundant.
- **Remove the "Register resource types" step** from both provider
workflows (`run-rad-commands-aws.yml`, `run-rad-commands-azure.yml`).
- **`run-rad-commands` action:** drop the `extension radiusCompute`
injection into the app bicep and the `radiusCompute` merge/create into
the repo's `bicepconfig.json`. The app's `extension radius` import and
the user's own bicepconfig now cover `Radius.Compute/containerImages`.
- **README** updated to match.

The containerImages Terraform recipe (in-cluster image build/push) is
unchanged — it is still defined in the recipe pack.

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…12345)

## Summary

The `.github/extension/run-rad-commands-{aws,azure}.yml` reference
copies in this repo had drifted from the ai-extensions templates that
are actually generated into user repos at deploy time. This PR resyncs
them so the reviewed reference and the runtime source of truth match.

## Changes

- **Deploy `radius-env.bicep` from the app directory (both providers).**
The recipe-pack/environment step wrote `radius-env.bicep` to the
workspace root and ran `rad deploy` there. bicep resolves
`bicepconfig.json` nearest the `.bicep` file, so when the app and its
`bicepconfig.json` live under `.radius/`, the root deploy could not
resolve the `radius` extension (`extension radius`) and the
environment/recipe-pack deploy failed. Now it writes and deploys from
`dirname "$APP_FILE"` (e.g. `.radius/`), picking up the repo's own
bicepconfig.
- **Azure: switch to the AVM recipe pack.** Replace the inline generated
recipe pack with the Azure Verified Modules pack downloaded from
`resource-types-contrib` (`recipepack/azure/aks-recipepack.bicep`),
matching the ai-extensions Azure template.

## Context

Follows #12343 (which removed containerImages type registration). The
AWS copy needed only the app-directory fix; the Azure copy also needed
the AVM pack swap.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Reflect that the deploy workflow no longer registers resource types
(the Radius.Compute/containerImages type ships with the published radius
Bicep extension) and that the recipe pack is deployed from the app file's
directory so the repo's own bicepconfig.json resolves the radius extension.
Azure downloads the azure-avm pack from resource-types-contrib; AWS
generates an inline pack.

Updates the design note, extension README, and radius-deploy skill:
- Drop register-resource-types from composite-action lists and mermaid.
- Rewrite the recipe-pack section for AVM download vs inline generation.
- Note the app-dir deploy / bicepconfig resolution.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Signed-off-by: sk593 <shruthikumar@microsoft.com>
@radius-functional-tests

radius-functional-tests Bot commented Jul 8, 2026 •

Copy link
Copy Markdown

Radius functional test overview

🔍 Go to test action run

Click here to see the test run details
Name Value
Repository radius-project/radius
Commit ref 91ff490
Unique ID func4260af4b39
Image tag pr-func4260af4b39
  • 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-func4260af4b39
  • 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-func4260af4b39
  • dynamic-rp test image location: ghcr.io/radius-project/dev/dynamic-rp:pr-func4260af4b39
  • controller test image location: ghcr.io/radius-project/dev/controller:pr-func4260af4b39
  • ucp test image location: ghcr.io/radius-project/dev/ucpd:pr-func4260af4b39
  • 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

@sk593 sk593 closed this Jul 8, 2026
sk593 pushed a commit that referenced this pull request Jul 8, 2026
…12264)

Adds onto #12250 the two items the Repo Radius feature spec requires for
Investment 3 that aren't in the deploy workflow yet: the
**`radius_commands`
dispatch contract** and a **technical design note**. Targets the
`add-deploy-workflow` branch so it folds into #12250.

The feature spec (Step 3, Investment 3) defines the workflow's dispatch
contract as
`environment` + `radius_commands`: a single `rad` command string, or a
JSON array of
command strings run in order (the `rad` prefix omitted), so a frontend
can drive
arbitrary `rad` commands — not only a single deploy.

This adds `radius_commands` as an **optional** input alongside the
existing `image`:

- When `radius_commands` is set, the workflow runs each command in
order, stops on
the first failure, and uploads each command's output as the
`radius-output`
  artifact for incremental frontend polling (spec Step 5).
- When it's empty, the workflow runs its existing default `rad deploy`
of
`.radius/app.bicep` with the `image`/`password` parameters — **current
behavior is
  unchanged**.

This keeps the convenient single-deploy path while making the documented
multi-command contract available to frontends (Copilot app, CLI, etc.).

`eng/design-notes/environments/2026-06-repo-radius-deploy-workflow.md` —
the design
doc Nicole requires for this feature. It documents Investments 3 & 4:
the dispatch
contract, the `RADIUS_TARGET_KUBECONFIG` seam, the UCP-credential +
projected-OIDC-
token model (AWS IRSA / Azure WI), state persistence, and the
recipe-pack /
image-build flow as implemented in #12250.

- Co-authored design note (sk593 + sylvainsf) reflecting the #12250
implementation,
  not the earlier prototype.
- The `radius-output` artifact uses the same SHA-pinned
`upload-artifact` already in
  the workflow.

- This pull request adds or changes features of Radius and has an
approved issue (issue link required).

Related: #12118
Builds on: #12250

- An overview of proposed schema changes is included in a linked GitHub
issue.
    - [ ] Yes
    - [x] Not applicable
- A design document is added or updated under `eng/design-notes/` in
this repository, if new APIs are being introduced.
    - [x] Yes
    - [ ] Not applicable
- The design document has been reviewed and approved by Radius
maintainers/approvers.
    - [ ] Yes
    - [x] Not applicable
- A PR for
[resource-types-contrib](https://github.com/radius-project/resource-types-contrib/)
is created, if resource types or recipes are affected by the changes in
this PR.
    - [ ] Yes
    - [x] Not applicable
- A PR for [dashboard](https://github.com/radius-project/dashboard/) is
created, if the Radius Dashboard is affected by the changes in this PR.
    - [ ] Yes
    - [x] Not applicable
- A PR for the [documentation
repository](https://github.com/radius-project/docs) is created, if the
changes in this PR affect the documentation or any user facing updates
are made.
    - [ ] Yes
    - [x] Not applicable

---------

Signed-off-by: Sylvain Niles <sylvainniles@microsoft.com>
sk593 pushed a commit that referenced this pull request Jul 8, 2026
…12264)

Adds onto #12250 the two items the Repo Radius feature spec requires for
Investment 3 that aren't in the deploy workflow yet: the
**`radius_commands`
dispatch contract** and a **technical design note**. Targets the
`add-deploy-workflow` branch so it folds into #12250.

The feature spec (Step 3, Investment 3) defines the workflow's dispatch
contract as
`environment` + `radius_commands`: a single `rad` command string, or a
JSON array of
command strings run in order (the `rad` prefix omitted), so a frontend
can drive
arbitrary `rad` commands — not only a single deploy.

This adds `radius_commands` as an **optional** input alongside the
existing `image`:

- When `radius_commands` is set, the workflow runs each command in
order, stops on
the first failure, and uploads each command's output as the
`radius-output`
  artifact for incremental frontend polling (spec Step 5).
- When it's empty, the workflow runs its existing default `rad deploy`
of
`.radius/app.bicep` with the `image`/`password` parameters — **current
behavior is
  unchanged**.

This keeps the convenient single-deploy path while making the documented
multi-command contract available to frontends (Copilot app, CLI, etc.).

`eng/design-notes/environments/2026-06-repo-radius-deploy-workflow.md` —
the design
doc Nicole requires for this feature. It documents Investments 3 & 4:
the dispatch
contract, the `RADIUS_TARGET_KUBECONFIG` seam, the UCP-credential +
projected-OIDC-
token model (AWS IRSA / Azure WI), state persistence, and the
recipe-pack /
image-build flow as implemented in #12250.

- Co-authored design note (sk593 + sylvainsf) reflecting the #12250
implementation,
  not the earlier prototype.
- The `radius-output` artifact uses the same SHA-pinned
`upload-artifact` already in
  the workflow.

- This pull request adds or changes features of Radius and has an
approved issue (issue link required).

Related: #12118
Builds on: #12250

- An overview of proposed schema changes is included in a linked GitHub
issue.
    - [ ] Yes
    - [x] Not applicable
- A design document is added or updated under `eng/design-notes/` in
this repository, if new APIs are being introduced.
    - [x] Yes
    - [ ] Not applicable
- The design document has been reviewed and approved by Radius
maintainers/approvers.
    - [ ] Yes
    - [x] Not applicable
- A PR for
[resource-types-contrib](https://github.com/radius-project/resource-types-contrib/)
is created, if resource types or recipes are affected by the changes in
this PR.
    - [ ] Yes
    - [x] Not applicable
- A PR for [dashboard](https://github.com/radius-project/dashboard/) is
created, if the Radius Dashboard is affected by the changes in this PR.
    - [ ] Yes
    - [x] Not applicable
- A PR for the [documentation
repository](https://github.com/radius-project/docs) is created, if the
changes in this PR affect the documentation or any user facing updates
are made.
    - [ ] Yes
    - [x] Not applicable

---------

Signed-off-by: Sylvain Niles <sylvainniles@microsoft.com>
Signed-off-by: sk593 <shruthikumar@microsoft.com>
sk593 added a commit to radius-project/ai-extensions that referenced this pull request Jul 9, 2026
Replace the two monolithic deploy templates (deploy-azure.yml/deploy-aws.yml)
with the dispatcher + thin provider workflow structure from
radius-project/radius#12250:

- run-rad-commands.yml: unified dispatcher (the only file dispatched). Owns the
  dispatch contract and workflow_run chain off "Radius - Verify Credentials",
  detects the provider from environment vars, and calls the matching reusable
  provider workflow.
- run-rad-commands-azure.yml / run-rad-commands-aws.yml: reusable (workflow_call)
  provider workflows holding only cloud-specific steps; provider-agnostic phases
  are composite actions referenced from radius-project/radius at a pinned ref
  ({{RADIUS_REF}} = add-deploy-workflow until #12250 merges).

Generator now emits all three files (deploy.ts returns a filename->YAML map,
filling ENV/APP_FILE/RADIUS_REF); the canvas commits all three under
.github/workflows/ and removes the legacy radius-deploy.yml so it does not
double-trigger. Dispatch and run-monitoring now target run-rad-commands.yml.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Signed-off-by: sk593 <shruthikumar@microsoft.com>
sk593 added a commit to radius-project/ai-extensions that referenced this pull request Jul 9, 2026
Replace the two monolithic deploy templates (deploy-azure.yml/deploy-aws.yml)
with the dispatcher + thin provider workflow structure from
radius-project/radius#12250:

- run-rad-commands.yml: unified dispatcher (the only file dispatched). Owns the
  dispatch contract and workflow_run chain off "Radius - Verify Credentials",
  detects the provider from environment vars, and calls the matching reusable
  provider workflow.
- run-rad-commands-azure.yml / run-rad-commands-aws.yml: reusable (workflow_call)
  provider workflows holding only cloud-specific steps; provider-agnostic phases
  are composite actions referenced from radius-project/radius at a pinned ref
  ({{RADIUS_REF}} = add-deploy-workflow until #12250 merges).

Generator now emits all three files (deploy.ts returns a filename->YAML map,
filling ENV/APP_FILE/RADIUS_REF); the canvas commits all three under
.github/workflows/ and removes the legacy radius-deploy.yml so it does not
double-trigger. Dispatch and run-monitoring now target run-rad-commands.yml.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Signed-off-by: sk593 <shruthikumar@microsoft.com>
brooke-hamilton pushed a commit to radius-project/ai-extensions that referenced this pull request Jul 9, 2026
* Extract verify/deploy workflows into static YAML templates

The verify and deploy GitHub Actions workflows were previously emitted from
large inline template literals inside verify.ts and deploy.ts. Move the YAML
into committed, static template files and have the generators fill placeholder
tokens instead of generating the YAML inline.

- Add radius-core/src/workflows/templates/{verify,deploy}.yml as the source of
  truth for the workflow YAML, with {{TOKEN}} placeholders for the dynamic
  pieces (env name, app file, and the platform-specific step/credential
  snippets).
- Add fillTemplate() which substitutes {{UPPER_SNAKE}} tokens via a replacer
  function so `$`-bearing values (GitHub `${{ }}` expressions, shell `$VAR`)
  are inserted verbatim and never treated as replacement patterns.
- Rewrite verify.ts and deploy.ts to import the static templates as text and
  fill tokens; output is byte-identical to the previous inline generation for
  both azure and aws platforms.
- Configure esbuild's text loader for .yml so templates are inlined into the
  bundled extension.mjs at build time; add ambient *.yml module declarations
  for both tsconfig projects and rebuild the checked-in extension.mjs.
- Ignore the local .corepack-cache/ directory.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Signed-off-by: sk593 <shruthikumar@microsoft.com>

* Add optional Client ID field to reuse existing App Registration

Expose the Azure Client ID as a visible optional input in the create-environment
form so users can supply an existing App Registration instead of auto-creating a
new one each time. The auto-setup backend already reuses a provided Client ID.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Signed-off-by: sk593 <shruthikumar@microsoft.com>

* Add dynamic app parameters and hybrid rad_commands to deploy workflow

Split the deploy workflow into provider-specific static templates
(deploy-azure.yml / deploy-aws.yml) and add support for dynamic
application parameters declared in the user's app.bicep.

- bicep.mjs: parse `param` declarations (type, @secure, defaults),
  resolve deploy params (user value > bicep default > auto-generate),
  and partition into secret/non-secret buckets for the hybrid path.
- server.mjs: /api/app-params endpoint; provision non-secret params
  inline via vars.RADIUS_RAD_COMMANDS and secret params via the
  RADIUS_DEPLOY_PARAMS secret.
- pages.mjs: render optional deploy-form fields for each app.bicep param.
- templates: RAD_COMMANDS falls back to vars.RADIUS_RAD_COMMANDS; deploy
  commands append the image and secret params via a word-split-safe argv
  array so secret values never land in the dispatch input or artifact.
- gh.mjs: fall back to the keyring token (which has `workflow` scope)
  when the injected GH_TOKEN lacks it.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Signed-off-by: sk593 <shruthikumar@microsoft.com>

* Fix containerImages registry secret namespace mismatch

The Radius.Compute/containerImages recipe loads the registry credentials
Kubernetes Secret from the environment namespace (per its README), but
the deploy workflow only created `ghcr-registry-creds` in the per-app
namespace (`<namespace>-<appname>`). The recipe therefore read a null
secret and failed with "Attempt to index null value" on
data.kubernetes_secret.registry_creds[0].data.

Create the secret in both the environment namespace and the per-app
namespace so it is found regardless of how the Radius version resolves
context.runtime.kubernetes.namespace.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Signed-off-by: sk593 <shruthikumar@microsoft.com>

* Guide app.bicep generator to use git URL for containerImages build.source

The Radius.Compute/containerImages recipe builds images in-cluster with a
BuildKit sidecar, so build.source must be a git:: URL BuildKit can clone;
a runner-local filesystem path is invisible to the pod and fails with
"invalid local: ... no such file or directory".

Add explicit generator guidance (per the containerImages README) to emit
`git::https://github.com/<owner>/<repo>.git` and to use go-getter subdir
and ?ref= for non-root Dockerfiles.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Signed-off-by: sk593 <shruthikumar@microsoft.com>

* Provision registry credentials via Radius.Security/secrets

Replace the kubectl-based registry secret creation step with an
environment-scoped Radius.Security/secrets resource in the generated
radius-env.bicep. The secret materializes into the environment namespace
where the containerImages recipe reads it. Credentials are passed as
secure deploy parameters so the token is never written into the echoed
bicep file and stays masked in logs.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Signed-off-by: sk593 <shruthikumar@microsoft.com>

* Move registry creds secret from environment to application scope

The Radius.Compute/containerImages recipe reads its registry-push
credentials from context.runtime.kubernetes.namespace — the namespace
of the containerImages resource itself, i.e. the application namespace.
The previous commit provisioned an environment-scoped
Radius.Security/secrets in the workflow-generated radius-env.bicep,
which materializes into the environment namespace instead, so the recipe
could not find the secret.

Provision the secret the correct way: an application-scoped
Radius.Security/secrets resource declared in the app's own app.bicep,
so it materializes into the app namespace the recipe reads from. The
deploy workflow no longer creates the secret; it only supplies the
credentials as secure bicep parameters to `rad deploy $APP_FILE`,
guarded so apps that do not declare the params are unaffected. The
recipe pack keeps registrySecretName: 'ghcr-registry-creds'.

- deploy-aws.yml / deploy-azure.yml: drop env-scoped ghcrCreds secret and
  its params from radius-env.bicep; inject registryUsername/registryPassword
  into the app deploy step (both default and caller-supplied deploy).
- radius-app-bicep SKILL.md: app.bicep skeleton now declares the params and
  an application-scoped ghcr-registry-creds secret with dependsOn on
  containerImages.
- Regenerate .github/radius/extension.mjs.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Signed-off-by: sk593 <shruthikumar@microsoft.com>

* Provision registry creds on control plane; fix Azure mySQL recipe params

Redesign the containerImages registry-credential flow: instead of an
app-scoped Radius.Security/secrets resource (which lands on the target
cluster where the recipe cannot read it), the deploy workflow now
provisions the ghcr-registry-creds secret directly onto the control-plane
cluster from the default GITHUB_TOKEN, where the in-pod BuildKit reads it.
Registry path is now ghcr.io/<owner>/<repo>. Removes the app-level
registryUsername/registryPassword param plumbing and the GHCR_PAT fallback.

Also drop the azure_subscription_id/resourceGroupName/location parameters
from the Azure mySQL recipe pack entry: the recipe reads those from the
Radius context (var.context.azure) via the environment providers block and
declares no such variables, so passing them failed Terraform with
"Extraneous JSON object property".

Rebuilds the canvas extension bundle from the templates.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Signed-off-by: sk593 <shruthikumar@microsoft.com>

* Remove Application Parameters input block from deploy canvas

Drop the optional Application Parameters section from the environment/deploy
page: the per-param inputs, the dynamic /api/app-params fetch/render, and the
collectDeployParams helper. The deploy submission now sends an empty
deployParams object, so the server still auto-generates values for params
without a Bicep default (e.g. the app's @secure() password) and inlines the
non-secret ones. Rebuilds the canvas extension bundle.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Signed-off-by: sk593 <shruthikumar@microsoft.com>

* Split verify workflow into per-provider static templates

Mirror the deploy workflow pattern for credential verification: instead of a
single verify.yml with provider steps injected inline from TypeScript strings,
add static verify-azure.yml and verify-aws.yml templates with each provider's
OIDC login, cluster-access checks, and provider id baked in. Only the {{ENV}}
placeholder is filled at generation time.

verify.ts now selects the template by platform.id via a VERIFY_TEMPLATES map
(same shape as deploy.ts) and throws on unknown providers. Removes the inline
verifyWorkflowSteps from platforms/azure.ts, platforms/aws.ts, and the
ComputePlatform interface, and deletes the obsolete single verify.yml.
Rebuilds the canvas extension bundle.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Signed-off-by: sk593 <shruthikumar@microsoft.com>

* Restructure deploy workflow to composite-action model (radius#12250)

Replace the two monolithic deploy templates (deploy-azure.yml/deploy-aws.yml)
with the dispatcher + thin provider workflow structure from
radius-project/radius#12250:

- run-rad-commands.yml: unified dispatcher (the only file dispatched). Owns the
  dispatch contract and workflow_run chain off "Radius - Verify Credentials",
  detects the provider from environment vars, and calls the matching reusable
  provider workflow.
- run-rad-commands-azure.yml / run-rad-commands-aws.yml: reusable (workflow_call)
  provider workflows holding only cloud-specific steps; provider-agnostic phases
  are composite actions referenced from radius-project/radius at a pinned ref
  ({{RADIUS_REF}} = add-deploy-workflow until #12250 merges).

Generator now emits all three files (deploy.ts returns a filename->YAML map,
filling ENV/APP_FILE/RADIUS_REF); the canvas commits all three under
.github/workflows/ and removes the legacy radius-deploy.yml so it does not
double-trigger. Dispatch and run-monitoring now target run-rad-commands.yml.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Signed-off-by: sk593 <shruthikumar@microsoft.com>

* Rebuild canvas bundle after rebase onto main

Reconcile the built extension.mjs with the merged source after rebasing the
deploy-workflow restructure onto the latest main.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Signed-off-by: sk593 <shruthikumar@microsoft.com>

* Switch Azure deploy to Azure Verified Module recipe pack

Replace the Azure workflow's inline Terraform recipe pack (azure-terraform)
with the Bicep Azure Verified Module recipes from
radius-project/resource-types-contrib recipepack/azure (pack name azure-avm).

Data, messaging and AI resource types (redisCaches, mongoDatabases,
mySqlDatabases, postgreSqlDatabases, sqlServerDatabases, rabbitMQ, kafka,
AI/models, AI/search) now provision real Azure resources via AVM Bicep modules
(mcr.microsoft.com/bicep/avm), and containers use the pack's Bicep kube-recipe.

Kept as-is:
- Radius.Compute/containerImages: still builds the app image from repo source
  with in-pod BuildKit; the container recipe consumes the built image.
- Radius.Compute/persistentVolumes, Radius.Compute/routes, Radius.Security/secrets:
  kept on the shared Kubernetes Terraform recipes since the AVM pack omits them,
  so apps using those types keep working.

Drops the sk593/add-azure-mysql-recipe feature-branch dependency. AWS workflow
is unchanged. Bundle rebuilt.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Signed-off-by: sk593 <shruthikumar@microsoft.com>

* Reference upstream Azure recipe pack instead of inline generation

Replace the inline azure-avm recipe pack bicep in run-rad-commands-azure.yml
with a download of resource-types-contrib's default-recipepack.bicep, pinned
to PR #218 commit 7a2fd8e. The workflow now only supplies parameters; the
recipe/pack logic lives upstream. The environment name and namespace are
passed via the new environmentName/environmentNamespace pack parameters so
the created Radius environment matches the deploy target.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Signed-off-by: sk593 <shruthikumar@microsoft.com>

* Always auto-create Azure credentials, drop existing-clientId reuse

The Azure auto-setup path previously let users pass an existing Client ID to
reuse an App Registration. Remove that branch so auto-setup always creates a
fresh App Registration, and make the canvas Client ID field a read-only
display of the generated value instead of an input.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Signed-off-by: sk593 <shruthikumar@microsoft.com>

* Drop user-input application parameters, keep required auto-generation

Application parameters are no longer taken from the UI. The env-setup form no
longer sends a deployParams object, and the server no longer merges user input
when resolving app.bicep parameters. The app.bicep is still parsed only to
auto-generate values for required parameters that have no Bicep default (e.g.
an @secure() password); defaulted params are left to Bicep.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Signed-off-by: sk593 <shruthikumar@microsoft.com>

* Track merged Azure recipe pack on main

resource-types-contrib PR #218 merged, renaming the recipe pack to
aks-recipepack.bicep. Point the Azure workflow at recipepack/azure/
aks-recipepack.bicep on main instead of the pinned PR commit.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Signed-off-by: sk593 <shruthikumar@microsoft.com>

* Stop writing bicepconfig.json from the canvas

The canvas previously generated and committed a partial .radius/bicepconfig.json
(only the `radius` extension) into the target repo. Because bicep resolves the
config nearest the .bicep file, that committed file shadowed the complete config
the deploy workflow provides, dropping the `radiusCompute` alias and breaking
Radius.Compute/containerImages resolution.

Remove all bicepconfig.json handling from the canvas. bicepconfig wiring is now
owned entirely by the deploy workflow (register-resource-types builds
radiuscompute.tgz; run-rad-commands merges the radiusCompute extension into the
repo's own bicepconfig and injects the extension into app.bicep) — all at deploy
time in the working copy, never committed back to the repo.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Signed-off-by: sk593 <shruthikumar@microsoft.com>

* Remove containerImages type registration from deploy workflows

Radius.Compute/containerImages now ships with the published Radius Bicep
extension, so the generated provider workflows no longer register the type at
deploy time.

- Drop the "Register resource types" step from the aws and azure
  run-rad-commands templates.
- Azure: remove the now-unused RESOURCE_TYPES_CONTRIB_REPO/REF env (only the
  register step used them; the recipe pack comes from the AVM pack). AWS keeps
  them — its inline recipe pack still uses them.
- Refresh the deploy.ts and server.mjs comments, rebuild the canvas bundle.

The containerImages recipe (image build/push) is unchanged.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Signed-off-by: sk593 <shruthikumar@microsoft.com>

* Deploy recipe pack from the app dir so the repo bicepconfig resolves

The environment/recipe-pack step wrote radius-env.bicep to the workspace root
and ran `rad deploy radius-env.bicep` from there. bicep resolves bicepconfig.json
nearest the .bicep file, so when the app (and the user's bicepconfig.json) live
under .radius/, the root deploy could not resolve `extension radius` and the
environment/recipe-pack deploy failed.

Write and deploy radius-env.bicep from `dirname "$APP_FILE"` (e.g. .radius/) in
both the aws and azure templates, so the repo's own bicepconfig.json is used.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Signed-off-by: sk593 <shruthikumar@microsoft.com>

* Pin deploy workflow RADIUS_REF to main

The shared composite actions (setup-control-plane, restore-state,
run-rad-commands, teardown) have merged to radius-project/radius main,
so point the generated provider workflows at @main instead of the
add-deploy-workflow feature branch.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Signed-off-by: sk593 <shruthikumar@microsoft.com>

* Pin verify-workflow actions to commit SHAs

Pin the third-party actions in the credential-verify templates to full
commit SHAs (with version comments) instead of floating version tags,
matching the already-pinned run-rad-commands provider workflows:
- actions/checkout@34e1148 (v4)
- aws-actions/configure-aws-credentials@7474bc4 (v4)
- Azure/login@a457da9 (v2)
- Azure/use-kubelogin@76597ae (v1)

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Signed-off-by: sk593 <shruthikumar@microsoft.com>

* Update deploy and app-graph skills to current architecture

The radius-deploy skill described the old radius-deploy.yml single-file
workflow (Docker-socket patching, resource-type registration,
azure-terraform recipes). Rewrite it for the run-rad-commands dispatcher
+ provider workflows + shared composite actions, in-pod BuildKit, the
azure-avm / inline AWS recipe packs, app-directory bicepconfig
resolution, and no deploy-time resource-type registration.

The radius-app-graph skill described a rad-graph-build orphan-branch
(radius-graph) data flow that no longer exists; the graph is now built
in-canvas from .radius/app.bicep via buildGraphFromBicep. Update the
data flow, prerequisites, and troubleshooting accordingly.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Signed-off-by: sk593 <shruthikumar@microsoft.com>

* Fetch workflow templates from radius repo instead of bundling

The extension shipped its own copies of the deploy (run-rad-commands*)
and verify (verify-*) workflow templates and committed those to user
repos. The radius repo hosts the canonical templates in
.github/extension/, so the bundled copies could silently drift (the
verify templates already had).

Now the extension fetches each template from radius-project/radius at
the pinned RADIUS_REF and fills its placeholders before committing, so
user repos always get the reviewed upstream version. The bundled
templates are kept as an offline/transient-failure fallback (per file),
so deploys still work if the radius repo can't be reached or the ref
isn't published yet.

- radius-core: generateDeployWorkflow / generateVerifyWorkflow accept
  the fetched template(s); default to the bundled BUNDLED_*_TEMPLATES.
  Export RADIUS_WORKFLOW_REPO/DIR, verify file names, and bundled maps.
- canvas adapter: infra.mjs fetches the templates from the radius repo
  (fetchFileFromRepo @ RADIUS_REF) with per-file fallback; the two
  generators are now async and awaited at their server.mjs call sites.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Signed-off-by: sk593 <shruthikumar@microsoft.com>

* Sync radius-deploy/-environment skills with radius repo facts

The canvas-side radius-deploy and radius-environment skills had drifted
from the canonical skills in radius-project/radius:

- environment: referenced the old verify workflow name
  radius-verify-credentials.yml (now verify-aws.yml / verify-azure.yml),
  a nonexistent AWS_IAM_ROLE_ARN secret and RADIUS_K8S_CLUSTER var
  (actual vars are AWS_ROLE_ARN / AWS_EKS_CLUSTER_NAME /
  AZURE_AKS_CLUSTER_NAME, variables-only), and omitted the cluster-access
  verification and the cloud-side OIDC prerequisites.
- deploy: had the older 8-step flow; updated to the accurate 9-step flow
  (target-cluster kubeconfig, --set global.targetCluster.enabled, token
  refresh, Radius.Core/environments, inline AWS recipe list) and noted
  templates are now fetched from radius-project/radius@main.

Factual content now matches the radius repo skills; the canvas-focused
framing (radius-panel canvas, hub deploy, live polling) is preserved.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Signed-off-by: sk593 <shruthikumar@microsoft.com>

* Always fetch workflow templates from radius repo, drop bundled fallback

radius-project/radius is the single source of truth for the deploy
(run-rad-commands*) and verify (verify-*) workflow templates. The
extension previously bundled its own copies as an offline fallback, which
could silently drift from upstream. Remove the bundled templates entirely
and always fetch from radius-project/radius at the pinned RADIUS_REF; a
fetch failure is now a hard error instead of falling back to a stale copy.

- radius-core: generateDeployWorkflow / generateVerifyWorkflow now require
  the fetched template(s) and throw if any are missing. Removed
  BUNDLED_*_TEMPLATES, the templates/*.yml files, and the .yml text-import
  type shims.
- canvas adapter: fetchRadiusTemplate throws on fetch failure; the two
  generators no longer pass a fallback.
- build: dropped the esbuild .yml text loader (no templates to inline);
  bundle shrinks ~379kb -> ~343kb.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Signed-off-by: sk593 <shruthikumar@microsoft.com>

* Remove tests for workflow-step properties removed in feature branch

Signed-off-by: sk593 <shruthikumar@microsoft.com>

* Update comment

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Shruthi Kumar <shruthikumar2401@gmail.com>

* Resolve remaining merge conflicts in gh.mjs and server.mjs

* Surface real fetch-error cause when pulling workflow templates

The try/catch in fetchRadiusTemplate was dead code: ghApiGetContent /
fetchFileFromRepo resolve null on any failure (network error, 404,
missing ref) and never reject, so every fetch failure collapsed into a
generic "not found" message that discarded the underlying cause.

Add Result-returning helpers ghApiGetContentResult and
fetchFileFromRepoResult in gh.mjs that surface the real gh stderr / 404 /
decode error via a { content, error } shape without rejecting. Rewrite
fetchRadiusTemplate to use the Result helper, drop the dead try/catch,
and throw with the actual cause (or an explicit "empty" message).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Signed-off-by: sk593 <shruthikumar@microsoft.com>

* fix: resolve SKILL.md merge conflict - take main's rad app graph descriptions

---------

Signed-off-by: sk593 <shruthikumar@microsoft.com>
Signed-off-by: Shruthi Kumar <shruthikumar2401@gmail.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:standard Ongoing maintenance, minor improvements, documentation updates, and routine development work

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Repo Radius verify/deploy workflows to the repo

3 participants