Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for job and step level execution status #95

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
28 changes: 25 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,11 @@
"enablement": "viewItem =~ /^githubLocalActions.history_(Success|Failed|Cancelled).*/",
"icon": "$(close)"
},
{
"category": "GitHub Local Actions",
"command": "githubLocalActions.focusTask",
"title": "Focus Task"
},
{
"category": "GitHub Local Actions",
"command": "githubLocalActions.refreshSettings",
Expand Down Expand Up @@ -436,6 +441,10 @@
"command": "githubLocalActions.remove",
"when": "never"
},
{
"command": "githubLocalActions.focusTask",
"when": "never"
},
{
"command": "githubLocalActions.refreshSettings",
"when": "never"
Expand Down Expand Up @@ -640,6 +649,11 @@
"when": "view == history && viewItem =~ /^githubLocalActions.history.*/",
"group": "inline@3"
},
{
"command": "githubLocalActions.focusTask",
"when": "view == history && viewItem =~ /^githubLocalActions.history.*/",
"group": "0_focus@0"
},
{
"command": "githubLocalActions.createSecretFile",
"when": "view == settings && viewItem =~ /^githubLocalActions.secrets.*/",
Expand Down Expand Up @@ -745,23 +759,31 @@
"colors": [
{
"id": "GitHubLocalActions.green",
"description": "Color for green in GitHub Local Actions extension",
"description": "Color for green in the GitHub Local Actions extension",
"defaults": {
"dark": "#89d185",
"light": "#89d185"
}
},
{
"id": "GitHubLocalActions.yellow",
"description": "Color for yellow in GitHub Local Actions extension",
"description": "Color for yellow in the GitHub Local Actions extension",
"defaults": {
"dark": "#cca700",
"light": "#cca700"
}
},
{
"id": "GitHubLocalActions.purple",
"description": "Color for purple in the GitHub Local Actions extension",
"defaults": {
"dark": "#d6bcfa",
"light": "#d6bcfa"
}
},
{
"id": "GitHubLocalActions.red",
"description": "Color for red in GitHub Local Actions extension",
"description": "Color for red in the GitHub Local Actions extension",
"defaults": {
"dark": "#f48771",
"light": "#f48771"
Expand Down
261 changes: 203 additions & 58 deletions src/act.ts

Large diffs are not rendered by default.

64 changes: 58 additions & 6 deletions src/historyManager.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TaskExecution, Uri, window, workspace, WorkspaceFolder } from "vscode";
import { TaskExecution, ThemeColor, ThemeIcon, Uri, window, workspace, WorkspaceFolder } from "vscode";
import { CommandArgs } from "./act";
import { act, historyTreeDataProvider } from "./extension";
import { StorageKey, StorageManager } from "./storageManager";
Expand All @@ -12,16 +12,38 @@ export interface History {
start: string,
end?: string,
},
taskExecution?: TaskExecution,
commandArgs: CommandArgs,
logPath: string
logPath: string,
taskExecution?: TaskExecution,
jobs?: Job[],
}

export interface Job {
name: string,
status: HistoryStatus,
date: {
start: string,
end?: string,
},
steps?: Step[]
}

export interface Step {
id: string,
name: string,
status: HistoryStatus,
date: {
start: string,
end?: string,
}
}

export enum HistoryStatus {
Running = 'Running',
Success = 'Success',
Failed = 'Failed',
Cancelled = 'Cancelled'
Cancelled = 'Cancelled',
Unknown = 'Unknown'
}

export class HistoryManager {
Expand All @@ -33,6 +55,21 @@ export class HistoryManager {
const workspaceHistory = this.storageManager.get<{ [path: string]: History[] }>(StorageKey.WorkspaceHistory) || {};
for (const [path, historyLogs] of Object.entries(workspaceHistory)) {
workspaceHistory[path] = historyLogs.map(history => {
history.jobs?.forEach((job, jobIndex) => {
history.jobs![jobIndex].steps?.forEach((step, stepIndex) => {
// Update status of all running steps
if (step.status === HistoryStatus.Running) {
history.jobs![jobIndex].steps![stepIndex].status = HistoryStatus.Cancelled;
}
});

// Update status of all running jobs
if (job.status === HistoryStatus.Running) {
history.jobs![jobIndex].status = HistoryStatus.Cancelled;
}
});

// Update history status
if (history.status === HistoryStatus.Running) {
history.status = HistoryStatus.Cancelled;
}
Expand All @@ -53,7 +90,7 @@ export class HistoryManager {

this.workspaceHistory[workspaceFolder.uri.fsPath] = [];
historyTreeDataProvider.refresh();
this.storageManager.update(StorageKey.WorkspaceHistory, this.workspaceHistory);
await this.storageManager.update(StorageKey.WorkspaceHistory, this.workspaceHistory);
}

async viewOutput(history: History) {
Expand All @@ -77,11 +114,26 @@ export class HistoryManager {
const historyIndex = this.workspaceHistory[history.commandArgs.path].findIndex(workspaceHistory => workspaceHistory.index === history.index);
if (historyIndex > -1) {
this.workspaceHistory[history.commandArgs.path].splice(historyIndex, 1);
this.storageManager.update(StorageKey.WorkspaceHistory, this.workspaceHistory);
await this.storageManager.update(StorageKey.WorkspaceHistory, this.workspaceHistory);

try {
await workspace.fs.delete(Uri.file(history.logPath));
} catch (error: any) { }
}
}

static statusToIcon(status: HistoryStatus) {
switch (status) {
case HistoryStatus.Running:
return new ThemeIcon('loading~spin');
case HistoryStatus.Success:
return new ThemeIcon('pass', new ThemeColor('GitHubLocalActions.green'));
case HistoryStatus.Failed:
return new ThemeIcon('error', new ThemeColor('GitHubLocalActions.red'));
case HistoryStatus.Cancelled:
return new ThemeIcon('circle-slash', new ThemeColor('GitHubLocalActions.yellow'));
case HistoryStatus.Unknown:
return new ThemeIcon('question', new ThemeColor('GitHubLocalActions.purple'));
}
}
}
8 changes: 4 additions & 4 deletions src/settingsManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export interface Settings {
runners: Setting[];
payloadFiles: CustomSetting[];
options: CustomSetting[];
environments: Setting[];
// environments: Setting[];
}

export interface Setting {
Expand Down Expand Up @@ -74,7 +74,7 @@ export class SettingsManager {
const runners = (await this.getSetting(workspaceFolder, SettingsManager.runnersRegExp, StorageKey.Runners, false, Visibility.show)).filter(runner => !isUserSelected || (runner.selected && runner.value));
const payloadFiles = (await this.getCustomSettings(workspaceFolder, StorageKey.PayloadFiles)).filter(payloadFile => !isUserSelected || payloadFile.selected);
const options = (await this.getCustomSettings(workspaceFolder, StorageKey.Options)).filter(option => !isUserSelected || (option.selected && (option.path || option.notEditable)));
const environments = await this.getEnvironments(workspaceFolder);
// const environments = await this.getEnvironments(workspaceFolder);

return {
secrets: secrets,
Expand All @@ -86,7 +86,7 @@ export class SettingsManager {
runners: runners,
payloadFiles: payloadFiles,
options: options,
environments: environments
// environments: environments
};
}

Expand Down Expand Up @@ -131,7 +131,7 @@ export class SettingsManager {
}
}
existingSettings[workspaceFolder.uri.fsPath] = settings;
this.storageManager.update(storageKey, existingSettings);
await this.storageManager.update(storageKey, existingSettings);

return settings;
}
Expand Down
29 changes: 6 additions & 23 deletions src/views/history/history.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import * as path from "path";
import { ThemeColor, ThemeIcon, TreeItem, TreeItemCollapsibleState, WorkspaceFolder } from "vscode";
import { History, HistoryStatus } from "../../historyManager";
import { TreeItem, TreeItemCollapsibleState, WorkspaceFolder } from "vscode";
import { History, HistoryManager, HistoryStatus } from "../../historyManager";
import { Utils } from "../../utils";
import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem";
import JobTreeItem from "./job";

export default class HistoryTreeItem extends TreeItem implements GithubLocalActionsTreeItem {
static contextValue = 'githubLocalActions.history';
history: History;

constructor(public workspaceFolder: WorkspaceFolder, history: History) {
super(`${history.name} #${history.count}`, TreeItemCollapsibleState.None);
super(`${history.name} #${history.count}`, TreeItemCollapsibleState.Collapsed);
this.history = history;

let endTime: string | undefined;
Expand All @@ -24,20 +25,7 @@ export default class HistoryTreeItem extends TreeItem implements GithubLocalActi

this.description = totalDuration;
this.contextValue = `${HistoryTreeItem.contextValue}_${history.status}`;
switch (history.status) {
case HistoryStatus.Running:
this.iconPath = new ThemeIcon('loading~spin');
break;
case HistoryStatus.Success:
this.iconPath = new ThemeIcon('pass', new ThemeColor('GitHubLocalActions.green'));
break;
case HistoryStatus.Failed:
this.iconPath = new ThemeIcon('error', new ThemeColor('GitHubLocalActions.red'));
break;
case HistoryStatus.Cancelled:
this.iconPath = new ThemeIcon('circle-slash', new ThemeColor('GitHubLocalActions.yellow'));
break;
}
this.iconPath = HistoryManager.statusToIcon(history.status);
this.tooltip = `Name: ${history.name} #${history.count}\n` +
`${history.commandArgs.extraHeader.map(header => `${header.key}: ${header.value}`).join('\n')}\n` +
`Path: ${history.commandArgs.path}\n` +
Expand All @@ -46,14 +34,9 @@ export default class HistoryTreeItem extends TreeItem implements GithubLocalActi
`Started: ${Utils.getDateString(history.date.start)}\n` +
`Ended: ${endTime ? Utils.getDateString(endTime) : 'N/A'}\n` +
`Total Duration: ${totalDuration ? totalDuration : 'N/A'}`;
this.command = {
title: 'Focus Task',
command: 'githubLocalActions.focusTask',
arguments: [this]
};
}

async getChildren(): Promise<GithubLocalActionsTreeItem[]> {
return [];
return this.history.jobs?.map(job => new JobTreeItem(this.workspaceFolder, job)) || [];
}
}
7 changes: 7 additions & 0 deletions src/views/history/historyTreeDataProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,15 @@ export default class HistoryTreeDataProvider implements TreeDataProvider<GithubL
for (const terminal of terminals) {
if (terminal.creationOptions.name === `${historyTreeItem.history.name} #${historyTreeItem.history.count}`) {
terminal.show();
return;
}
}

window.showErrorMessage(`${historyTreeItem.history.name} #${historyTreeItem.history.count} task is no longer open.`, 'View Output').then(async value => {
if (value === 'View Output') {
await commands.executeCommand('githubLocalActions.viewOutput', historyTreeItem);
}
});
}),
commands.registerCommand('githubLocalActions.viewOutput', async (historyTreeItem: HistoryTreeItem) => {
await act.historyManager.viewOutput(historyTreeItem.history);
Expand Down
38 changes: 38 additions & 0 deletions src/views/history/job.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { TreeItem, TreeItemCollapsibleState, WorkspaceFolder } from "vscode";
import { HistoryManager, HistoryStatus, Job } from "../../historyManager";
import { Utils } from "../../utils";
import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem";
import StepTreeItem from "./step";

export default class JobTreeItem extends TreeItem implements GithubLocalActionsTreeItem {
static contextValue = 'githubLocalActions.job';
job: Job;

constructor(public workspaceFolder: WorkspaceFolder, job: Job) {
super(job.name, TreeItemCollapsibleState.Expanded);
this.job = job;

let endTime: string | undefined;
let totalDuration: string | undefined;
if (job.date.end) {
endTime = job.date.end;
totalDuration = Utils.getTimeDuration(job.date.start, endTime);
} else if (job.status === HistoryStatus.Running) {
endTime = new Date().toString();
totalDuration = Utils.getTimeDuration(job.date.start, endTime);
}

this.description = totalDuration;
this.contextValue = `${JobTreeItem.contextValue}_${job.status}`;
this.iconPath = HistoryManager.statusToIcon(job.status);
this.tooltip = `Name: ${job.name}\n` +
`Status: ${job.status}\n` +
`Started: ${Utils.getDateString(job.date.start)}\n` +
`Ended: ${endTime ? Utils.getDateString(endTime) : 'N/A'}\n` +
`Total Duration: ${totalDuration ? totalDuration : 'N/A'}`;
}

async getChildren(): Promise<GithubLocalActionsTreeItem[]> {
return this.job.steps?.map(step => new StepTreeItem(this.workspaceFolder, step)) || [];
}
}
37 changes: 37 additions & 0 deletions src/views/history/step.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { TreeItem, TreeItemCollapsibleState, WorkspaceFolder } from "vscode";
import { HistoryManager, HistoryStatus, Step } from "../../historyManager";
import { Utils } from "../../utils";
import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem";

export default class StepTreeItem extends TreeItem implements GithubLocalActionsTreeItem {
static contextValue = 'githubLocalActions.step';
step: Step;

constructor(public workspaceFolder: WorkspaceFolder, step: Step) {
super(step.name, TreeItemCollapsibleState.None);
this.step = step;

let endTime: string | undefined;
let totalDuration: string | undefined;
if (step.date.end) {
endTime = step.date.end;
totalDuration = Utils.getTimeDuration(step.date.start, endTime);
} else if (step.status === HistoryStatus.Running) {
endTime = new Date().toString();
totalDuration = Utils.getTimeDuration(step.date.start, endTime);
}

this.description = totalDuration;
this.contextValue = `${StepTreeItem.contextValue}_${step.status}`;
this.iconPath = HistoryManager.statusToIcon(step.status);
this.tooltip = `Name: ${step.name}\n` +
`Status: ${step.status}\n` +
`Started: ${Utils.getDateString(step.date.start)}\n` +
`Ended: ${endTime ? Utils.getDateString(endTime) : 'N/A'}\n` +
`Total Duration: ${totalDuration ? totalDuration : 'N/A'}`;
}

async getChildren(): Promise<GithubLocalActionsTreeItem[]> {
return [];
}
}
4 changes: 2 additions & 2 deletions src/views/settings/settingsTreeDataProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,9 +307,9 @@ export default class SettingsTreeDataProvider implements TreeDataProvider<Github
];

options.forEach((option, index) => {
options[index].label = options[index].label.slice(2)
options[index].label = options[index].label.slice(2);
options[index].iconPath = new ThemeIcon('symbol-property');
})
});

const settings = await act.settingsManager.getSettings(optionsTreeItem.workspaceFolder, false);
const optionNames = settings.options.map(option => option.name);
Expand Down