feat: Add Gitea workflow support (.gitea/workflows) - Support for both .github/workflows and .gitea/workflows directories - Fixed workflow execution path resolution - Cleaned up debugging code - Updated to version 1.2.5
Some checks failed
Test Gitea Workflow / test (push) Has been cancelled
Some checks failed
Test Gitea Workflow / test (push) Has been cancelled
This commit is contained in:
21
.gitea/workflows/test-gitea.yml
Normal file
21
.gitea/workflows/test-gitea.yml
Normal file
@@ -0,0 +1,21 @@
|
||||
name: Test Gitea Workflow
|
||||
run-name: Test Gitea Workflow
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Run tests
|
||||
run: echo "Testing Gitea workflow"
|
||||
|
||||
- name: Build
|
||||
run: echo "Building project"
|
||||
2935
src/Extension Host.log
Normal file
2935
src/Extension Host.log
Normal file
File diff suppressed because it is too large
Load Diff
880
src/act.ts
880
src/act.ts
File diff suppressed because it is too large
Load Diff
@@ -1,22 +1,21 @@
|
||||
import { ConfigurationTarget, workspace } from 'vscode';
|
||||
import { Act } from './act';
|
||||
import { WorkflowsManager } from './workflowsManager';
|
||||
import { ConfigurationTarget, workspace } from "vscode";
|
||||
import { Act } from "./act";
|
||||
|
||||
export enum Platform {
|
||||
windows = 'win32',
|
||||
mac = 'darwin',
|
||||
linux = 'linux'
|
||||
windows = "win32",
|
||||
mac = "darwin",
|
||||
linux = "linux",
|
||||
}
|
||||
|
||||
export enum Section {
|
||||
actCommand = 'actCommand',
|
||||
workflowsDirectory = 'workflowsDirectory',
|
||||
dockerDesktopPath = 'dockerDesktopPath'
|
||||
actCommand = "actCommand",
|
||||
dockerDesktopPath = "dockerDesktopPath",
|
||||
}
|
||||
|
||||
export namespace ConfigurationManager {
|
||||
export const group: string = 'githubLocalActions';
|
||||
export const searchPrefix: string = '@ext:sanjulaganepola.github-local-actions';
|
||||
export const group: string = "githubLocalActions";
|
||||
export const searchPrefix: string =
|
||||
"@ext:sanjulaganepola.github-local-actions";
|
||||
|
||||
export async function initialize(): Promise<void> {
|
||||
let actCommand = ConfigurationManager.get<string>(Section.actCommand);
|
||||
@@ -24,25 +23,32 @@ export namespace ConfigurationManager {
|
||||
await ConfigurationManager.set(Section.actCommand, Act.defaultActCommand);
|
||||
}
|
||||
|
||||
let workflowsDirectory = ConfigurationManager.get<string>(Section.workflowsDirectory);
|
||||
if (!workflowsDirectory) {
|
||||
await ConfigurationManager.set(Section.workflowsDirectory, WorkflowsManager.defaultWorkflowsDirectory);
|
||||
}
|
||||
// Don't set a default workflows directory to allow multi-directory support
|
||||
// let workflowsDirectory = ConfigurationManager.get<string>(Section.workflowsDirectory);
|
||||
// if (!workflowsDirectory) {
|
||||
// await ConfigurationManager.set(Section.workflowsDirectory, WorkflowsManager.defaultWorkflowsDirectory);
|
||||
// }
|
||||
|
||||
let dockerDesktopPath = ConfigurationManager.get<string>(Section.dockerDesktopPath);
|
||||
let dockerDesktopPath = ConfigurationManager.get<string>(
|
||||
Section.dockerDesktopPath
|
||||
);
|
||||
if (!dockerDesktopPath) {
|
||||
switch (process.platform) {
|
||||
case Platform.windows:
|
||||
dockerDesktopPath = 'C:/Program Files/Docker/Docker/Docker Desktop.exe';
|
||||
dockerDesktopPath =
|
||||
"C:/Program Files/Docker/Docker/Docker Desktop.exe";
|
||||
break;
|
||||
case Platform.mac:
|
||||
dockerDesktopPath = '/Applications/Docker.app';
|
||||
dockerDesktopPath = "/Applications/Docker.app";
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
await ConfigurationManager.set(Section.dockerDesktopPath, dockerDesktopPath);
|
||||
await ConfigurationManager.set(
|
||||
Section.dockerDesktopPath,
|
||||
dockerDesktopPath
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,10 +57,14 @@ export namespace ConfigurationManager {
|
||||
}
|
||||
|
||||
export function get<T>(section: Section): T | undefined {
|
||||
return workspace.getConfiguration(ConfigurationManager.group).get(section) as T;
|
||||
return workspace
|
||||
.getConfiguration(ConfigurationManager.group)
|
||||
.get(section) as T;
|
||||
}
|
||||
|
||||
export async function set(section: Section, value: any): Promise<void> {
|
||||
return await workspace.getConfiguration(ConfigurationManager.group).update(section, value, ConfigurationTarget.Global);
|
||||
return await workspace
|
||||
.getConfiguration(ConfigurationManager.group)
|
||||
.update(section, value, ConfigurationTarget.Global);
|
||||
}
|
||||
}
|
||||
129
src/extension.ts
129
src/extension.ts
@@ -1,15 +1,23 @@
|
||||
import { commands, env, ExtensionContext, TreeCheckboxChangeEvent, Uri, window, workspace } from 'vscode';
|
||||
import { Act } from './act';
|
||||
import { ConfigurationManager, Section } from './configurationManager';
|
||||
import { IssueHandler } from './issueHandler';
|
||||
import ComponentsTreeDataProvider from './views/components/componentsTreeDataProvider';
|
||||
import { DecorationProvider } from './views/decorationProvider';
|
||||
import { GithubLocalActionsTreeItem } from './views/githubLocalActionsTreeItem';
|
||||
import HistoryTreeDataProvider from './views/history/historyTreeDataProvider';
|
||||
import SettingTreeItem from './views/settings/setting';
|
||||
import SettingsTreeDataProvider from './views/settings/settingsTreeDataProvider';
|
||||
import WorkflowsTreeDataProvider from './views/workflows/workflowsTreeDataProvider';
|
||||
import { WorkflowsManager } from './workflowsManager';
|
||||
import {
|
||||
commands,
|
||||
env,
|
||||
ExtensionContext,
|
||||
TreeCheckboxChangeEvent,
|
||||
Uri,
|
||||
window,
|
||||
workspace,
|
||||
} from "vscode";
|
||||
import { Act } from "./act";
|
||||
import { ConfigurationManager, Section } from "./configurationManager";
|
||||
import { IssueHandler } from "./issueHandler";
|
||||
import ComponentsTreeDataProvider from "./views/components/componentsTreeDataProvider";
|
||||
import { DecorationProvider } from "./views/decorationProvider";
|
||||
import { GithubLocalActionsTreeItem } from "./views/githubLocalActionsTreeItem";
|
||||
import HistoryTreeDataProvider from "./views/history/historyTreeDataProvider";
|
||||
import SettingTreeItem from "./views/settings/setting";
|
||||
import SettingsTreeDataProvider from "./views/settings/settingsTreeDataProvider";
|
||||
import WorkflowsTreeDataProvider from "./views/workflows/workflowsTreeDataProvider";
|
||||
import { WorkflowsManager } from "./workflowsManager";
|
||||
|
||||
export let act: Act;
|
||||
export let componentsTreeDataProvider: ComponentsTreeDataProvider;
|
||||
@@ -18,47 +26,63 @@ export let historyTreeDataProvider: HistoryTreeDataProvider;
|
||||
export let settingsTreeDataProvider: SettingsTreeDataProvider;
|
||||
|
||||
export function activate(context: ExtensionContext) {
|
||||
console.log('Congratulations, your extension "github-local-actions" is now active!');
|
||||
console.log(
|
||||
'Congratulations, your extension "github-local-actions" is now active!'
|
||||
);
|
||||
|
||||
act = new Act(context);
|
||||
|
||||
// Create tree views
|
||||
const decorationProvider = new DecorationProvider();
|
||||
componentsTreeDataProvider = new ComponentsTreeDataProvider(context);
|
||||
const componentsTreeView = window.createTreeView(ComponentsTreeDataProvider.VIEW_ID, { treeDataProvider: componentsTreeDataProvider, showCollapseAll: true });
|
||||
const componentsTreeView = window.createTreeView(
|
||||
ComponentsTreeDataProvider.VIEW_ID,
|
||||
{ treeDataProvider: componentsTreeDataProvider, showCollapseAll: true }
|
||||
);
|
||||
|
||||
workflowsTreeDataProvider = new WorkflowsTreeDataProvider(context);
|
||||
const workflowsTreeView = window.createTreeView(WorkflowsTreeDataProvider.VIEW_ID, { treeDataProvider: workflowsTreeDataProvider, showCollapseAll: true });
|
||||
const workflowsTreeView = window.createTreeView(
|
||||
WorkflowsTreeDataProvider.VIEW_ID,
|
||||
{ treeDataProvider: workflowsTreeDataProvider, showCollapseAll: true }
|
||||
);
|
||||
|
||||
historyTreeDataProvider = new HistoryTreeDataProvider(context);
|
||||
const historyTreeView = window.createTreeView(HistoryTreeDataProvider.VIEW_ID, { treeDataProvider: historyTreeDataProvider, showCollapseAll: true });
|
||||
const historyTreeView = window.createTreeView(
|
||||
HistoryTreeDataProvider.VIEW_ID,
|
||||
{ treeDataProvider: historyTreeDataProvider, showCollapseAll: true }
|
||||
);
|
||||
settingsTreeDataProvider = new SettingsTreeDataProvider(context);
|
||||
const settingsTreeView = window.createTreeView(SettingsTreeDataProvider.VIEW_ID, { treeDataProvider: settingsTreeDataProvider, showCollapseAll: true });
|
||||
settingsTreeView.onDidChangeCheckboxState(async (event: TreeCheckboxChangeEvent<GithubLocalActionsTreeItem>) => {
|
||||
await settingsTreeDataProvider.onDidChangeCheckboxState(event as TreeCheckboxChangeEvent<SettingTreeItem>);
|
||||
});
|
||||
const settingsTreeView = window.createTreeView(
|
||||
SettingsTreeDataProvider.VIEW_ID,
|
||||
{ treeDataProvider: settingsTreeDataProvider, showCollapseAll: true }
|
||||
);
|
||||
settingsTreeView.onDidChangeCheckboxState(
|
||||
async (event: TreeCheckboxChangeEvent<GithubLocalActionsTreeItem>) => {
|
||||
await settingsTreeDataProvider.onDidChangeCheckboxState(
|
||||
event as TreeCheckboxChangeEvent<SettingTreeItem>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
// Create file watcher
|
||||
let workflowsFileWatcher = setupFileWatcher(context);
|
||||
|
||||
// Initialize configurations
|
||||
ConfigurationManager.initialize();
|
||||
workspace.onDidChangeConfiguration(async event => {
|
||||
workspace.onDidChangeConfiguration(async (event) => {
|
||||
if (event.affectsConfiguration(ConfigurationManager.group)) {
|
||||
await ConfigurationManager.initialize();
|
||||
|
||||
if (event.affectsConfiguration(`${ConfigurationManager.group}.${Section.actCommand}`) ||
|
||||
event.affectsConfiguration(`${ConfigurationManager.group}.${Section.dockerDesktopPath}`)) {
|
||||
if (
|
||||
event.affectsConfiguration(
|
||||
`${ConfigurationManager.group}.${Section.actCommand}`
|
||||
) ||
|
||||
event.affectsConfiguration(
|
||||
`${ConfigurationManager.group}.${Section.dockerDesktopPath}`
|
||||
)
|
||||
) {
|
||||
componentsTreeDataProvider.refresh();
|
||||
}
|
||||
|
||||
if (event.affectsConfiguration(`${ConfigurationManager.group}.${Section.workflowsDirectory}`)) {
|
||||
workflowsTreeDataProvider.refresh();
|
||||
settingsTreeDataProvider.refresh();
|
||||
|
||||
if (workflowsFileWatcher) {
|
||||
workflowsFileWatcher.dispose();
|
||||
workflowsFileWatcher = setupFileWatcher(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -69,18 +93,31 @@ export function activate(context: ExtensionContext) {
|
||||
settingsTreeView,
|
||||
window.registerFileDecorationProvider(decorationProvider),
|
||||
workflowsFileWatcher,
|
||||
commands.registerCommand('githubLocalActions.viewDocumentation', async () => {
|
||||
await env.openExternal(Uri.parse('https://sanjulaganepola.github.io/github-local-actions-docs'));
|
||||
}),
|
||||
commands.registerCommand('githubLocalActions.reportAnIssue', async () => {
|
||||
commands.registerCommand(
|
||||
"githubLocalActions.viewDocumentation",
|
||||
async () => {
|
||||
await env.openExternal(
|
||||
Uri.parse(
|
||||
"https://sanjulaganepola.github.io/github-local-actions-docs"
|
||||
)
|
||||
);
|
||||
}
|
||||
),
|
||||
commands.registerCommand("githubLocalActions.reportAnIssue", async () => {
|
||||
await IssueHandler.openBugReport(context);
|
||||
}),
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function setupFileWatcher(context: ExtensionContext) {
|
||||
const workflowsDirectory = WorkflowsManager.getWorkflowsDirectory();
|
||||
const workflowsFileWatcher = workspace.createFileSystemWatcher(`**/${workflowsDirectory}/*.{${WorkflowsManager.ymlExtension},${WorkflowsManager.yamlExtension}}`);
|
||||
const workflowsDirectories = WorkflowsManager.getWorkflowsDirectories();
|
||||
const fileWatchers: any[] = [];
|
||||
|
||||
for (const workflowsDirectory of workflowsDirectories) {
|
||||
const workflowsFileWatcher = workspace.createFileSystemWatcher(
|
||||
`**/${workflowsDirectory}/*.{${WorkflowsManager.ymlExtension},${WorkflowsManager.yamlExtension}}`
|
||||
);
|
||||
|
||||
workflowsFileWatcher.onDidCreate(() => {
|
||||
workflowsTreeDataProvider.refresh();
|
||||
settingsTreeDataProvider.refresh();
|
||||
@@ -94,7 +131,15 @@ function setupFileWatcher(context: ExtensionContext) {
|
||||
settingsTreeDataProvider.refresh();
|
||||
});
|
||||
|
||||
return workflowsFileWatcher;
|
||||
fileWatchers.push(workflowsFileWatcher);
|
||||
}
|
||||
|
||||
// Return a disposable that disposes all watchers
|
||||
return {
|
||||
dispose: () => {
|
||||
fileWatchers.forEach((watcher) => watcher.dispose());
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function deactivate() { }
|
||||
export function deactivate() {}
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
import * as path from "path";
|
||||
import { CancellationToken, commands, EventEmitter, ExtensionContext, TreeDataProvider, TreeItem, window, workspace } from "vscode";
|
||||
import {
|
||||
CancellationToken,
|
||||
commands,
|
||||
EventEmitter,
|
||||
ExtensionContext,
|
||||
TreeDataProvider,
|
||||
TreeItem,
|
||||
window,
|
||||
workspace,
|
||||
} from "vscode";
|
||||
import { Event } from "../../act";
|
||||
import { act } from "../../extension";
|
||||
import { Utils } from "../../utils";
|
||||
@@ -9,51 +18,88 @@ import JobTreeItem from "./job";
|
||||
import WorkflowTreeItem from "./workflow";
|
||||
import WorkspaceFolderWorkflowsTreeItem from "./workspaceFolderWorkflows";
|
||||
|
||||
export default class WorkflowsTreeDataProvider implements TreeDataProvider<GithubLocalActionsTreeItem> {
|
||||
private _onDidChangeTreeData = new EventEmitter<GithubLocalActionsTreeItem | undefined | null | void>();
|
||||
export default class WorkflowsTreeDataProvider
|
||||
implements TreeDataProvider<GithubLocalActionsTreeItem>
|
||||
{
|
||||
private _onDidChangeTreeData = new EventEmitter<
|
||||
GithubLocalActionsTreeItem | undefined | null | void
|
||||
>();
|
||||
readonly onDidChangeTreeData = this._onDidChangeTreeData.event;
|
||||
static VIEW_ID = 'workflows';
|
||||
static VIEW_ID = "workflows";
|
||||
|
||||
constructor(context: ExtensionContext) {
|
||||
context.subscriptions.push(
|
||||
commands.registerCommand('githubLocalActions.runAllWorkflows', async (workspaceFolderWorkflowsTreeItem?: WorkspaceFolderWorkflowsTreeItem) => {
|
||||
const workspaceFolder = await Utils.getWorkspaceFolder(workspaceFolderWorkflowsTreeItem?.workspaceFolder);
|
||||
commands.registerCommand(
|
||||
"githubLocalActions.runAllWorkflows",
|
||||
async (
|
||||
workspaceFolderWorkflowsTreeItem?: WorkspaceFolderWorkflowsTreeItem
|
||||
) => {
|
||||
const workspaceFolder = await Utils.getWorkspaceFolder(
|
||||
workspaceFolderWorkflowsTreeItem?.workspaceFolder
|
||||
);
|
||||
if (workspaceFolder) {
|
||||
await act.runAllWorkflows(workspaceFolder);
|
||||
}
|
||||
}),
|
||||
commands.registerCommand('githubLocalActions.runEvent', async (workspaceFolderWorkflowsTreeItem?: WorkspaceFolderWorkflowsTreeItem) => {
|
||||
const workspaceFolder = await Utils.getWorkspaceFolder(workspaceFolderWorkflowsTreeItem?.workspaceFolder);
|
||||
}
|
||||
),
|
||||
commands.registerCommand(
|
||||
"githubLocalActions.runEvent",
|
||||
async (
|
||||
workspaceFolderWorkflowsTreeItem?: WorkspaceFolderWorkflowsTreeItem
|
||||
) => {
|
||||
const workspaceFolder = await Utils.getWorkspaceFolder(
|
||||
workspaceFolderWorkflowsTreeItem?.workspaceFolder
|
||||
);
|
||||
if (workspaceFolder) {
|
||||
const event = await window.showQuickPick(Object.values(Event), {
|
||||
title: 'Select the event to run',
|
||||
placeHolder: 'Event'
|
||||
title: "Select the event to run",
|
||||
placeHolder: "Event",
|
||||
});
|
||||
|
||||
if (event) {
|
||||
await act.runEvent(workspaceFolder, event as Event);
|
||||
}
|
||||
}
|
||||
}),
|
||||
commands.registerCommand('githubLocalActions.refreshWorkflows', async () => {
|
||||
}
|
||||
),
|
||||
commands.registerCommand(
|
||||
"githubLocalActions.refreshWorkflows",
|
||||
async () => {
|
||||
this.refresh();
|
||||
}),
|
||||
commands.registerCommand('githubLocalActions.openWorkflow', async (workflowTreeItem: WorkflowTreeItem) => {
|
||||
}
|
||||
),
|
||||
commands.registerCommand(
|
||||
"githubLocalActions.openWorkflow",
|
||||
async (workflowTreeItem: WorkflowTreeItem) => {
|
||||
try {
|
||||
const document = await workspace.openTextDocument(workflowTreeItem.workflow.uri);
|
||||
const document = await workspace.openTextDocument(
|
||||
workflowTreeItem.workflow.uri
|
||||
);
|
||||
await window.showTextDocument(document);
|
||||
} catch (error: any) {
|
||||
try {
|
||||
await workspace.fs.stat(workflowTreeItem.workflow.uri);
|
||||
window.showErrorMessage(`Failed to open workflow. Error: ${error}`);
|
||||
window.showErrorMessage(
|
||||
`Failed to open workflow. Error: ${error}`
|
||||
);
|
||||
} catch (error: any) {
|
||||
window.showErrorMessage(`Workflow ${path.parse(workflowTreeItem.workflow.uri.fsPath).base} not found.`);
|
||||
window.showErrorMessage(
|
||||
`Workflow ${
|
||||
path.parse(workflowTreeItem.workflow.uri.fsPath).base
|
||||
} not found.`
|
||||
);
|
||||
}
|
||||
}
|
||||
}),
|
||||
commands.registerCommand('githubLocalActions.runWorkflow', async (workflowTreeItem: WorkflowTreeItem) => {
|
||||
}
|
||||
),
|
||||
commands.registerCommand(
|
||||
"githubLocalActions.runWorkflow",
|
||||
async (workflowTreeItem: WorkflowTreeItem) => {
|
||||
if (workflowTreeItem) {
|
||||
await act.runWorkflow(workflowTreeItem.workspaceFolder, workflowTreeItem.workflow);
|
||||
await act.runWorkflow(
|
||||
workflowTreeItem.workspaceFolder,
|
||||
workflowTreeItem.workflow
|
||||
);
|
||||
} else {
|
||||
let errorMessage: string | undefined;
|
||||
|
||||
@@ -61,12 +107,21 @@ export default class WorkflowsTreeDataProvider implements TreeDataProvider<Githu
|
||||
if (activeTextEditor) {
|
||||
const uri = activeTextEditor.document.uri;
|
||||
const fileName = path.parse(uri.fsPath).base;
|
||||
const workflowsDirectory = WorkflowsManager.getWorkflowsDirectory();
|
||||
if (uri.path.match(`.*/${workflowsDirectory}/.*\\.(${WorkflowsManager.yamlExtension}|${WorkflowsManager.ymlExtension})`)) {
|
||||
const workflowsDirectory =
|
||||
WorkflowsManager.getWorkflowsDirectory();
|
||||
if (
|
||||
uri.path.match(
|
||||
`.*/${workflowsDirectory}/.*\\.(${WorkflowsManager.yamlExtension}|${WorkflowsManager.ymlExtension})`
|
||||
)
|
||||
) {
|
||||
const workspaceFolder = workspace.getWorkspaceFolder(uri);
|
||||
if (workspaceFolder) {
|
||||
const workflows = await act.workflowsManager.getWorkflows(workspaceFolder);
|
||||
const workflow = workflows.find(workflow => workflow.uri.fsPath === uri.fsPath);
|
||||
const workflows = await act.workflowsManager.getWorkflows(
|
||||
workspaceFolder
|
||||
);
|
||||
const workflow = workflows.find(
|
||||
(workflow) => workflow.uri.fsPath === uri.fsPath
|
||||
);
|
||||
if (workflow) {
|
||||
await act.runWorkflow(workspaceFolder, workflow);
|
||||
} else {
|
||||
@@ -79,57 +134,91 @@ export default class WorkflowsTreeDataProvider implements TreeDataProvider<Githu
|
||||
errorMessage = `${fileName} is not a workflow that can be executed locally.`;
|
||||
}
|
||||
} else {
|
||||
errorMessage = 'No workflow opened to execute locally.';
|
||||
errorMessage = "No workflow opened to execute locally.";
|
||||
}
|
||||
|
||||
if (errorMessage) {
|
||||
window.showErrorMessage(errorMessage, 'View Workflows').then(async value => {
|
||||
if (value === 'View Workflows') {
|
||||
await commands.executeCommand('workflows.focus');
|
||||
window
|
||||
.showErrorMessage(errorMessage, "View Workflows")
|
||||
.then(async (value) => {
|
||||
if (value === "View Workflows") {
|
||||
await commands.executeCommand("workflows.focus");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}),
|
||||
commands.registerCommand('githubLocalActions.runJob', async (jobTreeItem: JobTreeItem) => {
|
||||
await act.runJob(jobTreeItem.workspaceFolder, jobTreeItem.workflow, jobTreeItem.job);
|
||||
}),
|
||||
commands.registerCommand('githubLocalActions.runWorkflowEvent', async (workflowTreeItem: WorkflowTreeItem) => {
|
||||
}
|
||||
),
|
||||
commands.registerCommand(
|
||||
"githubLocalActions.runJob",
|
||||
async (jobTreeItem: JobTreeItem) => {
|
||||
await act.runJob(
|
||||
jobTreeItem.workspaceFolder,
|
||||
jobTreeItem.workflow,
|
||||
jobTreeItem.job
|
||||
);
|
||||
}
|
||||
),
|
||||
commands.registerCommand(
|
||||
"githubLocalActions.runWorkflowEvent",
|
||||
async (workflowTreeItem: WorkflowTreeItem) => {
|
||||
// Filter to only events that are registered on the workflow
|
||||
const registeredEventsOnWorkflow = Object.keys(workflowTreeItem.workflow.yaml.on);
|
||||
const registeredEventsOnWorkflow = Object.keys(
|
||||
workflowTreeItem.workflow.yaml.on
|
||||
);
|
||||
|
||||
if (registeredEventsOnWorkflow.length === 0) {
|
||||
window.showErrorMessage(`No events registered on the workflow (${workflowTreeItem.workflow.name}). Add an event to the \`on\` section of the workflow to trigger it.`);
|
||||
window.showErrorMessage(
|
||||
`No events registered on the workflow (${workflowTreeItem.workflow.name}). Add an event to the \`on\` section of the workflow to trigger it.`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const event = await window.showQuickPick(registeredEventsOnWorkflow, {
|
||||
title: 'Select the event to run',
|
||||
placeHolder: 'Event',
|
||||
title: "Select the event to run",
|
||||
placeHolder: "Event",
|
||||
});
|
||||
|
||||
if (event) {
|
||||
await act.runEvent(workflowTreeItem.workspaceFolder, event as Event, { workflow: workflowTreeItem.workflow });
|
||||
await act.runEvent(
|
||||
workflowTreeItem.workspaceFolder,
|
||||
event as Event,
|
||||
{ workflow: workflowTreeItem.workflow }
|
||||
);
|
||||
}
|
||||
}),
|
||||
commands.registerCommand('githubLocalActions.runJobEvent', async (jobTreeItem: JobTreeItem) => {
|
||||
}
|
||||
),
|
||||
commands.registerCommand(
|
||||
"githubLocalActions.runJobEvent",
|
||||
async (jobTreeItem: JobTreeItem) => {
|
||||
// Filter to only events that are registered on the job's parent workflow
|
||||
const registeredEventsOnJobParentWorkflow = Object.keys(jobTreeItem.workflow.yaml.on);
|
||||
const registeredEventsOnJobParentWorkflow = Object.keys(
|
||||
jobTreeItem.workflow.yaml.on
|
||||
);
|
||||
|
||||
if (registeredEventsOnJobParentWorkflow.length === 0) {
|
||||
window.showErrorMessage(`No events registered on the workflow (${jobTreeItem.workflow.name}). Add an event to the \`on\` section of the workflow to trigger it.`);
|
||||
window.showErrorMessage(
|
||||
`No events registered on the workflow (${jobTreeItem.workflow.name}). Add an event to the \`on\` section of the workflow to trigger it.`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const event = await window.showQuickPick(registeredEventsOnJobParentWorkflow, {
|
||||
title: 'Select the event to run',
|
||||
placeHolder: 'Event'
|
||||
});
|
||||
const event = await window.showQuickPick(
|
||||
registeredEventsOnJobParentWorkflow,
|
||||
{
|
||||
title: "Select the event to run",
|
||||
placeHolder: "Event",
|
||||
}
|
||||
);
|
||||
|
||||
if (event) {
|
||||
await act.runEvent(jobTreeItem.workspaceFolder, event as Event, { workflow: jobTreeItem.workflow, job: jobTreeItem.job });
|
||||
await act.runEvent(jobTreeItem.workspaceFolder, event as Event, {
|
||||
workflow: jobTreeItem.workflow,
|
||||
job: jobTreeItem.job,
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -137,11 +226,17 @@ export default class WorkflowsTreeDataProvider implements TreeDataProvider<Githu
|
||||
this._onDidChangeTreeData.fire(element);
|
||||
}
|
||||
|
||||
getTreeItem(element: GithubLocalActionsTreeItem): GithubLocalActionsTreeItem | Thenable<GithubLocalActionsTreeItem> {
|
||||
getTreeItem(
|
||||
element: GithubLocalActionsTreeItem
|
||||
): GithubLocalActionsTreeItem | Thenable<GithubLocalActionsTreeItem> {
|
||||
return element;
|
||||
}
|
||||
|
||||
async resolveTreeItem(item: TreeItem, element: GithubLocalActionsTreeItem, token: CancellationToken): Promise<GithubLocalActionsTreeItem> {
|
||||
async resolveTreeItem(
|
||||
item: TreeItem,
|
||||
element: GithubLocalActionsTreeItem,
|
||||
token: CancellationToken
|
||||
): Promise<GithubLocalActionsTreeItem> {
|
||||
if (element.getToolTip) {
|
||||
element.tooltip = await element.getToolTip();
|
||||
}
|
||||
@@ -149,7 +244,9 @@ export default class WorkflowsTreeDataProvider implements TreeDataProvider<Githu
|
||||
return element;
|
||||
}
|
||||
|
||||
async getChildren(element?: GithubLocalActionsTreeItem): Promise<GithubLocalActionsTreeItem[]> {
|
||||
async getChildren(
|
||||
element?: GithubLocalActionsTreeItem
|
||||
): Promise<GithubLocalActionsTreeItem[]> {
|
||||
if (element) {
|
||||
return element.getChildren();
|
||||
} else {
|
||||
@@ -159,9 +256,15 @@ export default class WorkflowsTreeDataProvider implements TreeDataProvider<Githu
|
||||
const workspaceFolders = workspace.workspaceFolders;
|
||||
if (workspaceFolders) {
|
||||
if (workspaceFolders.length === 1) {
|
||||
items.push(...await new WorkspaceFolderWorkflowsTreeItem(workspaceFolders[0]).getChildren());
|
||||
items.push(
|
||||
...(await new WorkspaceFolderWorkflowsTreeItem(
|
||||
workspaceFolders[0]
|
||||
).getChildren())
|
||||
);
|
||||
|
||||
const workflows = await act.workflowsManager.getWorkflows(workspaceFolders[0]);
|
||||
const workflows = await act.workflowsManager.getWorkflows(
|
||||
workspaceFolders[0]
|
||||
);
|
||||
if (workflows && workflows.length > 0) {
|
||||
noWorkflows = false;
|
||||
}
|
||||
@@ -169,7 +272,9 @@ export default class WorkflowsTreeDataProvider implements TreeDataProvider<Githu
|
||||
for (const workspaceFolder of workspaceFolders) {
|
||||
items.push(new WorkspaceFolderWorkflowsTreeItem(workspaceFolder));
|
||||
|
||||
const workflows = await act.workflowsManager.getWorkflows(workspaceFolder);
|
||||
const workflows = await act.workflowsManager.getWorkflows(
|
||||
workspaceFolder
|
||||
);
|
||||
if (workflows && workflows.length > 0) {
|
||||
noWorkflows = false;
|
||||
}
|
||||
@@ -177,7 +282,11 @@ export default class WorkflowsTreeDataProvider implements TreeDataProvider<Githu
|
||||
}
|
||||
}
|
||||
|
||||
await commands.executeCommand('setContext', 'githubLocalActions:noWorkflows', noWorkflows);
|
||||
await commands.executeCommand(
|
||||
"setContext",
|
||||
"githubLocalActions:noWorkflows",
|
||||
noWorkflows
|
||||
);
|
||||
return items;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,56 +2,83 @@ import * as fs from "fs/promises";
|
||||
import * as path from "path";
|
||||
import { RelativePattern, Uri, workspace, WorkspaceFolder } from "vscode";
|
||||
import * as yaml from "yaml";
|
||||
import { ConfigurationManager, Section } from "./configurationManager";
|
||||
|
||||
export interface Workflow {
|
||||
name: string,
|
||||
uri: Uri,
|
||||
fileContent?: string,
|
||||
yaml?: any,
|
||||
error?: string
|
||||
name: string;
|
||||
uri: Uri;
|
||||
fileContent?: string;
|
||||
yaml?: any;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export interface Job {
|
||||
name: string
|
||||
id: string
|
||||
name: string;
|
||||
id: string;
|
||||
}
|
||||
|
||||
export class WorkflowsManager {
|
||||
static defaultWorkflowsDirectory: string = '.github/workflows';
|
||||
static yamlExtension: string = 'yaml';
|
||||
static ymlExtension: string = 'yml';
|
||||
static defaultWorkflowsDirectory: string = ".github/workflows";
|
||||
static giteaWorkflowsDirectory: string = ".gitea/workflows";
|
||||
static yamlExtension: string = "yaml";
|
||||
static ymlExtension: string = "yml";
|
||||
|
||||
static getWorkflowsDirectories(): string[] {
|
||||
const directories = [
|
||||
WorkflowsManager.defaultWorkflowsDirectory,
|
||||
WorkflowsManager.giteaWorkflowsDirectory,
|
||||
];
|
||||
return directories;
|
||||
}
|
||||
|
||||
static getWorkflowsDirectory(): string {
|
||||
return ConfigurationManager.get<string>(Section.workflowsDirectory) || WorkflowsManager.defaultWorkflowsDirectory;
|
||||
return WorkflowsManager.defaultWorkflowsDirectory;
|
||||
}
|
||||
|
||||
async getWorkflows(workspaceFolder: WorkspaceFolder): Promise<Workflow[]> {
|
||||
const workflows: Workflow[] = [];
|
||||
|
||||
const workflowsDirectory = WorkflowsManager.getWorkflowsDirectory();
|
||||
const workflowFileUris = await workspace.findFiles(new RelativePattern(workspaceFolder, `${workflowsDirectory}/*.{${WorkflowsManager.yamlExtension},${WorkflowsManager.ymlExtension}}`));
|
||||
const workflowsDirectories = WorkflowsManager.getWorkflowsDirectories();
|
||||
|
||||
for (const workflowsDirectory of workflowsDirectories) {
|
||||
try {
|
||||
const workflowFileUris = await workspace.findFiles(
|
||||
new RelativePattern(
|
||||
workspaceFolder,
|
||||
`${workflowsDirectory}/*.{${WorkflowsManager.yamlExtension},${WorkflowsManager.ymlExtension}}`
|
||||
)
|
||||
);
|
||||
|
||||
for await (const workflowFileUri of workflowFileUris) {
|
||||
let yamlContent: any | undefined;
|
||||
|
||||
try {
|
||||
const fileContent = await fs.readFile(workflowFileUri.fsPath, 'utf8');
|
||||
const fileContent = await fs.readFile(
|
||||
workflowFileUri.fsPath,
|
||||
"utf8"
|
||||
);
|
||||
yamlContent = yaml.parse(fileContent);
|
||||
|
||||
workflows.push({
|
||||
name: yamlContent.name || path.parse(workflowFileUri.fsPath).name,
|
||||
uri: workflowFileUri,
|
||||
fileContent: fileContent,
|
||||
yaml: yaml.parse(fileContent)
|
||||
yaml: yaml.parse(fileContent),
|
||||
});
|
||||
} catch (error: any) {
|
||||
workflows.push({
|
||||
name: (yamlContent ? yamlContent.name : undefined) || path.parse(workflowFileUri.fsPath).name,
|
||||
name:
|
||||
(yamlContent ? yamlContent.name : undefined) ||
|
||||
path.parse(workflowFileUri.fsPath).name,
|
||||
uri: workflowFileUri,
|
||||
error: 'Failed to parse workflow'
|
||||
error: "Failed to parse workflow",
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
// Directory doesn't exist, skip it
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return workflows;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user