Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions .github/extension/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,13 @@ The dispatcher routes to the matching provider workflow, which runs on `ubuntu-l
11. **Create the Radius environment and recipe pack.** `rad deploy`s a `radius-env.bicep` that defines a `Radius.Core/recipePacks` resource and the `Radius.Core/environments` resource that references it. Azure downloads the `azure-avm` pack (Azure Verified Modules) from [resource-types-contrib](https://github.com/radius-project/resource-types-contrib); AWS generates an inline `aws-terraform` pack. `radius-env.bicep` is written to the app file's directory (e.g. `.radius/`) and deployed from there, so `rad deploy` resolves the repo's own `bicepconfig.json` (which declares the `radius` extension) — bicep resolves the config nearest the `.bicep` file. The `Radius.Compute/containerImages` type ships with the Radius extension, so no separate resource-type registration is needed.
12. **Register custom types and apply custom recipe pack.** When the app's `.radius/` folder carries a `custom-types.yaml` file, the shared `apply-custom-recipe-packs` action registers those resource types with `rad resource-type create --from-file` (skipped when absent). When it carries a `custom-recipe-pack.bicep` file, the action snapshots the recipe-pack IDs before and after `rad deploy`ing that pack to identify the newly-created pack(s), reads the environment's existing `recipePacks` with `rad env show --preview`, and runs `rad env update <env> --recipe-packs <existing ∪ new> --preview` so the environment keeps the default provider pack and gains the custom pack — without pulling in unrelated packs the control plane may know about (skipped when absent). When neither file exists this step is a no-op and the default pack stays in place.
13. **Run the requested rad commands.** Validates each command in `rad_commands` against the allowed-command set, then runs them in order (stopping on the first failure) and writes a combined `rad-commands-result` artifact. Before deploying the app, the shared action compiles its Bicep file once and reads the declared ARM parameters. It passes each extension-generated parameter only when the template declares it: `image` (the workflow input, defaulting to `github.sha`), `registryUsername` (`github.actor`), and `registryPassword` (the built-in `GITHUB_TOKEN`). Caller-configured application parameters from the `RADIUS_DEPLOY_PARAMS` secret remain strict and are passed unchanged. The registry parameters feed the app's `Radius.Security/secrets` resource (`radius-ghcr-registry-creds`), when present, so the containerImages recipe's in-pod BuildKit can push the application image. Secret values are passed via an argv array and never written into the recorded command string.
14. **Publish deployed graph/status artifact.** Whenever the run is not cancelled (`if: !cancelled()`), the shared `publish-deploy-status` action runs `rad app graph --application <app> --preview --include-icons --output json` against the live control plane and publishes `deploy-graph.json` plus sibling status files (`deploy-progress.log` — per-resource provisioning state, `deploy-activity.log` — the rad command result envelope, `deploy-controlplane.log` — control-plane health, `deploy-state.txt`) as a single OCI artifact in GHCR (`RADIUS_GRAPH_REGISTRY`, with `RADIUS_GRAPH_TAG` or a derived `<environment>-<app>-latest` tag). It publishes on failed deploys too, since that is when the Deployed graph is most useful. Publishing is best-effort: if the push fails (most often no `packages: write` on the derived graph package, which the pre-flight [GHCR package push check](#ghcr-package-push-check) does not cover because it only tests `RADIUS_STATE_REGISTRY`), the action emits a warning and leaves the deployment result unchanged.
14. **Publish deployed graph/status artifact.** Whenever the run is not cancelled (`if: !cancelled()`), the shared `publish-deploy-status` action runs `rad app graph --application <app> --preview --include-icons --output json` against the live control plane and publishes `deploy-graph.json` plus sibling status files (`deploy-progress.json` — per-resource status the canvas paints the graph from, `deploy-activity.log` — the rad command result envelope, `deploy-controlplane.log` — control-plane health, `deploy-state.txt` — a flat `key=value` summary of the run, not read by the canvas) as a **workflow artifact** named `radius-deploy-status-<environment>-<app>` (lowercased, with characters outside `[a-z0-9._-]` collapsed to `-`), retained for 30 days. It publishes on failed deploys too, since that is when the Deployed graph is most useful.

Publishing is best-effort and never changes the deployment result. When the application name cannot be resolved, or `rad app graph` fails, the action warns, publishes nothing, and exits 0. When only `rad resource list` fails, it still publishes: `deploy-progress.json` carries the run-level state with an empty `resources` array, so the Deployed tab shows the run rather than nothing.

`deploy-progress.json` is the authority on deploy state and the only status file the canvas reads. Its `state` uses `succeeded`/`failed`/`in_progress`, where `in_progress` also covers "no verdict" — it is what a finished run reports when `rad-commands-result.json` is missing or unreadable, since claiming a failure the deploy may not have had is worse than reporting no outcome. Each entry in `resources[]` carries both the raw `provisioningState` and a normalized `status`; an unrecognized provisioning state normalizes to `in_progress`, never `failed`, so a Radius state this action has not seen cannot paint a node red. `deploy-state.txt` predates `deploy-progress.json` and uses its own older vocabulary (`state=success`, mirroring the rad command outcome), so the two files can describe the same successful run with different words. That is deliberate; `deploy-progress.json` is the one to trust.

Workflow artifacts are the transport because the REST API can read them **while the run is still in progress** (`GET /repos/{owner}/{repo}/actions/runs/{run_id}/artifacts`), which is what lets the canvas show deployment state as it happens; `GET /repos/{owner}/{repo}/actions/artifacts?name=<name>` finds the newest one later without knowing the run. They also require no extra registry, no `packages: write` permission, and no name derivation duplicated between this action and the canvas reader.
15. **Persist state (`rad shutdown`).** Backs the control-plane databases and Terraform recipe-state Secrets up to the state archive — the OCI-backed archive by default (pushed to GHCR, selected by the `RADIUS_STATE_*` variables), or the `radius-state` git orphan branch when `RADIUS_STATE_BACKEND=git`. This runs even when the deploy fails (`if: always()`), so a partially-applied Terraform run is not lost.
16. **Tear down.** Runs `rad app list`, and always deletes the ephemeral `radius-cp` cluster. On failure, Radius and application logs are collected and uploaded as the `radius-logs` artifact (three-day retention).

Expand All @@ -131,7 +137,7 @@ Triggers and permissions live on the **dispatcher** (`run-rad-commands.yml`); th

The workflow reads cloud and cluster configuration from GitHub Actions **variables** (`vars`). Configure the relevant provider's set on the target GitHub Environment:

- Common: `KUBERNETES_NAMESPACE` (default `default`), `RADIUS_BUILD_REGISTRY` (default `ghcr.io/<owner>/<repo>`), `RADIUS_RAD_COMMANDS` (optional fallback for `rad_commands`), `RADIUS_GRAPH_REGISTRY` (optional GHCR repo for deployed graph/status artifacts), `RADIUS_GRAPH_TAG` (optional tag override)
- Common: `KUBERNETES_NAMESPACE` (default `default`), `RADIUS_BUILD_REGISTRY` (default `ghcr.io/<owner>/<repo>`), `RADIUS_RAD_COMMANDS` (optional fallback for `rad_commands`), `RADIUS_GRAPH_REGISTRY` (optional OCI repository for the `rad` CLI's modeled graph archive)
- Azure (`run-rad-commands-azure.yml`): `AZURE_CLIENT_ID`, `AZURE_TENANT_ID`, `AZURE_SUBSCRIPTION_ID`, `AZURE_RESOURCE_GROUP`, `AZURE_AKS_CLUSTER_NAME`
- AWS (`run-rad-commands-aws.yml`): `AWS_ROLE_ARN`, `AWS_REGION`, `AWS_ACCOUNT_ID`, `AWS_EKS_CLUSTER_NAME`, `RADIUS_VPC_ID`, `RADIUS_SUBNET_IDS`

Expand Down
Loading
Loading