Actions reference
Actions add menu items that appear on the detail-view kebab and (optionally) the list-view bulk-actions dropdown. Register one with buoy.addAction({...}):
buoy.addAction({
match: { group: "argoproj.io", kind: "Rollout" },
id: "abort",
label: "Abort",
danger: true,
when: (obj) => obj.status?.phase === "Progressing",
confirm: {
phrase: (obj) => obj.metadata.name,
title: (obj) => `Abort rollout ${obj.metadata.name}?`,
},
run: async (ctx) => {
await ctx.statusPatch({ status: { abort: true } });
},
});
Required fields
| field | type | notes |
|---|---|---|
match | { group, kind } | Exact match. group: "" for core kinds. |
id | string | Unique within this plugin. |
label | string | Menu item text. |
run | (ctx) => Promise | The body. See Run callback. |
Optional fields
| field | type | notes |
|---|---|---|
danger | boolean | Red styling + the standard danger ConfirmModal look. |
bulk | boolean | Also show in ListView’s bulk-actions menu. |
alsoSingle | boolean (default true) | When bulk: true, controls whether the item also shows for single objects. |
icon | string | Optional lucide icon name (matches built-in icon catalog). |
when | (obj) => boolean | Hide the action when this returns false. |
confirm | ActionConfirmSpec | See Confirm gating. |
Run callback
run(ctx) receives a pre-bound context. The patch helpers wrap Buoy’s
plugin_patch Tauri command so you only supply the JSON body.
run: async (ctx) => {
// ctx.obj — the live object
// ctx.resource — resource string (e.g. "rollouts")
// ctx.context — kube context name (or null)
// ctx.namespace — object namespace (or null for cluster-scoped)
// ctx.name — object name
await ctx.mergePatch({ spec: { replicas: 3 } });
// or:
await ctx.strategicPatch({ spec: { template: { metadata: { labels: { x: "y" } } } } });
await ctx.jsonPatch([{ op: "add", path: "/metadata/labels/x", value: "y" }]);
await ctx.statusPatch({ status: { abort: true } });
await ctx.delete();
}
Throwing from run aborts the action and surfaces the error inside the ConfirmModal — no need to wrap in try/catch unless you want to translate the message.
For bulk actions, run is called once per selected row with the appropriate ctx.
Confirm gating
Every action goes through ConfirmModal — the same red typing-required dialog the built-in Delete uses. Configure it via confirm::
confirm: {
phrase: (obj) => obj.metadata.name, // user types this to enable Confirm
title: (obj) => `Delete ${obj.metadata.name}?`, // dialog title
body: "This will tear down the workload immediately.", // optional explainer
}
Each field accepts either a plain string or a (obj) => string callback. Use the callback when the confirm needs object data.
For bulk actions, the confirm fields receive the first selected object, while the typed phrase becomes the verb summary (e.g. DELETE 3 pods).
Tips
- Don’t reach for actions for everything. If the underlying operation is just a relabel, the built-in Edit Labels modal is usually faster than a plugin action.
- Use
whento keep menus tidy. Hide actions that don’t apply to the current object state. E.g. a “Pause Rollout” action’swhen: (obj) => !obj.spec?.pausedkeeps it from showing up next to “Resume”. - Prefer
statusPatchfor/statussubresources. Many CRDs reject writes tostatusthrough the main resource; the helper hits the right endpoint. - Patches are sent as the active impersonation. If
/as <user>is on, the action runs as that user; RBAC denials surface in the modal.