From 049b6bdc8fe2bcf77f479d4c868edc51d5396f66 Mon Sep 17 00:00:00 2001 From: Sanjula Ganepola Date: Thu, 21 Nov 2024 21:48:27 -0500 Subject: [PATCH 1/8] Add actions to add and open secret, variable, and input files Signed-off-by: Sanjula Ganepola --- package.json | 79 ++++++++++++++++++- src/act.ts | 36 ++++----- src/historyManager.ts | 4 +- src/settingsManager.ts | 46 ++++++++++- src/storageManager.ts | 3 + src/views/history/history.ts | 2 +- src/views/settings/inputs.ts | 20 ++++- src/views/settings/secrets.ts | 20 ++++- src/views/settings/setting.ts | 9 ++- src/views/settings/settingFile.ts | 59 ++++++++++++++ .../settings/settingsTreeDataProvider.ts | 71 +++++++++++++++-- src/views/settings/variables.ts | 20 ++++- 12 files changed, 325 insertions(+), 44 deletions(-) create mode 100644 src/views/settings/settingFile.ts diff --git a/package.json b/package.json index 422e76c..42c8094 100644 --- a/package.json +++ b/package.json @@ -240,6 +240,12 @@ "title": "Refresh", "icon": "$(refresh)" }, + { + "category": "GitHub Local Actions", + "command": "githubLocalActions.addSecretFiles", + "title": "Add Secret Files", + "icon": "$(add)" + }, { "category": "GitHub Local Actions", "command": "githubLocalActions.show", @@ -252,12 +258,36 @@ "title": "Hide", "icon": "$(eye-closed)" }, + { + "category": "GitHub Local Actions", + "command": "githubLocalActions.addVariableFiles", + "title": "Add Variable Files", + "icon": "$(add)" + }, { "category": "GitHub Local Actions", "command": "githubLocalActions.importFromGithub", "title": "Import from GitHub", "icon": "$(github)" }, + { + "category": "GitHub Local Actions", + "command": "githubLocalActions.addInputFiles", + "title": "Add Input Files", + "icon": "$(add)" + }, + { + "category": "GitHub Local Actions", + "command": "githubLocalActions.openSettingFile", + "title": "Open", + "icon": "$(go-to-file)" + }, + { + "category": "GitHub Local Actions", + "command": "githubLocalActions.removeSettingFile", + "title": "Remove", + "icon": "$(close)" + }, { "category": "GitHub Local Actions", "command": "githubLocalActions.editSetting", @@ -352,6 +382,10 @@ "command": "githubLocalActions.refreshSettings", "when": "never" }, + { + "command": "githubLocalActions.addSecretFiles", + "when": "never" + }, { "command": "githubLocalActions.show", "when": "never" @@ -360,10 +394,26 @@ "command": "githubLocalActions.hide", "when": "never" }, + { + "command": "githubLocalActions.addVariableFiles", + "when": "never" + }, { "command": "githubLocalActions.importFromGithub", "when": "never" }, + { + "command": "githubLocalActions.addInputFiles", + "when": "never" + }, + { + "command": "githubLocalActions.openSettingFile", + "when": "never" + }, + { + "command": "githubLocalActions.removeSettingFile", + "when": "never" + }, { "command": "githubLocalActions.editSetting", "when": "never" @@ -495,6 +545,11 @@ "when": "view == history && viewItem =~ /^githubLocalActions.history.*/", "group": "inline@3" }, + { + "command": "githubLocalActions.addSecretFiles", + "when": "view == settings && viewItem =~ /^githubLocalActions.secrets.*/", + "group": "inline@0" + }, { "command": "githubLocalActions.show", "when": "view == settings && viewItem =~ /^githubLocalActions.secret(?!s)_hide.*/", @@ -506,13 +561,33 @@ "group": "inline@0" }, { - "command": "githubLocalActions.importFromGithub", + "command": "githubLocalActions.addVariableFiles", "when": "view == settings && viewItem =~ /^githubLocalActions.variables.*/", "group": "inline@0" }, + { + "command": "githubLocalActions.importFromGithub", + "when": "view == settings && viewItem =~ /^githubLocalActions.variables.*/", + "group": "inline@1" + }, + { + "command": "githubLocalActions.addInputFiles", + "when": "view == settings && viewItem =~ /^githubLocalActions.inputs.*/", + "group": "inline@0" + }, + { + "command": "githubLocalActions.openSettingFile", + "when": "view == settings && viewItem =~ /^githubLocalActions.(secret|variable|input)File.*/", + "group": "inline@0" + }, + { + "command": "githubLocalActions.removeSettingFile", + "when": "view == settings && viewItem =~ /^githubLocalActions.(secret|variable|input)File.*/", + "group": "inline@1" + }, { "command": "githubLocalActions.editSetting", - "when": "view == settings && viewItem =~ /^githubLocalActions.(secret|variable|input|runner)(?!s).*/", + "when": "view == settings && viewItem =~ /^githubLocalActions.(secret|variable|input|runner)(?!(File|s)).*/", "group": "inline@1" } ] diff --git a/src/act.ts b/src/act.ts index feb2a0b..051cc4e 100644 --- a/src/act.ts +++ b/src/act.ts @@ -55,7 +55,7 @@ export enum Option { } export interface CommandArgs { - fsPath: string, + path: string, options: string, name: string, extraHeader: { key: string, value: string }[] @@ -168,7 +168,7 @@ export class Act { const historyIndex = taskDefinition.historyIndex; // Add new entry to workspace history - this.historyManager.workspaceHistory[commandArgs.fsPath].push({ + this.historyManager.workspaceHistory[commandArgs.path].push({ index: historyIndex, count: taskDefinition.count, name: `${commandArgs.name}`, @@ -191,18 +191,18 @@ export class Act { const historyIndex = taskDefinition.historyIndex; // Set end status - if (this.historyManager.workspaceHistory[commandArgs.fsPath][historyIndex].status === HistoryStatus.Running) { + if (this.historyManager.workspaceHistory[commandArgs.path][historyIndex].status === HistoryStatus.Running) { if (e.exitCode === 0) { - this.historyManager.workspaceHistory[commandArgs.fsPath][historyIndex].status = HistoryStatus.Success; + this.historyManager.workspaceHistory[commandArgs.path][historyIndex].status = HistoryStatus.Success; } else if (!e.exitCode) { - this.historyManager.workspaceHistory[commandArgs.fsPath][historyIndex].status = HistoryStatus.Cancelled; + this.historyManager.workspaceHistory[commandArgs.path][historyIndex].status = HistoryStatus.Cancelled; } else { - this.historyManager.workspaceHistory[commandArgs.fsPath][historyIndex].status = HistoryStatus.Failed; + this.historyManager.workspaceHistory[commandArgs.path][historyIndex].status = HistoryStatus.Failed; } } // Set end time - this.historyManager.workspaceHistory[commandArgs.fsPath][historyIndex].date.end = new Date().toString(); + this.historyManager.workspaceHistory[commandArgs.path][historyIndex].date.end = new Date().toString(); historyTreeDataProvider.refresh(); this.storageManager.update(StorageKey.WorkspaceHistory, this.historyManager.workspaceHistory); @@ -212,7 +212,7 @@ export class Act { async runAllWorkflows(workspaceFolder: WorkspaceFolder) { return await this.runCommand({ - fsPath: workspaceFolder.uri.fsPath, + path: workspaceFolder.uri.fsPath, options: ``, name: workspaceFolder.name, extraHeader: [] @@ -221,7 +221,7 @@ export class Act { async runWorkflow(workspaceFolder: WorkspaceFolder, workflow: Workflow) { return await this.runCommand({ - fsPath: workspaceFolder.uri.fsPath, + path: workspaceFolder.uri.fsPath, options: `${Option.Workflows} ".github/workflows/${path.parse(workflow.uri.fsPath).base}"`, name: workflow.name, extraHeader: [ @@ -232,7 +232,7 @@ export class Act { async runJob(workspaceFolder: WorkspaceFolder, workflow: Workflow, job: Job) { return await this.runCommand({ - fsPath: workspaceFolder.uri.fsPath, + path: workspaceFolder.uri.fsPath, options: `${Option.Workflows} ".github/workflows/${path.parse(workflow.uri.fsPath).base}" ${Option.Job} "${job.id}"`, name: `${workflow.name}/${job.name}`, extraHeader: [ @@ -244,7 +244,7 @@ export class Act { async runEvent(workspaceFolder: WorkspaceFolder, event: Event) { return await this.runCommand({ - fsPath: workspaceFolder.uri.fsPath, + path: workspaceFolder.uri.fsPath, options: event, name: event, extraHeader: [ @@ -266,21 +266,21 @@ export class Act { // } // Map to workspace folder - const workspaceFolder = workspace.getWorkspaceFolder(Uri.file(commandArgs.fsPath)); + const workspaceFolder = workspace.getWorkspaceFolder(Uri.file(commandArgs.path)); if (!workspaceFolder) { - window.showErrorMessage(`Failed to locate workspace folder for ${commandArgs.fsPath}`); + window.showErrorMessage(`Failed to locate workspace folder for ${commandArgs.path}`); return; } // Initialize history for workspace - if (!this.historyManager.workspaceHistory[commandArgs.fsPath]) { - this.historyManager.workspaceHistory[commandArgs.fsPath] = []; + if (!this.historyManager.workspaceHistory[commandArgs.path]) { + this.historyManager.workspaceHistory[commandArgs.path] = []; this.storageManager.update(StorageKey.WorkspaceHistory, this.historyManager.workspaceHistory); } // Process task count suffix - const historyIndex = this.historyManager.workspaceHistory[commandArgs.fsPath].length; - const matchingTasks = this.historyManager.workspaceHistory[commandArgs.fsPath] + const historyIndex = this.historyManager.workspaceHistory[commandArgs.path].length; + const matchingTasks = this.historyManager.workspaceHistory[commandArgs.path] .filter(history => history.name === commandArgs.name) .sort((a, b) => b.count - a.count); const count = matchingTasks && matchingTasks.length > 0 ? matchingTasks[0].count + 1 : 1; @@ -341,7 +341,7 @@ export class Act { execution: new ShellExecution( command, { - cwd: commandArgs.fsPath, + cwd: commandArgs.path, env: settings.secrets .filter(secret => secret.value) .reduce((previousValue, currentValue) => { diff --git a/src/historyManager.ts b/src/historyManager.ts index cf38f5d..3bc45b8 100644 --- a/src/historyManager.ts +++ b/src/historyManager.ts @@ -74,8 +74,8 @@ export class HistoryManager { } async remove(history: History) { - const historyIndex = this.workspaceHistory[history.commandArgs.fsPath].findIndex(workspaceHistory => workspaceHistory.index === history.index); - this.workspaceHistory[history.commandArgs.fsPath].splice(historyIndex, 1); + const historyIndex = this.workspaceHistory[history.commandArgs.path].findIndex(workspaceHistory => workspaceHistory.index === history.index); + this.workspaceHistory[history.commandArgs.path].splice(historyIndex, 1); this.storageManager.update(StorageKey.WorkspaceHistory, this.workspaceHistory); try { diff --git a/src/settingsManager.ts b/src/settingsManager.ts index 01ae06c..95424e0 100644 --- a/src/settingsManager.ts +++ b/src/settingsManager.ts @@ -4,6 +4,17 @@ import { GitHubManager } from "./githubManager"; import { SecretManager } from "./secretManager"; import { StorageKey, StorageManager } from "./storageManager"; +export interface Settings { + secrets: Setting[]; + secretFiles: SettingFile[]; + variables: Setting[]; + variableFiles: SettingFile[]; + inputs: Setting[]; + inputFiles: SettingFile[]; + runners: Setting[]; + environments: Setting[]; +} + export interface Setting { key: string, value: string, @@ -12,6 +23,12 @@ export interface Setting { visible: Visibility } +export interface SettingFile { + name: string, + path: string, + selected: boolean +} + export enum Visibility { show = 'show', hide = 'hide' @@ -32,17 +49,23 @@ export class SettingsManager { this.githubManager = new GitHubManager(); } - async getSettings(workspaceFolder: WorkspaceFolder, isUserSelected: boolean) { + async getSettings(workspaceFolder: WorkspaceFolder, isUserSelected: boolean): Promise { const secrets = (await this.getSetting(workspaceFolder, SettingsManager.secretsRegExp, StorageKey.Secrets, true, Visibility.hide)).filter(secret => !isUserSelected || secret.selected); + const secretFiles = await this.getSettingFiles(workspaceFolder, StorageKey.SecretFiles); const variables = (await this.getSetting(workspaceFolder, SettingsManager.variablesRegExp, StorageKey.Variables, false, Visibility.show)).filter(variable => !isUserSelected || variable.selected); + const variableFiles = await this.getSettingFiles(workspaceFolder, StorageKey.VariableFiles); const inputs = (await this.getSetting(workspaceFolder, SettingsManager.inputsRegExp, StorageKey.Inputs, false, Visibility.show)).filter(input => !isUserSelected || (input.selected && input.value)); + const inputFiles = await this.getSettingFiles(workspaceFolder, StorageKey.InputFiles); const runners = (await this.getSetting(workspaceFolder, SettingsManager.runnersRegExp, StorageKey.Runners, false, Visibility.show)).filter(runner => !isUserSelected || (runner.selected && runner.value)); const environments = await this.getEnvironments(workspaceFolder); return { secrets: secrets, + secretFiles: secretFiles, variables: variables, + variableFiles: variableFiles, inputs: inputs, + inputFiles: inputFiles, runners: runners, environments: environments }; @@ -94,6 +117,11 @@ export class SettingsManager { return settings; } + async getSettingFiles(workspaceFolder: WorkspaceFolder, storageKey: StorageKey): Promise { + const existingSettingFiles = this.storageManager.get<{ [path: string]: SettingFile[] }>(storageKey) || {}; + return existingSettingFiles[workspaceFolder.uri.fsPath] || []; + } + async getEnvironments(workspaceFolder: WorkspaceFolder): Promise { const environments: Setting[] = []; @@ -125,6 +153,22 @@ export class SettingsManager { return environments; } + async editSettingFile(workspaceFolder: WorkspaceFolder, newSettingFile: SettingFile, storageKey: StorageKey) { + const existingSettingFiles = this.storageManager.get<{ [path: string]: SettingFile[] }>(storageKey) || {}; + if (existingSettingFiles[workspaceFolder.uri.fsPath]) { + const index = existingSettingFiles[workspaceFolder.uri.fsPath].findIndex(settingFile => settingFile.path === newSettingFile.path); + if (index > -1) { + existingSettingFiles[workspaceFolder.uri.fsPath][index] = newSettingFile; + } else { + existingSettingFiles[workspaceFolder.uri.fsPath].push(newSettingFile); + } + } else { + existingSettingFiles[workspaceFolder.uri.fsPath] = [newSettingFile]; + } + + await this.storageManager.update(storageKey, existingSettingFiles); + } + async editSetting(workspaceFolder: WorkspaceFolder, newSetting: Setting, storageKey: StorageKey) { const value = newSetting.value; if (storageKey === StorageKey.Secrets) { diff --git a/src/storageManager.ts b/src/storageManager.ts index f84bcfa..739246c 100644 --- a/src/storageManager.ts +++ b/src/storageManager.ts @@ -3,8 +3,11 @@ import { ExtensionContext } from "vscode"; export enum StorageKey { WorkspaceHistory = 'workspaceHistory', Secrets = 'secrets', + SecretFiles = 'secretFiles', Variables = 'variables', + VariableFiles = 'variableFiles', Inputs = 'inputs', + InputFiles = 'inputFiles', Runners = 'runners' } diff --git a/src/views/history/history.ts b/src/views/history/history.ts index c4aa34a..b4ea819 100644 --- a/src/views/history/history.ts +++ b/src/views/history/history.ts @@ -40,7 +40,7 @@ export default class HistoryTreeItem extends TreeItem implements GithubLocalActi } this.tooltip = `Name: ${history.name} #${history.count}\n` + `${history.commandArgs.extraHeader.map(header => `${header.key}: ${header.value}`).join('\n')}\n` + - `Path: ${history.commandArgs.fsPath}\n` + + `Path: ${history.commandArgs.path}\n` + `Log File: ${path.parse(history.logPath).base}\n` + `Status: ${history.status}\n` + `Started: ${Utils.getDateString(history.date.start)}\n` + diff --git a/src/views/settings/inputs.ts b/src/views/settings/inputs.ts index 19be59e..590a3ba 100644 --- a/src/views/settings/inputs.ts +++ b/src/views/settings/inputs.ts @@ -1,11 +1,14 @@ import { ThemeIcon, TreeItem, TreeItemCollapsibleState, WorkspaceFolder } from "vscode"; import { act } from "../../extension"; import { Setting } from "../../settingsManager"; +import { StorageKey } from "../../storageManager"; import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem"; import SettingTreeItem from "./setting"; +import SettingFileTreeItem from "./settingFile"; export default class InputsTreeItem extends TreeItem implements GithubLocalActionsTreeItem { static contextValue = 'githubLocalActions.inputs'; + storageKey = StorageKey.InputFiles; constructor(public workspaceFolder: WorkspaceFolder, inputs: Setting[]) { super('Inputs', TreeItemCollapsibleState.Collapsed); @@ -18,10 +21,19 @@ export default class InputsTreeItem extends TreeItem implements GithubLocalActio const items: GithubLocalActionsTreeItem[] = []; const settings = await act.settingsManager.getSettings(this.workspaceFolder, false); - for (const input of settings.inputs) { - items.push(SettingTreeItem.getInputTreeItem(this.workspaceFolder, input)); - } - return items.sort((a, b) => a.label!.toString().localeCompare(b.label!.toString())); + const inputTreeItems: GithubLocalActionsTreeItem[] = []; + for (const input of settings.inputs) { + inputTreeItems.push(SettingTreeItem.getInputTreeItem(this.workspaceFolder, input)); + } + items.push(...inputTreeItems.sort((a, b) => a.label!.toString().localeCompare(b.label!.toString()))); + + const inputFileTreeItems: GithubLocalActionsTreeItem[] = []; + for (const inputFile of settings.inputFiles) { + inputFileTreeItems.push(SettingFileTreeItem.getInputTreeItem(this.workspaceFolder, inputFile)); + } + items.push(...inputFileTreeItems.sort((a, b) => a.label!.toString().localeCompare(b.label!.toString()))); + + return items; } } \ No newline at end of file diff --git a/src/views/settings/secrets.ts b/src/views/settings/secrets.ts index fb021b3..28eefda 100644 --- a/src/views/settings/secrets.ts +++ b/src/views/settings/secrets.ts @@ -1,11 +1,14 @@ import { ThemeIcon, TreeItem, TreeItemCollapsibleState, WorkspaceFolder } from "vscode"; import { act } from "../../extension"; import { Setting } from "../../settingsManager"; +import { StorageKey } from "../../storageManager"; import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem"; import SettingTreeItem from "./setting"; +import SettingFileTreeItem from "./settingFile"; export default class SecretsTreeItem extends TreeItem implements GithubLocalActionsTreeItem { static contextValue = 'githubLocalActions.secrets'; + storageKey = StorageKey.SecretFiles; constructor(public workspaceFolder: WorkspaceFolder, secrets: Setting[]) { super('Secrets', TreeItemCollapsibleState.Collapsed); @@ -18,10 +21,19 @@ export default class SecretsTreeItem extends TreeItem implements GithubLocalActi const items: GithubLocalActionsTreeItem[] = []; const settings = await act.settingsManager.getSettings(this.workspaceFolder, false); - for (const secret of settings.secrets) { - items.push(SettingTreeItem.getSecretTreeItem(this.workspaceFolder, secret)); - } - return items.sort((a, b) => a.label!.toString().localeCompare(b.label!.toString())); + const secretTreeItems: GithubLocalActionsTreeItem[] = []; + for (const secret of settings.secrets) { + secretTreeItems.push(SettingTreeItem.getSecretTreeItem(this.workspaceFolder, secret)); + } + items.push(...secretTreeItems.sort((a, b) => a.label!.toString().localeCompare(b.label!.toString()))); + + const secretFileTreeItems: GithubLocalActionsTreeItem[] = []; + for (const secretFile of settings.secretFiles) { + secretFileTreeItems.push(SettingFileTreeItem.getSecretTreeItem(this.workspaceFolder, secretFile)); + } + items.push(...secretFileTreeItems.sort((a, b) => a.label!.toString().localeCompare(b.label!.toString()))); + + return items; } } \ No newline at end of file diff --git a/src/views/settings/setting.ts b/src/views/settings/setting.ts index 49a8361..cbdaea6 100644 --- a/src/views/settings/setting.ts +++ b/src/views/settings/setting.ts @@ -36,7 +36,8 @@ export default class SettingTreeItem extends TreeItem implements GithubLocalActi static getVariableTreeItem(workspaceFolder: WorkspaceFolder, variable: Setting): SettingTreeItem { return new SettingTreeItem( workspaceFolder, - variable, StorageKey.Variables, + variable, + StorageKey.Variables, { contextValue: 'githubLocalActions.variable', iconPath: new ThemeIcon('symbol-variable') @@ -47,7 +48,8 @@ export default class SettingTreeItem extends TreeItem implements GithubLocalActi static getInputTreeItem(workspaceFolder: WorkspaceFolder, input: Setting): SettingTreeItem { return new SettingTreeItem( workspaceFolder, - input, StorageKey.Inputs, + input, + StorageKey.Inputs, { contextValue: 'githubLocalActions.input', iconPath: new ThemeIcon('symbol-parameter') @@ -58,7 +60,8 @@ export default class SettingTreeItem extends TreeItem implements GithubLocalActi static getRunnerTreeItem(workspaceFolder: WorkspaceFolder, runner: Setting): SettingTreeItem { return new SettingTreeItem( workspaceFolder, - runner, StorageKey.Runners, + runner, + StorageKey.Runners, { contextValue: 'githubLocalActions.runner', iconPath: new ThemeIcon('vm-connect') diff --git a/src/views/settings/settingFile.ts b/src/views/settings/settingFile.ts new file mode 100644 index 0000000..5e96070 --- /dev/null +++ b/src/views/settings/settingFile.ts @@ -0,0 +1,59 @@ +import { ThemeIcon, TreeItem, TreeItemCheckboxState, TreeItemCollapsibleState, WorkspaceFolder } from "vscode"; +import { SettingFile } from "../../settingsManager"; +import { StorageKey } from "../../storageManager"; +import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem"; + +export default class SettingFileTreeItem extends TreeItem implements GithubLocalActionsTreeItem { + settingFile: SettingFile; + storageKey: StorageKey; + + constructor(public workspaceFolder: WorkspaceFolder, settingFile: SettingFile, storageKey: StorageKey, treeItem: { contextValue: string, iconPath: ThemeIcon }) { + super(settingFile.name, TreeItemCollapsibleState.None); + this.settingFile = settingFile; + this.storageKey = storageKey; + this.description = settingFile.path; + this.contextValue = treeItem.contextValue; + this.iconPath = treeItem.iconPath; + this.checkboxState = settingFile.selected ? TreeItemCheckboxState.Checked : TreeItemCheckboxState.Unchecked; + } + + static getSecretTreeItem(workspaceFolder: WorkspaceFolder, secretFile: SettingFile): SettingFileTreeItem { + return new SettingFileTreeItem( + workspaceFolder, + secretFile, + StorageKey.SecretFiles, + { + contextValue: 'githubLocalActions.secretFile', + iconPath: new ThemeIcon('gist-secret') + } + ); + } + + static getVariableTreeItem(workspaceFolder: WorkspaceFolder, variableFile: SettingFile): SettingFileTreeItem { + return new SettingFileTreeItem( + workspaceFolder, + variableFile, + StorageKey.VariableFiles, + { + contextValue: 'githubLocalActions.variableFile', + iconPath: new ThemeIcon('file') + } + ); + } + + static getInputTreeItem(workspaceFolder: WorkspaceFolder, inputFile: SettingFile): SettingFileTreeItem { + return new SettingFileTreeItem( + workspaceFolder, + inputFile, + StorageKey.InputFiles, + { + contextValue: 'githubLocalActions.inputFile', + iconPath: new ThemeIcon('file') + } + ); + } + + async getChildren(): Promise { + return []; + } +} \ No newline at end of file diff --git a/src/views/settings/settingsTreeDataProvider.ts b/src/views/settings/settingsTreeDataProvider.ts index 4e4beaf..90e3c9c 100644 --- a/src/views/settings/settingsTreeDataProvider.ts +++ b/src/views/settings/settingsTreeDataProvider.ts @@ -1,9 +1,14 @@ +import * as path from "path"; import { CancellationToken, commands, EventEmitter, ExtensionContext, QuickPickItem, QuickPickItemKind, ThemeIcon, TreeCheckboxChangeEvent, TreeDataProvider, TreeItem, TreeItemCheckboxState, window, workspace } from "vscode"; import { act } from "../../extension"; -import { Visibility } from "../../settingsManager"; +import { SettingFile, Visibility } from "../../settingsManager"; import { StorageKey } from "../../storageManager"; import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem"; +import InputsTreeItem from "./inputs"; +import SecretsTreeItem from "./secrets"; import SettingTreeItem from "./setting"; +import SettingFileTreeItem from "./settingFile"; +import VariablesTreeItem from "./variables"; import WorkspaceFolderSettingsTreeItem from "./workspaceFolderSettings"; export default class SettingsTreeDataProvider implements TreeDataProvider { @@ -15,6 +20,56 @@ export default class SettingsTreeDataProvider implements TreeDataProvider { this.refresh(); + }), + commands.registerCommand('githubLocalActions.addSettingFiles', async (treeItem: SecretsTreeItem | VariablesTreeItem | InputsTreeItem, title: string) => { + const settingFilesUris = await window.showOpenDialog({ + title: title, + canSelectFiles: true, + canSelectFolders: false, + canSelectMany: true, + defaultUri: treeItem.workspaceFolder.uri + }); + + if (settingFilesUris) { + const settingFilesPaths = (await act.settingsManager.getSettingFiles(treeItem.workspaceFolder, treeItem.storageKey)).map(settingFile => settingFile.path); + const existingSettingFileNames: string[] = []; + + for await (const uri of settingFilesUris) { + const settingFileName = path.parse(uri.fsPath).name; + + if (settingFilesPaths.includes(uri.fsPath)) { + existingSettingFileNames.push(settingFileName); + } else { + const newSettingFile: SettingFile = { + name: path.parse(uri.fsPath).name, + path: uri.fsPath, + selected: false + }; + await act.settingsManager.editSettingFile(treeItem.workspaceFolder, newSettingFile, treeItem.storageKey); + } + } + + if (existingSettingFileNames.length > 0) { + window.showErrorMessage(`The following file(s) have already been added: ${existingSettingFileNames.join(', ')}`); + } + this.refresh(); + } + }), + commands.registerCommand('githubLocalActions.addSecretFiles', async (secretsTreeItem: SecretsTreeItem) => { + await commands.executeCommand('githubLocalActions.addSettingFiles', secretsTreeItem, 'Add Secret File'); + }), + commands.registerCommand('githubLocalActions.addVariableFiles', async (variablesTreeItem: VariablesTreeItem) => { + await commands.executeCommand('githubLocalActions.addSettingFiles', variablesTreeItem, 'Add Variable File'); + }), + commands.registerCommand('githubLocalActions.addInputFiles', async (inputsTreeItem: InputsTreeItem) => { + await commands.executeCommand('githubLocalActions.addSettingFiles', inputsTreeItem, 'Add Input File'); + }), + commands.registerCommand('githubLocalActions.openSettingFile', async (settingFileTreeItem: SettingFileTreeItem) => { + const document = await workspace.openTextDocument(settingFileTreeItem.settingFile.path); + await window.showTextDocument(document); + }), + commands.registerCommand('githubLocalActions.removeSettingFile', async (settingFileTreeItem: SettingFileTreeItem) => { + }), commands.registerCommand('githubLocalActions.show', async (settingTreeItem: SettingTreeItem) => { const newSetting = settingTreeItem.setting; @@ -167,11 +222,17 @@ export default class SettingsTreeDataProvider implements TreeDataProvider) { + async onDidChangeCheckboxState(event: TreeCheckboxChangeEvent) { for await (const [treeItem, state] of event.items) { - const newSetting = treeItem.setting; - newSetting.selected = (state === TreeItemCheckboxState.Checked); - await act.settingsManager.editSetting(treeItem.workspaceFolder, newSetting, treeItem.storageKey); + if (treeItem instanceof SettingTreeItem) { + const newSetting = treeItem.setting; + newSetting.selected = (state === TreeItemCheckboxState.Checked); + await act.settingsManager.editSetting(treeItem.workspaceFolder, newSetting, treeItem.storageKey); + } else { + const newSettingFile = treeItem.settingFile; + newSettingFile.selected = (state === TreeItemCheckboxState.Checked); + await act.settingsManager.editSettingFile(treeItem.workspaceFolder, newSettingFile, treeItem.storageKey); + } } this.refresh(); } diff --git a/src/views/settings/variables.ts b/src/views/settings/variables.ts index 6c43350..10316ef 100644 --- a/src/views/settings/variables.ts +++ b/src/views/settings/variables.ts @@ -1,11 +1,14 @@ import { ThemeIcon, TreeItem, TreeItemCollapsibleState, WorkspaceFolder } from "vscode"; import { act } from "../../extension"; import { Setting } from "../../settingsManager"; +import { StorageKey } from "../../storageManager"; import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem"; import SettingTreeItem from "./setting"; +import SettingFileTreeItem from "./settingFile"; export default class VariablesTreeItem extends TreeItem implements GithubLocalActionsTreeItem { static contextValue = 'githubLocalActions.variables'; + storageKey = StorageKey.VariableFiles; constructor(public workspaceFolder: WorkspaceFolder, variables: Setting[]) { super('Variables', TreeItemCollapsibleState.Collapsed); @@ -18,10 +21,19 @@ export default class VariablesTreeItem extends TreeItem implements GithubLocalAc const items: GithubLocalActionsTreeItem[] = []; const settings = await act.settingsManager.getSettings(this.workspaceFolder, false); - for (const variable of settings.variables) { - items.push(SettingTreeItem.getVariableTreeItem(this.workspaceFolder, variable)); - } - return items.sort((a, b) => a.label!.toString().localeCompare(b.label!.toString())); + const variableTreeItems: GithubLocalActionsTreeItem[] = []; + for (const variable of settings.variables) { + variableTreeItems.push(SettingTreeItem.getVariableTreeItem(this.workspaceFolder, variable)); + } + items.push(...variableTreeItems.sort((a, b) => a.label!.toString().localeCompare(b.label!.toString()))); + + const variableFileTreeItems: GithubLocalActionsTreeItem[] = []; + for (const variableFile of settings.variableFiles) { + variableFileTreeItems.push(SettingFileTreeItem.getVariableTreeItem(this.workspaceFolder, variableFile)); + } + items.push(...variableFileTreeItems.sort((a, b) => a.label!.toString().localeCompare(b.label!.toString()))); + + return items; } } \ No newline at end of file From db7972e887a9166be4ba3ae87a8a00cefb032b19 Mon Sep 17 00:00:00 2001 From: Sanjula Ganepola Date: Thu, 21 Nov 2024 21:50:51 -0500 Subject: [PATCH 2/8] Add tooltip for setting file and use base name Signed-off-by: Sanjula Ganepola --- src/views/settings/settingFile.ts | 2 ++ src/views/settings/settingsTreeDataProvider.ts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/views/settings/settingFile.ts b/src/views/settings/settingFile.ts index 5e96070..2caf6e9 100644 --- a/src/views/settings/settingFile.ts +++ b/src/views/settings/settingFile.ts @@ -15,6 +15,8 @@ export default class SettingFileTreeItem extends TreeItem implements GithubLocal this.contextValue = treeItem.contextValue; this.iconPath = treeItem.iconPath; this.checkboxState = settingFile.selected ? TreeItemCheckboxState.Checked : TreeItemCheckboxState.Unchecked; + this.tooltip = `Name: ${settingFile.name}\n` + + `Path: ${settingFile.path}\n`; } static getSecretTreeItem(workspaceFolder: WorkspaceFolder, secretFile: SettingFile): SettingFileTreeItem { diff --git a/src/views/settings/settingsTreeDataProvider.ts b/src/views/settings/settingsTreeDataProvider.ts index 90e3c9c..dfff2bf 100644 --- a/src/views/settings/settingsTreeDataProvider.ts +++ b/src/views/settings/settingsTreeDataProvider.ts @@ -41,7 +41,7 @@ export default class SettingsTreeDataProvider implements TreeDataProvider Date: Thu, 21 Nov 2024 22:20:17 -0500 Subject: [PATCH 3/8] Add actions to remove and delete setting files Signed-off-by: Sanjula Ganepola --- package.json | 15 ++++++++++++ src/act.ts | 2 +- src/githubManager.ts | 2 +- src/historyManager.ts | 16 +++++++------ src/settingsManager.ts | 23 ++++++++++++++++++- src/views/settings/inputs.ts | 7 +++--- src/views/settings/secrets.ts | 7 +++--- .../settings/settingsTreeDataProvider.ts | 7 +++++- src/views/settings/variables.ts | 7 +++--- src/views/settings/workspaceFolderSettings.ts | 6 ++--- src/workflowsManager.ts | 2 +- 11 files changed, 70 insertions(+), 24 deletions(-) diff --git a/package.json b/package.json index 42c8094..54a7e16 100644 --- a/package.json +++ b/package.json @@ -288,6 +288,12 @@ "title": "Remove", "icon": "$(close)" }, + { + "category": "GitHub Local Actions", + "command": "githubLocalActions.deleteSettingFile", + "title": "Delete", + "icon": "$(trash)" + }, { "category": "GitHub Local Actions", "command": "githubLocalActions.editSetting", @@ -414,6 +420,10 @@ "command": "githubLocalActions.removeSettingFile", "when": "never" }, + { + "command": "githubLocalActions.deleteSettingFile", + "when": "never" + }, { "command": "githubLocalActions.editSetting", "when": "never" @@ -585,6 +595,11 @@ "when": "view == settings && viewItem =~ /^githubLocalActions.(secret|variable|input)File.*/", "group": "inline@1" }, + { + "command": "githubLocalActions.deleteSettingFile", + "when": "view == settings && viewItem =~ /^githubLocalActions.(secret|variable|input)File.*/", + "group": "inline@2" + }, { "command": "githubLocalActions.editSetting", "when": "view == settings && viewItem =~ /^githubLocalActions.(secret|variable|input|runner)(?!(File|s)).*/", diff --git a/src/act.ts b/src/act.ts index 051cc4e..f3923c7 100644 --- a/src/act.ts +++ b/src/act.ts @@ -298,7 +298,7 @@ export class Act { try { await workspace.fs.createDirectory(this.context.globalStorageUri); - } catch (error) { } + } catch (error: any) { } // Build command with settings const settings = await this.settingsManager.getSettings(workspaceFolder, true); diff --git a/src/githubManager.ts b/src/githubManager.ts index 722d302..8b56e3a 100644 --- a/src/githubManager.ts +++ b/src/githubManager.ts @@ -147,7 +147,7 @@ export class GitHubManager { private async getSession(): Promise { try { return await authentication.getSession('github', ['repo'], { createIfNone: true }); - } catch (error) { + } catch (error: any) { window.showErrorMessage(`Failed to authenticate to GitHub. Error ${error}`); return; } diff --git a/src/historyManager.ts b/src/historyManager.ts index 3bc45b8..1f8e629 100644 --- a/src/historyManager.ts +++ b/src/historyManager.ts @@ -48,7 +48,7 @@ export class HistoryManager { for (const history of existingHistory) { try { await workspace.fs.delete(Uri.file(history.logPath)); - } catch (error) { } + } catch (error: any) { } } this.workspaceHistory[workspaceFolder.uri.fsPath] = []; @@ -60,7 +60,7 @@ export class HistoryManager { try { const document = await workspace.openTextDocument(history.logPath); await window.showTextDocument(document); - } catch (error) { + } catch (error: any) { window.showErrorMessage(`${history.name} #${history.count} log file not found`); } } @@ -75,11 +75,13 @@ export class HistoryManager { async remove(history: History) { const historyIndex = this.workspaceHistory[history.commandArgs.path].findIndex(workspaceHistory => workspaceHistory.index === history.index); - this.workspaceHistory[history.commandArgs.path].splice(historyIndex, 1); - this.storageManager.update(StorageKey.WorkspaceHistory, this.workspaceHistory); + if (historyIndex > -1) { + this.workspaceHistory[history.commandArgs.path].splice(historyIndex, 1); + this.storageManager.update(StorageKey.WorkspaceHistory, this.workspaceHistory); - try { - await workspace.fs.delete(Uri.file(history.logPath)); - } catch (error) { } + try { + await workspace.fs.delete(Uri.file(history.logPath)); + } catch (error: any) { } + } } } \ No newline at end of file diff --git a/src/settingsManager.ts b/src/settingsManager.ts index 95424e0..cfcb334 100644 --- a/src/settingsManager.ts +++ b/src/settingsManager.ts @@ -1,4 +1,4 @@ -import { WorkspaceFolder } from "vscode"; +import { Uri, window, workspace, WorkspaceFolder } from "vscode"; import { act } from "./extension"; import { GitHubManager } from "./githubManager"; import { SecretManager } from "./secretManager"; @@ -169,6 +169,27 @@ export class SettingsManager { await this.storageManager.update(storageKey, existingSettingFiles); } + async removeSettingFile(workspaceFolder: WorkspaceFolder, settingFile: SettingFile, storageKey: StorageKey) { + const existingSettingFiles = this.storageManager.get<{ [path: string]: SettingFile[] }>(storageKey) || {}; + if (existingSettingFiles[workspaceFolder.uri.fsPath]) { + const settingFileIndex = existingSettingFiles[workspaceFolder.uri.fsPath].findIndex(settingFile => settingFile.path === settingFile.path); + if (settingFileIndex > -1) { + existingSettingFiles[workspaceFolder.uri.fsPath].splice(settingFileIndex, 1); + } + } + + await this.storageManager.update(storageKey, existingSettingFiles); + } + + async deleteSettingFile(workspaceFolder: WorkspaceFolder, settingFile: SettingFile, storageKey: StorageKey) { + try { + await workspace.fs.delete(Uri.file(settingFile.path)); + await this.removeSettingFile(workspaceFolder, settingFile, storageKey); + } catch (error: any) { + window.showErrorMessage(`Failed to delete file. Error ${error}`) + } + } + async editSetting(workspaceFolder: WorkspaceFolder, newSetting: Setting, storageKey: StorageKey) { const value = newSetting.value; if (storageKey === StorageKey.Secrets) { diff --git a/src/views/settings/inputs.ts b/src/views/settings/inputs.ts index 590a3ba..1b17339 100644 --- a/src/views/settings/inputs.ts +++ b/src/views/settings/inputs.ts @@ -1,6 +1,6 @@ import { ThemeIcon, TreeItem, TreeItemCollapsibleState, WorkspaceFolder } from "vscode"; import { act } from "../../extension"; -import { Setting } from "../../settingsManager"; +import { Setting, SettingFile } from "../../settingsManager"; import { StorageKey } from "../../storageManager"; import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem"; import SettingTreeItem from "./setting"; @@ -10,9 +10,10 @@ export default class InputsTreeItem extends TreeItem implements GithubLocalActio static contextValue = 'githubLocalActions.inputs'; storageKey = StorageKey.InputFiles; - constructor(public workspaceFolder: WorkspaceFolder, inputs: Setting[]) { + constructor(public workspaceFolder: WorkspaceFolder, inputs: Setting[], inputFiles: SettingFile[]) { super('Inputs', TreeItemCollapsibleState.Collapsed); - this.description = `${inputs.filter(input => input.selected).length}/${inputs.length}`; + this.description = `${inputs.filter(input => input.selected).length}/${inputs.length}` + + (inputFiles.length > 0 ? ` + ${inputFiles.length} input file(s)` : ``); this.contextValue = InputsTreeItem.contextValue; this.iconPath = new ThemeIcon('record-keys'); } diff --git a/src/views/settings/secrets.ts b/src/views/settings/secrets.ts index 28eefda..577ff06 100644 --- a/src/views/settings/secrets.ts +++ b/src/views/settings/secrets.ts @@ -1,6 +1,6 @@ import { ThemeIcon, TreeItem, TreeItemCollapsibleState, WorkspaceFolder } from "vscode"; import { act } from "../../extension"; -import { Setting } from "../../settingsManager"; +import { Setting, SettingFile } from "../../settingsManager"; import { StorageKey } from "../../storageManager"; import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem"; import SettingTreeItem from "./setting"; @@ -10,9 +10,10 @@ export default class SecretsTreeItem extends TreeItem implements GithubLocalActi static contextValue = 'githubLocalActions.secrets'; storageKey = StorageKey.SecretFiles; - constructor(public workspaceFolder: WorkspaceFolder, secrets: Setting[]) { + constructor(public workspaceFolder: WorkspaceFolder, secrets: Setting[], secretFiles: SettingFile[]) { super('Secrets', TreeItemCollapsibleState.Collapsed); - this.description = `${secrets.filter(secret => secret.selected).length}/${secrets.length}`; + this.description = `${secrets.filter(secret => secret.selected).length}/${secrets.length}` + + (secretFiles.length > 0 ? ` + ${secretFiles.length} secret file(s)` : ``); this.contextValue = SecretsTreeItem.contextValue; this.iconPath = new ThemeIcon('lock'); } diff --git a/src/views/settings/settingsTreeDataProvider.ts b/src/views/settings/settingsTreeDataProvider.ts index dfff2bf..96be3b0 100644 --- a/src/views/settings/settingsTreeDataProvider.ts +++ b/src/views/settings/settingsTreeDataProvider.ts @@ -69,7 +69,12 @@ export default class SettingsTreeDataProvider implements TreeDataProvider { - + await act.settingsManager.removeSettingFile(settingFileTreeItem.workspaceFolder, settingFileTreeItem.settingFile, settingFileTreeItem.storageKey); + this.refresh(); + }), + commands.registerCommand('githubLocalActions.deleteSettingFile', async (settingFileTreeItem: SettingFileTreeItem) => { + await act.settingsManager.deleteSettingFile(settingFileTreeItem.workspaceFolder, settingFileTreeItem.settingFile, settingFileTreeItem.storageKey); + this.refresh(); }), commands.registerCommand('githubLocalActions.show', async (settingTreeItem: SettingTreeItem) => { const newSetting = settingTreeItem.setting; diff --git a/src/views/settings/variables.ts b/src/views/settings/variables.ts index 10316ef..9f335a4 100644 --- a/src/views/settings/variables.ts +++ b/src/views/settings/variables.ts @@ -1,6 +1,6 @@ import { ThemeIcon, TreeItem, TreeItemCollapsibleState, WorkspaceFolder } from "vscode"; import { act } from "../../extension"; -import { Setting } from "../../settingsManager"; +import { Setting, SettingFile } from "../../settingsManager"; import { StorageKey } from "../../storageManager"; import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem"; import SettingTreeItem from "./setting"; @@ -10,9 +10,10 @@ export default class VariablesTreeItem extends TreeItem implements GithubLocalAc static contextValue = 'githubLocalActions.variables'; storageKey = StorageKey.VariableFiles; - constructor(public workspaceFolder: WorkspaceFolder, variables: Setting[]) { + constructor(public workspaceFolder: WorkspaceFolder, variables: Setting[], variableFiles: SettingFile[]) { super('Variables', TreeItemCollapsibleState.Collapsed); - this.description = `${variables.filter(variable => variable.selected).length}/${variables.length}`; + this.description = `${variables.filter(variable => variable.selected).length}/${variables.length}` + + (variableFiles.length > 0 ? ` + ${variableFiles.length} variable file(s)` : ``); this.contextValue = VariablesTreeItem.contextValue; this.iconPath = new ThemeIcon('symbol-key'); } diff --git a/src/views/settings/workspaceFolderSettings.ts b/src/views/settings/workspaceFolderSettings.ts index 9b068a0..02379ba 100644 --- a/src/views/settings/workspaceFolderSettings.ts +++ b/src/views/settings/workspaceFolderSettings.ts @@ -20,9 +20,9 @@ export default class WorkspaceFolderSettingsTreeItem extends TreeItem implements const settings = await act.settingsManager.getSettings(this.workspaceFolder, false); items.push(...[ - new SecretsTreeItem(this.workspaceFolder, settings.secrets), - new VariablesTreeItem(this.workspaceFolder, settings.variables), - new InputsTreeItem(this.workspaceFolder, settings.inputs), + new SecretsTreeItem(this.workspaceFolder, settings.secrets, settings.secretFiles), + new VariablesTreeItem(this.workspaceFolder, settings.variables, settings.variableFiles), + new InputsTreeItem(this.workspaceFolder, settings.inputs, settings.inputFiles), new RunnersTreeItem(this.workspaceFolder, settings.runners) ]); diff --git a/src/workflowsManager.ts b/src/workflowsManager.ts index 9c3bf56..c487d33 100644 --- a/src/workflowsManager.ts +++ b/src/workflowsManager.ts @@ -34,7 +34,7 @@ export class WorkflowsManager { fileContent: fileContent, yaml: yaml.parse(fileContent) }); - } catch (error) { + } catch (error: any) { workflows.push({ name: (yamlContent ? yamlContent.name : undefined) || path.parse(workflowFileUri.fsPath).name, uri: workflowFileUri, From 9079f014c9c7ec8d45455f007ec50276d14458f6 Mon Sep 17 00:00:00 2001 From: Sanjula Ganepola Date: Thu, 21 Nov 2024 22:24:58 -0500 Subject: [PATCH 4/8] Fix setting file count description to be for user selected files Signed-off-by: Sanjula Ganepola --- src/views/settings/inputs.ts | 3 ++- src/views/settings/secrets.ts | 3 ++- src/views/settings/variables.ts | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/views/settings/inputs.ts b/src/views/settings/inputs.ts index 1b17339..ce36b7d 100644 --- a/src/views/settings/inputs.ts +++ b/src/views/settings/inputs.ts @@ -12,8 +12,9 @@ export default class InputsTreeItem extends TreeItem implements GithubLocalActio constructor(public workspaceFolder: WorkspaceFolder, inputs: Setting[], inputFiles: SettingFile[]) { super('Inputs', TreeItemCollapsibleState.Collapsed); + const selectedInputFiles = inputFiles.filter(inputFile => inputFile.selected); this.description = `${inputs.filter(input => input.selected).length}/${inputs.length}` + - (inputFiles.length > 0 ? ` + ${inputFiles.length} input file(s)` : ``); + (selectedInputFiles.length > 0 ? ` + ${selectedInputFiles.length} input file(s)` : ``); this.contextValue = InputsTreeItem.contextValue; this.iconPath = new ThemeIcon('record-keys'); } diff --git a/src/views/settings/secrets.ts b/src/views/settings/secrets.ts index 577ff06..8f1be60 100644 --- a/src/views/settings/secrets.ts +++ b/src/views/settings/secrets.ts @@ -12,8 +12,9 @@ export default class SecretsTreeItem extends TreeItem implements GithubLocalActi constructor(public workspaceFolder: WorkspaceFolder, secrets: Setting[], secretFiles: SettingFile[]) { super('Secrets', TreeItemCollapsibleState.Collapsed); + const selectedSecretFiles = secretFiles.filter(secretFile => secretFile.selected); this.description = `${secrets.filter(secret => secret.selected).length}/${secrets.length}` + - (secretFiles.length > 0 ? ` + ${secretFiles.length} secret file(s)` : ``); + (selectedSecretFiles.length > 0 ? ` + ${selectedSecretFiles.length} secret file(s)` : ``); this.contextValue = SecretsTreeItem.contextValue; this.iconPath = new ThemeIcon('lock'); } diff --git a/src/views/settings/variables.ts b/src/views/settings/variables.ts index 9f335a4..b8b0d28 100644 --- a/src/views/settings/variables.ts +++ b/src/views/settings/variables.ts @@ -12,8 +12,9 @@ export default class VariablesTreeItem extends TreeItem implements GithubLocalAc constructor(public workspaceFolder: WorkspaceFolder, variables: Setting[], variableFiles: SettingFile[]) { super('Variables', TreeItemCollapsibleState.Collapsed); + const selectedVariableFiles = variableFiles.filter(variableFile => variableFile.selected); this.description = `${variables.filter(variable => variable.selected).length}/${variables.length}` + - (variableFiles.length > 0 ? ` + ${variableFiles.length} variable file(s)` : ``); + (selectedVariableFiles.length > 0 ? ` + ${selectedVariableFiles.length} variable file(s)` : ``); this.contextValue = VariablesTreeItem.contextValue; this.iconPath = new ThemeIcon('symbol-key'); } From 55545573721e9e970f08ec33efcc783d855fbef1 Mon Sep 17 00:00:00 2001 From: Sanjula Ganepola Date: Fri, 22 Nov 2024 17:31:09 -0500 Subject: [PATCH 5/8] Add file to act command Signed-off-by: Sanjula Ganepola --- src/act.ts | 10 ++++++++-- src/settingsManager.ts | 15 ++++++++++----- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/act.ts b/src/act.ts index f3923c7..d9e3379 100644 --- a/src/act.ts +++ b/src/act.ts @@ -46,12 +46,15 @@ export enum Event { } export enum Option { - Input = '--input', + Workflows = '-W', Job = '-j', Platform = '-P', Secret = '--secret', + SecretFile = '--secret-file', Variable = '--var', - Workflows = '-W' + VariableFile = '--var-file', + Input = '--input', + InputFile = '--input-file' } export interface CommandArgs { @@ -306,8 +309,11 @@ export class Act { `set -o pipefail; ` + `${Act.base} ${commandArgs.options}` + (settings.secrets.length > 0 ? ` ${Option.Secret} ${settings.secrets.map(secret => secret.key).join(` ${Option.Secret} `)}` : ``) + + (settings.secretFiles.length > 0 ? ` ${Option.SecretFile} ${settings.secretFiles.map(secretFile => `"${secretFile.path}"`).join(` ${Option.SecretFile} `)}` : ``) + (settings.variables.length > 0 ? ` ${Option.Variable} ${settings.variables.map(variable => (variable.value ? `${variable.key}=${variable.value}` : variable.key)).join(` ${Option.Variable} `)}` : ``) + + (settings.variableFiles.length > 0 ? ` ${Option.VariableFile} ${settings.variableFiles.map(variableFile => `"${variableFile.path}"`).join(` ${Option.VariableFile} `)}` : ``) + (settings.inputs.length > 0 ? ` ${Option.Input} ${settings.inputs.map(input => `${input.key}=${input.value}`).join(` ${Option.Input} `)}` : ``) + + (settings.inputFiles.length > 0 ? ` ${Option.InputFile} ${settings.inputFiles.map(inputFile => `"${inputFile.path}"`).join(` ${Option.InputFile} `)}` : ``) + (settings.runners.length > 0 ? ` ${Option.Platform} ${settings.runners.map(runner => `${runner.key}=${runner.value}`).join(` ${Option.Platform} `)}` : ``) + ` 2>&1 | tee "${logPath}"`; diff --git a/src/settingsManager.ts b/src/settingsManager.ts index cfcb334..7cdd7a8 100644 --- a/src/settingsManager.ts +++ b/src/settingsManager.ts @@ -51,11 +51,11 @@ export class SettingsManager { async getSettings(workspaceFolder: WorkspaceFolder, isUserSelected: boolean): Promise { const secrets = (await this.getSetting(workspaceFolder, SettingsManager.secretsRegExp, StorageKey.Secrets, true, Visibility.hide)).filter(secret => !isUserSelected || secret.selected); - const secretFiles = await this.getSettingFiles(workspaceFolder, StorageKey.SecretFiles); + const secretFiles = (await this.getSettingFiles(workspaceFolder, StorageKey.SecretFiles)).filter(secretFile => !isUserSelected || secretFile.selected); const variables = (await this.getSetting(workspaceFolder, SettingsManager.variablesRegExp, StorageKey.Variables, false, Visibility.show)).filter(variable => !isUserSelected || variable.selected); - const variableFiles = await this.getSettingFiles(workspaceFolder, StorageKey.VariableFiles); + const variableFiles = (await this.getSettingFiles(workspaceFolder, StorageKey.VariableFiles)).filter(variableFile => !isUserSelected || variableFile.selected); const inputs = (await this.getSetting(workspaceFolder, SettingsManager.inputsRegExp, StorageKey.Inputs, false, Visibility.show)).filter(input => !isUserSelected || (input.selected && input.value)); - const inputFiles = await this.getSettingFiles(workspaceFolder, StorageKey.InputFiles); + const inputFiles = (await this.getSettingFiles(workspaceFolder, StorageKey.InputFiles)).filter(inputFile => !isUserSelected || inputFile.selected); const runners = (await this.getSetting(workspaceFolder, SettingsManager.runnersRegExp, StorageKey.Runners, false, Visibility.show)).filter(runner => !isUserSelected || (runner.selected && runner.value)); const environments = await this.getEnvironments(workspaceFolder); @@ -184,10 +184,15 @@ export class SettingsManager { async deleteSettingFile(workspaceFolder: WorkspaceFolder, settingFile: SettingFile, storageKey: StorageKey) { try { await workspace.fs.delete(Uri.file(settingFile.path)); - await this.removeSettingFile(workspaceFolder, settingFile, storageKey); } catch (error: any) { - window.showErrorMessage(`Failed to delete file. Error ${error}`) + try { + await workspace.fs.stat(Uri.file(settingFile.path)); + window.showErrorMessage(`Failed to delete file. Error ${error}`); + return; + } catch (error) { } } + + await this.removeSettingFile(workspaceFolder, settingFile, storageKey); } async editSetting(workspaceFolder: WorkspaceFolder, newSetting: Setting, storageKey: StorageKey) { From 2082c3c31260d5e68cb6bca411f19a5757c3d60a Mon Sep 17 00:00:00 2001 From: Sanjula Ganepola Date: Fri, 22 Nov 2024 20:16:29 -0500 Subject: [PATCH 6/8] Only support single setting file at a time Signed-off-by: Sanjula Ganepola --- src/views/settings/settingsTreeDataProvider.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/views/settings/settingsTreeDataProvider.ts b/src/views/settings/settingsTreeDataProvider.ts index 96be3b0..4a3a546 100644 --- a/src/views/settings/settingsTreeDataProvider.ts +++ b/src/views/settings/settingsTreeDataProvider.ts @@ -234,9 +234,24 @@ export default class SettingsTreeDataProvider implements TreeDataProvider Date: Fri, 22 Nov 2024 20:17:35 -0500 Subject: [PATCH 7/8] Add actions to create and locate setting files Signed-off-by: Sanjula Ganepola --- package.json | 85 ++++++++++---- src/act.ts | 6 +- src/settingsManager.ts | 49 ++++++++ src/views/settings/inputs.ts | 2 +- src/views/settings/secrets.ts | 2 +- .../settings/settingsTreeDataProvider.ts | 108 ++++++++++++------ src/views/settings/variables.ts | 2 +- 7 files changed, 191 insertions(+), 63 deletions(-) diff --git a/package.json b/package.json index 54a7e16..8fb7c41 100644 --- a/package.json +++ b/package.json @@ -242,10 +242,16 @@ }, { "category": "GitHub Local Actions", - "command": "githubLocalActions.addSecretFiles", - "title": "Add Secret Files", + "command": "githubLocalActions.createSecretFile", + "title": "Create Secret File", "icon": "$(add)" }, + { + "category": "GitHub Local Actions", + "command": "githubLocalActions.locateSecretFiles", + "title": "Locate Secret Files", + "icon": "$(search)" + }, { "category": "GitHub Local Actions", "command": "githubLocalActions.show", @@ -260,22 +266,34 @@ }, { "category": "GitHub Local Actions", - "command": "githubLocalActions.addVariableFiles", - "title": "Add Variable Files", + "command": "githubLocalActions.createVariableFile", + "title": "Create Variable File", "icon": "$(add)" }, + { + "category": "GitHub Local Actions", + "command": "githubLocalActions.locateVariableFiles", + "title": "Locate Variable Files", + "icon": "$(search)" + }, + { + "category": "GitHub Local Actions", + "command": "githubLocalActions.createInputFile", + "title": "Create Input File", + "icon": "$(add)" + }, + { + "category": "GitHub Local Actions", + "command": "githubLocalActions.locateInputFiles", + "title": "Locate Input Files", + "icon": "$(search)" + }, { "category": "GitHub Local Actions", "command": "githubLocalActions.importFromGithub", "title": "Import from GitHub", "icon": "$(github)" }, - { - "category": "GitHub Local Actions", - "command": "githubLocalActions.addInputFiles", - "title": "Add Input Files", - "icon": "$(add)" - }, { "category": "GitHub Local Actions", "command": "githubLocalActions.openSettingFile", @@ -389,7 +407,11 @@ "when": "never" }, { - "command": "githubLocalActions.addSecretFiles", + "command": "githubLocalActions.createSecretFile", + "when": "never" + }, + { + "command": "githubLocalActions.locateSecretFiles", "when": "never" }, { @@ -401,17 +423,25 @@ "when": "never" }, { - "command": "githubLocalActions.addVariableFiles", + "command": "githubLocalActions.createVariableFile", + "when": "never" + }, + { + "command": "githubLocalActions.locateVariableFiles", + "when": "never" + }, + { + "command": "githubLocalActions.createInputFile", + "when": "never" + }, + { + "command": "githubLocalActions.locateInputFiles", "when": "never" }, { "command": "githubLocalActions.importFromGithub", "when": "never" }, - { - "command": "githubLocalActions.addInputFiles", - "when": "never" - }, { "command": "githubLocalActions.openSettingFile", "when": "never" @@ -556,10 +586,15 @@ "group": "inline@3" }, { - "command": "githubLocalActions.addSecretFiles", + "command": "githubLocalActions.createSecretFile", "when": "view == settings && viewItem =~ /^githubLocalActions.secrets.*/", "group": "inline@0" }, + { + "command": "githubLocalActions.locateSecretFiles", + "when": "view == settings && viewItem =~ /^githubLocalActions.secrets.*/", + "group": "inline@1" + }, { "command": "githubLocalActions.show", "when": "view == settings && viewItem =~ /^githubLocalActions.secret(?!s)_hide.*/", @@ -571,20 +606,30 @@ "group": "inline@0" }, { - "command": "githubLocalActions.addVariableFiles", + "command": "githubLocalActions.createVariableFile", "when": "view == settings && viewItem =~ /^githubLocalActions.variables.*/", "group": "inline@0" }, { - "command": "githubLocalActions.importFromGithub", + "command": "githubLocalActions.locateVariableFiles", "when": "view == settings && viewItem =~ /^githubLocalActions.variables.*/", "group": "inline@1" }, { - "command": "githubLocalActions.addInputFiles", + "command": "githubLocalActions.createInputFile", "when": "view == settings && viewItem =~ /^githubLocalActions.inputs.*/", "group": "inline@0" }, + { + "command": "githubLocalActions.locateInputFiles", + "when": "view == settings && viewItem =~ /^githubLocalActions.inputs.*/", + "group": "inline@1" + }, + { + "command": "githubLocalActions.importFromGithub", + "when": "view == settings && viewItem =~ /^githubLocalActions.variables.*/", + "group": "inline@2" + }, { "command": "githubLocalActions.openSettingFile", "when": "view == settings && viewItem =~ /^githubLocalActions.(secret|variable|input)File.*/", diff --git a/src/act.ts b/src/act.ts index d9e3379..c2fce97 100644 --- a/src/act.ts +++ b/src/act.ts @@ -309,11 +309,11 @@ export class Act { `set -o pipefail; ` + `${Act.base} ${commandArgs.options}` + (settings.secrets.length > 0 ? ` ${Option.Secret} ${settings.secrets.map(secret => secret.key).join(` ${Option.Secret} `)}` : ``) + - (settings.secretFiles.length > 0 ? ` ${Option.SecretFile} ${settings.secretFiles.map(secretFile => `"${secretFile.path}"`).join(` ${Option.SecretFile} `)}` : ``) + + (settings.secretFiles.length > 0 ? ` ${Option.SecretFile} ${settings.secretFiles[0].path}` : ` ${Option.SecretFile} ""`) + (settings.variables.length > 0 ? ` ${Option.Variable} ${settings.variables.map(variable => (variable.value ? `${variable.key}=${variable.value}` : variable.key)).join(` ${Option.Variable} `)}` : ``) + - (settings.variableFiles.length > 0 ? ` ${Option.VariableFile} ${settings.variableFiles.map(variableFile => `"${variableFile.path}"`).join(` ${Option.VariableFile} `)}` : ``) + + (settings.variableFiles.length > 0 ? ` ${Option.VariableFile} ${settings.variableFiles[0].path}` : ` ${Option.VariableFile} ""`) + (settings.inputs.length > 0 ? ` ${Option.Input} ${settings.inputs.map(input => `${input.key}=${input.value}`).join(` ${Option.Input} `)}` : ``) + - (settings.inputFiles.length > 0 ? ` ${Option.InputFile} ${settings.inputFiles.map(inputFile => `"${inputFile.path}"`).join(` ${Option.InputFile} `)}` : ``) + + (settings.inputFiles.length > 0 ? ` ${Option.InputFile} ${settings.inputFiles[0].path}` : ` ${Option.InputFile} ""`) + (settings.runners.length > 0 ? ` ${Option.Platform} ${settings.runners.map(runner => `${runner.key}=${runner.value}`).join(` ${Option.Platform} `)}` : ``) + ` 2>&1 | tee "${logPath}"`; diff --git a/src/settingsManager.ts b/src/settingsManager.ts index 7cdd7a8..6f71337 100644 --- a/src/settingsManager.ts +++ b/src/settingsManager.ts @@ -1,3 +1,4 @@ +import * as path from "path"; import { Uri, window, workspace, WorkspaceFolder } from "vscode"; import { act } from "./extension"; import { GitHubManager } from "./githubManager"; @@ -34,6 +35,12 @@ export enum Visibility { hide = 'hide' } +export enum SettingFileName { + secretFile = '.secrets', + variableFile = '.env', + inputFile = '.input' +} + export class SettingsManager { storageManager: StorageManager; secretManager: SecretManager; @@ -153,6 +160,48 @@ export class SettingsManager { return environments; } + async createSettingFile(workspaceFolder: WorkspaceFolder, storageKey: StorageKey, settingFileName: string) { + const settingFileUri = Uri.file(path.join(workspaceFolder.uri.fsPath, settingFileName)); + + try { + await workspace.fs.stat(settingFileUri); + window.showErrorMessage(`A file or folder named ${settingFileName} already exists at ${workspaceFolder.uri.fsPath}. Please choose another name.`); + } catch (error: any) { + try { + await workspace.fs.writeFile(settingFileUri, new TextEncoder().encode('')); + await this.locateSettingFile(workspaceFolder, storageKey, [settingFileUri]); + const document = await workspace.openTextDocument(settingFileUri); + await window.showTextDocument(document); + } catch (error: any) { + window.showErrorMessage(`Failed to create ${settingFileName}. Error: ${error}`) + } + } + } + + async locateSettingFile(workspaceFolder: WorkspaceFolder, storageKey: StorageKey, settingFilesUris: Uri[]) { + const settingFilesPaths = (await act.settingsManager.getSettingFiles(workspaceFolder, storageKey)).map(settingFile => settingFile.path); + const existingSettingFileNames: string[] = []; + + for await (const uri of settingFilesUris) { + const settingFileName = path.parse(uri.fsPath).name; + + if (settingFilesPaths.includes(uri.fsPath)) { + existingSettingFileNames.push(settingFileName); + } else { + const newSettingFile: SettingFile = { + name: path.parse(uri.fsPath).base, + path: uri.fsPath, + selected: false + }; + await act.settingsManager.editSettingFile(workspaceFolder, newSettingFile, storageKey); + } + } + + if (existingSettingFileNames.length > 0) { + window.showErrorMessage(`The following file(s) have already been added: ${existingSettingFileNames.join(', ')}`); + } + } + async editSettingFile(workspaceFolder: WorkspaceFolder, newSettingFile: SettingFile, storageKey: StorageKey) { const existingSettingFiles = this.storageManager.get<{ [path: string]: SettingFile[] }>(storageKey) || {}; if (existingSettingFiles[workspaceFolder.uri.fsPath]) { diff --git a/src/views/settings/inputs.ts b/src/views/settings/inputs.ts index ce36b7d..6c1deb9 100644 --- a/src/views/settings/inputs.ts +++ b/src/views/settings/inputs.ts @@ -14,7 +14,7 @@ export default class InputsTreeItem extends TreeItem implements GithubLocalActio super('Inputs', TreeItemCollapsibleState.Collapsed); const selectedInputFiles = inputFiles.filter(inputFile => inputFile.selected); this.description = `${inputs.filter(input => input.selected).length}/${inputs.length}` + - (selectedInputFiles.length > 0 ? ` + ${selectedInputFiles.length} input file(s)` : ``); + (selectedInputFiles.length > 0 ? ` + ${selectedInputFiles[0].name}` : ``); this.contextValue = InputsTreeItem.contextValue; this.iconPath = new ThemeIcon('record-keys'); } diff --git a/src/views/settings/secrets.ts b/src/views/settings/secrets.ts index 8f1be60..8259532 100644 --- a/src/views/settings/secrets.ts +++ b/src/views/settings/secrets.ts @@ -14,7 +14,7 @@ export default class SecretsTreeItem extends TreeItem implements GithubLocalActi super('Secrets', TreeItemCollapsibleState.Collapsed); const selectedSecretFiles = secretFiles.filter(secretFile => secretFile.selected); this.description = `${secrets.filter(secret => secret.selected).length}/${secrets.length}` + - (selectedSecretFiles.length > 0 ? ` + ${selectedSecretFiles.length} secret file(s)` : ``); + (selectedSecretFiles.length > 0 ? ` + ${selectedSecretFiles[0].name}` : ``); this.contextValue = SecretsTreeItem.contextValue; this.iconPath = new ThemeIcon('lock'); } diff --git a/src/views/settings/settingsTreeDataProvider.ts b/src/views/settings/settingsTreeDataProvider.ts index 4a3a546..1de0022 100644 --- a/src/views/settings/settingsTreeDataProvider.ts +++ b/src/views/settings/settingsTreeDataProvider.ts @@ -1,7 +1,6 @@ -import * as path from "path"; import { CancellationToken, commands, EventEmitter, ExtensionContext, QuickPickItem, QuickPickItemKind, ThemeIcon, TreeCheckboxChangeEvent, TreeDataProvider, TreeItem, TreeItemCheckboxState, window, workspace } from "vscode"; import { act } from "../../extension"; -import { SettingFile, Visibility } from "../../settingsManager"; +import { SettingFileName, Visibility } from "../../settingsManager"; import { StorageKey } from "../../storageManager"; import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem"; import InputsTreeItem from "./inputs"; @@ -21,48 +20,83 @@ export default class SettingsTreeDataProvider implements TreeDataProvider { this.refresh(); }), - commands.registerCommand('githubLocalActions.addSettingFiles', async (treeItem: SecretsTreeItem | VariablesTreeItem | InputsTreeItem, title: string) => { - const settingFilesUris = await window.showOpenDialog({ - title: title, - canSelectFiles: true, - canSelectFolders: false, - canSelectMany: true, - defaultUri: treeItem.workspaceFolder.uri + commands.registerCommand('githubLocalActions.createSecretFile', async (secretsTreeItem: SecretsTreeItem) => { + const secretFileName = await window.showInputBox({ + prompt: `Enter the name for the secret file`, + placeHolder: `Secret File Name`, + value: SettingFileName.secretFile }); - if (settingFilesUris) { - const settingFilesPaths = (await act.settingsManager.getSettingFiles(treeItem.workspaceFolder, treeItem.storageKey)).map(settingFile => settingFile.path); - const existingSettingFileNames: string[] = []; - - for await (const uri of settingFilesUris) { - const settingFileName = path.parse(uri.fsPath).name; - - if (settingFilesPaths.includes(uri.fsPath)) { - existingSettingFileNames.push(settingFileName); - } else { - const newSettingFile: SettingFile = { - name: path.parse(uri.fsPath).base, - path: uri.fsPath, - selected: false - }; - await act.settingsManager.editSettingFile(treeItem.workspaceFolder, newSettingFile, treeItem.storageKey); - } - } - - if (existingSettingFileNames.length > 0) { - window.showErrorMessage(`The following file(s) have already been added: ${existingSettingFileNames.join(', ')}`); - } + if (secretFileName) { + await act.settingsManager.createSettingFile(secretsTreeItem.workspaceFolder, secretsTreeItem.storageKey, secretFileName); this.refresh(); } }), - commands.registerCommand('githubLocalActions.addSecretFiles', async (secretsTreeItem: SecretsTreeItem) => { - await commands.executeCommand('githubLocalActions.addSettingFiles', secretsTreeItem, 'Add Secret File'); + commands.registerCommand('githubLocalActions.locateSecretFiles', async (secretsTreeItem: SecretsTreeItem) => { + const secretFilesUris = await window.showOpenDialog({ + title: 'Locate Secret Files', + canSelectFiles: true, + canSelectFolders: false, + canSelectMany: true, + defaultUri: secretsTreeItem.workspaceFolder.uri + }); + + if (secretFilesUris) { + await act.settingsManager.locateSettingFile(secretsTreeItem.workspaceFolder, secretsTreeItem.storageKey, secretFilesUris); + this.refresh(); + } }), - commands.registerCommand('githubLocalActions.addVariableFiles', async (variablesTreeItem: VariablesTreeItem) => { - await commands.executeCommand('githubLocalActions.addSettingFiles', variablesTreeItem, 'Add Variable File'); + commands.registerCommand('githubLocalActions.createVariableFile', async (variablesTreeItem: VariablesTreeItem) => { + const variableFileName = await window.showInputBox({ + prompt: `Enter the name for the variable file`, + placeHolder: `Variable File Name`, + value: SettingFileName.variableFile + }); + + if (variableFileName) { + await act.settingsManager.createSettingFile(variablesTreeItem.workspaceFolder, variablesTreeItem.storageKey, variableFileName); + this.refresh(); + } }), - commands.registerCommand('githubLocalActions.addInputFiles', async (inputsTreeItem: InputsTreeItem) => { - await commands.executeCommand('githubLocalActions.addSettingFiles', inputsTreeItem, 'Add Input File'); + commands.registerCommand('githubLocalActions.locateVariableFiles', async (variablesTreeItem: VariablesTreeItem) => { + const variableFilesUris = await window.showOpenDialog({ + title: 'Locate Variable Files', + canSelectFiles: true, + canSelectFolders: false, + canSelectMany: true, + defaultUri: variablesTreeItem.workspaceFolder.uri + }); + + if (variableFilesUris) { + await act.settingsManager.locateSettingFile(variablesTreeItem.workspaceFolder, variablesTreeItem.storageKey, variableFilesUris); + this.refresh(); + } + }), + commands.registerCommand('githubLocalActions.createInputFile', async (inputsTreeItem: InputsTreeItem) => { + const inputFileName = await window.showInputBox({ + prompt: `Enter the name for the input file`, + placeHolder: `Input File Name`, + value: SettingFileName.inputFile + }); + + if (inputFileName) { + await act.settingsManager.createSettingFile(inputsTreeItem.workspaceFolder, inputsTreeItem.storageKey, inputFileName); + this.refresh(); + } + }), + commands.registerCommand('githubLocalActions.locateInputFiles', async (inputsTreeItem: InputsTreeItem) => { + const inputFilesUris = await window.showOpenDialog({ + title: 'Locate Variable Files', + canSelectFiles: true, + canSelectFolders: false, + canSelectMany: true, + defaultUri: inputsTreeItem.workspaceFolder.uri + }); + + if (inputFilesUris) { + await act.settingsManager.locateSettingFile(inputsTreeItem.workspaceFolder, inputsTreeItem.storageKey, inputFilesUris); + this.refresh(); + } }), commands.registerCommand('githubLocalActions.openSettingFile', async (settingFileTreeItem: SettingFileTreeItem) => { const document = await workspace.openTextDocument(settingFileTreeItem.settingFile.path); diff --git a/src/views/settings/variables.ts b/src/views/settings/variables.ts index b8b0d28..da6e4a9 100644 --- a/src/views/settings/variables.ts +++ b/src/views/settings/variables.ts @@ -14,7 +14,7 @@ export default class VariablesTreeItem extends TreeItem implements GithubLocalAc super('Variables', TreeItemCollapsibleState.Collapsed); const selectedVariableFiles = variableFiles.filter(variableFile => variableFile.selected); this.description = `${variables.filter(variable => variable.selected).length}/${variables.length}` + - (selectedVariableFiles.length > 0 ? ` + ${selectedVariableFiles.length} variable file(s)` : ``); + (selectedVariableFiles.length > 0 ? ` + ${selectedVariableFiles[0].name} variable file(s)` : ``); this.contextValue = VariablesTreeItem.contextValue; this.iconPath = new ThemeIcon('symbol-key'); } From 4349f2993e092b5aaa31865e8b558ef8d75d22a3 Mon Sep 17 00:00:00 2001 From: Sanjula Ganepola Date: Fri, 22 Nov 2024 21:20:24 -0500 Subject: [PATCH 8/8] Fix description and add missing quotes Signed-off-by: Sanjula Ganepola --- src/act.ts | 6 +++--- src/views/settings/variables.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/act.ts b/src/act.ts index c2fce97..7aca230 100644 --- a/src/act.ts +++ b/src/act.ts @@ -309,11 +309,11 @@ export class Act { `set -o pipefail; ` + `${Act.base} ${commandArgs.options}` + (settings.secrets.length > 0 ? ` ${Option.Secret} ${settings.secrets.map(secret => secret.key).join(` ${Option.Secret} `)}` : ``) + - (settings.secretFiles.length > 0 ? ` ${Option.SecretFile} ${settings.secretFiles[0].path}` : ` ${Option.SecretFile} ""`) + + (settings.secretFiles.length > 0 ? ` ${Option.SecretFile} "${settings.secretFiles[0].path}"` : ` ${Option.SecretFile} ""`) + (settings.variables.length > 0 ? ` ${Option.Variable} ${settings.variables.map(variable => (variable.value ? `${variable.key}=${variable.value}` : variable.key)).join(` ${Option.Variable} `)}` : ``) + - (settings.variableFiles.length > 0 ? ` ${Option.VariableFile} ${settings.variableFiles[0].path}` : ` ${Option.VariableFile} ""`) + + (settings.variableFiles.length > 0 ? ` ${Option.VariableFile} "${settings.variableFiles[0].path}"` : ` ${Option.VariableFile} ""`) + (settings.inputs.length > 0 ? ` ${Option.Input} ${settings.inputs.map(input => `${input.key}=${input.value}`).join(` ${Option.Input} `)}` : ``) + - (settings.inputFiles.length > 0 ? ` ${Option.InputFile} ${settings.inputFiles[0].path}` : ` ${Option.InputFile} ""`) + + (settings.inputFiles.length > 0 ? ` ${Option.InputFile} "${settings.inputFiles[0].path}"` : ` ${Option.InputFile} ""`) + (settings.runners.length > 0 ? ` ${Option.Platform} ${settings.runners.map(runner => `${runner.key}=${runner.value}`).join(` ${Option.Platform} `)}` : ``) + ` 2>&1 | tee "${logPath}"`; diff --git a/src/views/settings/variables.ts b/src/views/settings/variables.ts index da6e4a9..09b6a8a 100644 --- a/src/views/settings/variables.ts +++ b/src/views/settings/variables.ts @@ -14,7 +14,7 @@ export default class VariablesTreeItem extends TreeItem implements GithubLocalAc super('Variables', TreeItemCollapsibleState.Collapsed); const selectedVariableFiles = variableFiles.filter(variableFile => variableFile.selected); this.description = `${variables.filter(variable => variable.selected).length}/${variables.length}` + - (selectedVariableFiles.length > 0 ? ` + ${selectedVariableFiles[0].name} variable file(s)` : ``); + (selectedVariableFiles.length > 0 ? ` + ${selectedVariableFiles[0].name}` : ``); this.contextValue = VariablesTreeItem.contextValue; this.iconPath = new ThemeIcon('symbol-key'); }