diff --git a/src/Action.ts b/src/Action.ts index e8fee51d..d84930bf 100644 --- a/src/Action.ts +++ b/src/Action.ts @@ -123,14 +123,26 @@ export type ActionYaml = { * Parses and represents metadata from action.yml. */ export default class Action implements ActionYaml { - static validate(obj: unknown): obj is ActionType { + static validate(obj: unknown): obj is ActionYaml { if (typeof obj !== 'object' || obj === null) { return false; } const record = obj as Record; + const isRecord = (value: unknown): value is Record => + typeof value === 'object' && value !== null && !Array.isArray(value); + const validDescriptions = (value: unknown): boolean => + value === undefined || + (isRecord(value) && + Object.values(value).every( + (entry) => isRecord(entry) && + (entry.description === undefined || typeof entry.description === 'string'), + )); + if (!validDescriptions(record.inputs) || !validDescriptions(record.outputs)) { + return false; + } if ('name' in record && 'description' in record && 'runs' in record) { - const runs = record.runs as Record | undefined; - if (runs && 'using' in runs) { + const runs = record.runs; + if (typeof runs === 'object' && runs !== null && !Array.isArray(runs) && 'using' in runs) { return ( typeof record.name === 'string' && typeof record.description === 'string' && @@ -183,7 +195,7 @@ export default class Action implements ActionYaml { try { actionYaml = this.loadActionFrom(actionPath); } catch (error) { - throw new Error(`Failed to load ${actionPath}. ${String(error)}`); + throw new Error(`Failed to load ${actionPath}. ${String(error)}`, { cause: error }); } this.log.debug(`Action YAML: ${JSON.stringify(actionYaml)}`); @@ -215,7 +227,7 @@ export default class Action implements ActionYaml { this.rawYamlString = fs.readFileSync(actionPath, 'utf8'); this.log.debug(`Parse ${actionPath} from ${actionDir}`); - const actionObj = YAML.parse(this.rawYamlString) as ActionYaml; + const actionObj: unknown = YAML.parse(this.rawYamlString); if (Action.validate(actionObj)) { return actionObj; }