From 8cbc106022e2c6995ec67f4fac261df4e723ca10 Mon Sep 17 00:00:00 2001 From: ryux1 Date: Mon, 7 Sep 2026 18:45:52 +0200 Subject: [PATCH] Add workflow run deletion action --- package.json | 16 ++++++++++++ src/commands/deleteWorkflowRun.ts | 39 ++++++++++++++++++++++++++++ src/extension.ts | 2 ++ src/store/workflowRun.ts | 13 +++------- src/store/workflowRunContext.test.ts | 12 +++++++++ src/store/workflowRunContext.ts | 19 ++++++++++++++ 6 files changed, 91 insertions(+), 10 deletions(-) create mode 100644 src/commands/deleteWorkflowRun.ts create mode 100644 src/store/workflowRunContext.test.ts create mode 100644 src/store/workflowRunContext.ts diff --git a/package.json b/package.json index 8b4e7dd9..779b3786 100644 --- a/package.json +++ b/package.json @@ -188,6 +188,13 @@ "title": "Cancel workflow run", "when": "viewItem =~ /run/ && viewItem =~ /cancelable/" }, + { + "command": "github-actions.workflow.run.delete", + "category": "GitHub Actions", + "title": "Delete workflow run", + "when": "viewItem =~ /run/ && viewItem =~ /deletable/", + "icon": "$(trash)" + }, { "command": "github-actions.settings.secrets.manage", "category": "GitHub Actions", @@ -405,6 +412,11 @@ "command": "github-actions.workflow.run.rerun", "when": "viewItem =~ /run/ && viewItem =~ /rerunnable/" }, + { + "command": "github-actions.workflow.run.delete", + "when": "viewItem =~ /run/ && viewItem =~ /deletable/", + "group": "inline@3" + }, { "command": "github-actions.settings.secret.add", "group": "inline", @@ -484,6 +496,10 @@ "command": "github-actions.workflow.run.cancel", "when": "false" }, + { + "command": "github-actions.workflow.run.delete", + "when": "false" + }, { "command": "github-actions.settings.secrets.manage", "when": "false" diff --git a/src/commands/deleteWorkflowRun.ts b/src/commands/deleteWorkflowRun.ts new file mode 100644 index 00000000..14bbc433 --- /dev/null +++ b/src/commands/deleteWorkflowRun.ts @@ -0,0 +1,39 @@ +import * as vscode from "vscode"; +import {WorkflowRunCommandArgs} from "../treeViews/shared/workflowRunNode"; + +export function registerDeleteWorkflowRun(context: vscode.ExtensionContext) { + context.subscriptions.push( + vscode.commands.registerCommand("github-actions.workflow.run.delete", async (args: WorkflowRunCommandArgs) => { + const {gitHubRepoContext, run} = args; + const acceptText = "Yes, delete this workflow run"; + const answer = await vscode.window.showWarningMessage( + `Are you sure you want to delete workflow run #${run.run.run_number}?`, + { + modal: true, + detail: "Deleting this workflow run, its logs, and its artifacts cannot be undone" + }, + acceptText + ); + + if (answer !== acceptText) { + return; + } + + try { + await gitHubRepoContext.client.actions.deleteWorkflowRun({ + owner: gitHubRepoContext.owner, + repo: gitHubRepoContext.name, + run_id: run.run.id + }); + } catch (e) { + await vscode.window.showErrorMessage(`Could not delete workflow run: '${(e as Error).message}'`); + return; + } + + await Promise.all([ + vscode.commands.executeCommand("github-actions.explorer.refresh"), + vscode.commands.executeCommand("github-actions.explorer.current-branch.refresh") + ]); + }) + ); +} diff --git a/src/extension.ts b/src/extension.ts index be9a157f..9bc607f5 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -3,6 +3,7 @@ import * as vscode from "vscode"; import {canReachGitHubAPI} from "./api/canReachGitHubAPI"; import {getSession} from "./auth/auth"; import {registerCancelWorkflowRun} from "./commands/cancelWorkflowRun"; +import {registerDeleteWorkflowRun} from "./commands/deleteWorkflowRun"; import {registerOpenWorkflowFile} from "./commands/openWorkflowFile"; import {registerOpenWorkflowJobLogs} from "./commands/openWorkflowJobLogs"; import {registerOpenWorkflowStepLogs} from "./commands/openWorkflowStepLogs"; @@ -78,6 +79,7 @@ export async function activate(context: vscode.ExtensionContext) { registerTriggerWorkflowRun(context); registerReRunWorkflowRun(context); registerCancelWorkflowRun(context); + registerDeleteWorkflowRun(context); registerAddSecret(context); registerDeleteSecret(context); diff --git a/src/store/workflowRun.ts b/src/store/workflowRun.ts index 1001bc2e..4280e866 100644 --- a/src/store/workflowRun.ts +++ b/src/store/workflowRun.ts @@ -1,9 +1,10 @@ import * as vscode from "vscode"; import {GitHubRepoContext} from "../git/repository"; -import {RepositoryPermission, hasWritePermission} from "../git/repository-permissions"; +import {RepositoryPermission} from "../git/repository-permissions"; import {log, logDebug} from "../log"; import * as model from "../model"; import {WorkflowJob} from "./WorkflowJob"; +import {getWorkflowRunContextValue} from "./workflowRunContext"; abstract class WorkflowRunBase { protected _gitHubRepoContext: GitHubRepoContext; @@ -53,15 +54,7 @@ abstract class WorkflowRunBase { } contextValue(permission: RepositoryPermission): string { - const contextValues = ["run"]; - const completed = this._run.status === "completed"; - if (hasWritePermission(permission)) { - contextValues.push(completed ? "rerunnable" : "cancelable"); - } - if (completed) { - contextValues.push("completed"); - } - return contextValues.join(" "); + return getWorkflowRunContextValue(this._run.status, permission); } protected abstract fetchJobs(): Promise; diff --git a/src/store/workflowRunContext.test.ts b/src/store/workflowRunContext.test.ts new file mode 100644 index 00000000..3dae2563 --- /dev/null +++ b/src/store/workflowRunContext.test.ts @@ -0,0 +1,12 @@ +import {getWorkflowRunContextValue} from "./workflowRunContext"; + +describe("getWorkflowRunContextValue", () => { + it.each([ + ["read", "completed", "run completed"], + ["write", "queued", "run cancelable"], + ["write", "completed", "run rerunnable deletable completed"], + ["admin", "completed", "run rerunnable deletable completed"] + ] as const)("returns the available actions for %s access to a %s run", (permission, status, expected) => { + expect(getWorkflowRunContextValue(status, permission)).toBe(expected); + }); +}); diff --git a/src/store/workflowRunContext.ts b/src/store/workflowRunContext.ts new file mode 100644 index 00000000..c2a5e4cb --- /dev/null +++ b/src/store/workflowRunContext.ts @@ -0,0 +1,19 @@ +import {RepositoryPermission, hasWritePermission} from "../git/repository-permissions"; + +export function getWorkflowRunContextValue(status: string | null, permission: RepositoryPermission): string { + const contextValues = ["run"]; + const completed = status === "completed"; + + if (hasWritePermission(permission)) { + contextValues.push(completed ? "rerunnable" : "cancelable"); + if (completed) { + contextValues.push("deletable"); + } + } + + if (completed) { + contextValues.push("completed"); + } + + return contextValues.join(" "); +}