extract act options from cli command (#117)

* extract act options from cli command

* remove special options handled by the tree view

* Refactor logic to get act options (#1)

* Refactor get options logic
* Remove bool type options from having descriptions
* Force option description to be uppercase

Signed-off-by: Sanjula Ganepola <sanjulagane@gmail.com>

* disable generic early exit options as well

* filter out stringArray default value

* this removes default values like `[]` regardless if they are sent

* fix quote consitency

---------

Signed-off-by: Sanjula Ganepola <sanjulagane@gmail.com>
Co-authored-by: Sanjula Ganepola <32170854+SanjulaGanepola@users.noreply.github.com>
This commit is contained in:
ChristopherHX
2025-01-18 23:43:31 +01:00
committed by GitHub
parent ed60ff43c6
commit dc301e47e0
2 changed files with 242 additions and 188 deletions

View File

@@ -120,6 +120,13 @@ export interface CommandArgs {
extraHeader: { key: string, value: string }[] extraHeader: { key: string, value: string }[]
} }
export interface ActOption {
default: string;
name: string,
description: string
type: string
}
export class Act { export class Act {
static defaultActCommand: string = 'act'; static defaultActCommand: string = 'act';
static githubCliActCommand: string = 'gh act'; static githubCliActCommand: string = 'gh act';
@@ -323,6 +330,26 @@ export class Act {
} }
} }
getAllOptions(): Promise<ActOption[]> {
return new Promise<ActOption[]>((resolve, reject) => {
const exec = childProcess.spawn(
`${Act.getActCommand()} --list-options`,
{
shell: true,
}
);
let options: string = ""
exec.stdout.on('data', b => options += b.toString());
exec.on('exit', async (code, signal) => {
if (code === 0) {
resolve(JSON.parse(options));
} else {
reject(new Error("Not supported by this binary"));
}
});
})
}
async runCommand(commandArgs: CommandArgs) { async runCommand(commandArgs: CommandArgs) {
// Check if required components are ready // Check if required components are ready
// const unreadyComponents = await this.componentsManager.getUnreadyComponents(); // const unreadyComponents = await this.componentsManager.getUnreadyComponents();

View File

@@ -117,194 +117,221 @@ export default class SettingsTreeDataProvider implements TreeDataProvider<Github
} }
}), }),
commands.registerCommand('githubLocalActions.addOption', async (optionsTreeItem: OptionsTreeItem) => { commands.registerCommand('githubLocalActions.addOption', async (optionsTreeItem: OptionsTreeItem) => {
let options: any[] = [ let options: any[];
{
label: Option.ActionCachePath, try {
description: this.getCacheDirectory(['act']), const allOptions = await act.getAllOptions();
detail: 'Defines the path where the actions get cached and host workspaces are created.' const specialOptions: string[] = [
}, Option.Input,
{ Option.InputFile,
label: Option.ActionOfflineMode, Option.Var,
detail: 'If action contents exists, it will not be fetched and pulled again. If this is turned on, it will turn off force pull.' Option.VarFile,
}, Option.Secret,
{ Option.SecretFile,
label: Option.Actor, Option.EventPath,
description: 'nektos/act', Option.Platform,
detail: 'User that triggered the event.' // The following options would break this integration
}, Option.Help,
{ Option.BugReport,
label: Option.ArtifactServerAddr, Option.Watch,
description: '', Option.List,
detail: 'Defines the address to which the artifact server binds. If not set, nektos/act will use the outbound IP address of this machine. This means that it will try to access the internet and return the local IP address of the connection. If the machine cannot access the internet, it returns a preferred IP address from network interfaces. If no IP address is found, this will not be set.' Option.Version
}, ];
{ options = allOptions.map(opt => ({
label: Option.ArtifactServerPath, label: "--" + opt.name,
description: '', description: opt.type !== 'bool' ? opt.type === 'stringArray' ? '' : opt.default : undefined,
detail: 'Defines the path where the artifact server stores uploads and retrieves downloads from. If not specified, the artifact server will not start.' detail: opt.description.charAt(0).toUpperCase() + opt.description.slice(1)
}, })).filter(opt => !specialOptions.includes(opt.label));
{ } catch (error: any) {
label: Option.ArtifactServerPort, options = [
description: '34567', {
detail: 'Defines the port where the artifact server listens.' label: Option.ActionCachePath,
}, description: this.getCacheDirectory(['act']),
{ detail: 'Defines the path where the actions get cached and host workspaces are created.'
label: Option.Bind, },
detail: 'Bind working directory to container, rather than copy.' {
}, label: Option.ActionOfflineMode,
{ detail: 'If action contents exists, it will not be fetched and pulled again. If this is turned on, it will turn off force pull.'
label: Option.CacheServerAddr, },
description: '', {
detail: 'Defines the address to which the cache server binds. If not set, nektos/act will use the outbound IP address of this machine. This means that it will try to access the internet and return the local IP address of the connection. If the machine cannot access the internet, it returns a preferred IP address from network interfaces. If no IP address is found, this will not be set.' label: Option.Actor,
}, description: 'nektos/act',
{ detail: 'User that triggered the event.'
label: Option.CacheServerPath, },
description: this.getCacheDirectory(['actcache']), {
detail: 'Defines the path where the cache server stores caches.' label: Option.ArtifactServerAddr,
}, description: '',
{ detail: 'Defines the address to which the artifact server binds. If not set, nektos/act will use the outbound IP address of this machine. This means that it will try to access the internet and return the local IP address of the connection. If the machine cannot access the internet, it returns a preferred IP address from network interfaces. If no IP address is found, this will not be set.'
label: Option.CacheServerPort, },
description: '0', {
detail: 'Defines the port where the artifact server listens. 0 means a randomly available port.' label: Option.ArtifactServerPath,
}, description: '',
{ detail: 'Defines the path where the artifact server stores uploads and retrieves downloads from. If not specified, the artifact server will not start.'
label: Option.ContainerArchitecture, },
description: '', {
detail: 'The architecture which should be used to run containers (e.g.: linux/amd64). If not specified, the host default architecture will be used. This requires Docker server API Version 1.41+ (ignored on earlier Docker server platforms).' label: Option.ArtifactServerPort,
}, description: '34567',
{ detail: 'Defines the port where the artifact server listens.'
label: Option.ContainerCapAdd, },
description: '', {
detail: 'Kernel capabilities to add to the workflow containers (e.g. SYS_PTRACE).' label: Option.Bind,
}, detail: 'Bind working directory to container, rather than copy.'
{ },
label: Option.ContainerCapDrop, {
description: '', label: Option.CacheServerAddr,
detail: 'Kernel capabilities to remove from the workflow containers (e.g. SYS_PTRACE).' description: '',
}, detail: 'Defines the address to which the cache server binds. If not set, nektos/act will use the outbound IP address of this machine. This means that it will try to access the internet and return the local IP address of the connection. If the machine cannot access the internet, it returns a preferred IP address from network interfaces. If no IP address is found, this will not be set.'
{ },
label: Option.ContainerDaemonSocket, {
description: '', label: Option.CacheServerPath,
detail: 'URI to Docker Engine socket (e.g.: unix://~/.docker/run/docker.sock or - to disable bind mounting the socket).' description: this.getCacheDirectory(['actcache']),
}, detail: 'Defines the path where the cache server stores caches.'
{ },
label: Option.ContainerOptions, {
description: '', label: Option.CacheServerPort,
detail: 'Custom docker container options for the job container without an options property in the job definition.' description: '0',
}, detail: 'Defines the port where the artifact server listens. 0 means a randomly available port.'
{ },
label: Option.DefaultBranch, {
description: '', label: Option.ContainerArchitecture,
detail: 'The name of the main branch.' description: '',
}, detail: 'The architecture which should be used to run containers (e.g.: linux/amd64). If not specified, the host default architecture will be used. This requires Docker server API Version 1.41+ (ignored on earlier Docker server platforms).'
{ },
label: Option.DetectEvent, {
detail: 'Use first event type from workflow as event that triggered the workflow.' label: Option.ContainerCapAdd,
}, description: '',
{ detail: 'Kernel capabilities to add to the workflow containers (e.g. SYS_PTRACE).'
label: Option.Directory, },
description: '.', {
detail: 'The working directory used when running a nektos/act command.' label: Option.ContainerCapDrop,
}, description: '',
{ detail: 'Kernel capabilities to remove from the workflow containers (e.g. SYS_PTRACE).'
label: Option.DryRun, },
detail: 'Disable container creation and validate only workflow correctness.' {
}, label: Option.ContainerDaemonSocket,
{ description: '',
label: Option.GithubInstance, detail: 'URI to Docker Engine socket (e.g.: unix://~/.docker/run/docker.sock or - to disable bind mounting the socket).'
description: 'github.com', },
detail: 'The GitHub instance to use. Only use this when using GitHub Enterprise Server.' {
}, label: Option.ContainerOptions,
{ description: '',
label: Option.InsecureSecrets, detail: 'Custom docker container options for the job container without an options property in the job definition.'
detail: 'Show secrets while printing logs (NOT RECOMMENDED!).' },
}, {
{ label: Option.DefaultBranch,
label: Option.Json, description: '',
detail: 'Output logs in json format.' detail: 'The name of the main branch.'
}, },
{ {
label: Option.LocalRepository, label: Option.DetectEvent,
description: '', detail: 'Use first event type from workflow as event that triggered the workflow.'
detail: 'Replaces the specified repository and ref with a local folder (e.g. https://github.com/test/test@v0=/home/act/test or test/test@v0=/home/act/test, the latter matches any hosts or protocols).' },
}, {
{ label: Option.Directory,
label: Option.LogPrefixJobId, description: '.',
detail: 'Output the job id within non-json logs instead of the entire name.' detail: 'The working directory used when running a nektos/act command.'
}, },
{ {
label: Option.Network, label: Option.DryRun,
description: 'host', detail: 'Disable container creation and validate only workflow correctness.'
detail: 'Sets a docker network name.' },
}, {
{ label: Option.GithubInstance,
label: Option.NoCacheServer, description: 'github.com',
detail: 'Disable cache server.' detail: 'The GitHub instance to use. Only use this when using GitHub Enterprise Server.'
}, },
{ {
label: Option.NoRecurse, label: Option.InsecureSecrets,
detail: 'Flag to disable running workflows from subdirectories of specified path in --workflows/-W flag.' detail: 'Show secrets while printing logs (NOT RECOMMENDED!).'
}, },
{ {
label: Option.NoSkipCheckout, label: Option.Json,
detail: 'Do not skip actions/checkout.' detail: 'Output logs in json format.'
}, },
{ {
label: Option.Privileged, label: Option.LocalRepository,
detail: 'Use privileged mode.' description: '',
}, detail: 'Replaces the specified repository and ref with a local folder (e.g. https://github.com/test/test@v0=/home/act/test or test/test@v0=/home/act/test, the latter matches any hosts or protocols).'
{ },
label: Option.Pull, {
detail: 'Pull docker image(s) even if already present.' label: Option.LogPrefixJobId,
}, detail: 'Output the job id within non-json logs instead of the entire name.'
{ },
label: Option.Quiet, {
detail: 'Disable logging of output from steps.' label: Option.Network,
}, description: 'host',
{ detail: 'Sets a docker network name.'
label: Option.Rebuild, },
detail: 'Rebuild local action docker image(s) even if already present.' {
}, label: Option.NoCacheServer,
{ detail: 'Disable cache server.'
label: Option.RemoteName, },
description: 'origin', {
detail: 'Git remote name that will be used to retrieve the URL of Git repo.' label: Option.NoRecurse,
}, detail: 'Flag to disable running workflows from subdirectories of specified path in --workflows/-W flag.'
{ },
label: Option.ReplaceGheActionTokenWithGithubCom, {
description: '', label: Option.NoSkipCheckout,
detail: 'If you are using replace-ghe-action-with-github-com and you want to use private actions on GitHub, you have to set a personal access token.' detail: 'Do not skip actions/checkout.'
}, },
{ {
label: Option.ReplaceGheActionWithGithubCom, label: Option.Privileged,
description: '', detail: 'Use privileged mode.'
detail: 'If you are using GitHub Enterprise Server and allow specified actions from GitHub (github.com), you can set actions on this.' },
}, {
{ label: Option.Pull,
label: Option.Reuse, detail: 'Pull docker image(s) even if already present.'
detail: 'Don\'t remove container(s) on successfully completed workflow(s) to maintain state between runs.' },
}, {
{ label: Option.Quiet,
label: Option.Rm, detail: 'Disable logging of output from steps.'
detail: 'Automatically remove container(s)/volume(s) after a workflow(s) failure.' },
}, {
{ label: Option.Rebuild,
label: Option.UseGitignore, detail: 'Rebuild local action docker image(s) even if already present.'
detail: 'Controls whether paths specified in a .gitignore file should be copied into the container.' },
}, {
{ label: Option.RemoteName,
label: Option.UseNewActionCache, description: 'origin',
detail: 'Enable using the new Action Cache for storing Actions locally.' detail: 'Git remote name that will be used to retrieve the URL of Git repo.'
}, },
{ {
label: Option.Userns, label: Option.ReplaceGheActionTokenWithGithubCom,
description: '', description: '',
detail: 'User namespace to use.' detail: 'If you are using replace-ghe-action-with-github-com and you want to use private actions on GitHub, you have to set a personal access token.'
}, },
{ {
label: Option.Verbose, label: Option.ReplaceGheActionWithGithubCom,
detail: 'Enable verbose output.' description: '',
} detail: 'If you are using GitHub Enterprise Server and allow specified actions from GitHub (github.com), you can set actions on this.'
]; },
{
label: Option.Reuse,
detail: 'Don\'t remove container(s) on successfully completed workflow(s) to maintain state between runs.'
},
{
label: Option.Rm,
detail: 'Automatically remove container(s)/volume(s) after a workflow(s) failure.'
},
{
label: Option.UseGitignore,
detail: 'Controls whether paths specified in a .gitignore file should be copied into the container.'
},
{
label: Option.UseNewActionCache,
detail: 'Enable using the new Action Cache for storing Actions locally.'
},
{
label: Option.Userns,
description: '',
detail: 'User namespace to use.'
},
{
label: Option.Verbose,
detail: 'Enable verbose output.'
}
];
}
options.forEach((option, index) => { options.forEach((option, index) => {
options[index].label = options[index].label.slice(2); options[index].label = options[index].label.slice(2);