From d08fed3cf5ff08e6f140309d056177801790168c Mon Sep 17 00:00:00 2001 From: Felipe Suero Date: Wed, 5 Apr 2023 12:34:50 -0400 Subject: [PATCH] duplicate logic --- workflow-parser/src/model/converter/events.ts | 32 ++++--- .../src/model/converter/workflow-call.ts | 95 ++++++++++++++++++- 2 files changed, 114 insertions(+), 13 deletions(-) diff --git a/workflow-parser/src/model/converter/events.ts b/workflow-parser/src/model/converter/events.ts index dcfede6..8569f0e 100644 --- a/workflow-parser/src/model/converter/events.ts +++ b/workflow-parser/src/model/converter/events.ts @@ -60,18 +60,28 @@ export function convertOn(context: TemplateContext, token: TemplateToken): Event // All other events are defined as mappings. During schema validation we already ensure that events // receive only known keys, so here we can focus on the values and whether they are valid. const eventToken = item.value.assertMapping(`event ${eventName}`); - - result[eventName] = { - ...convertPatternFilter("branches", eventToken), - ...convertPatternFilter("tags", eventToken), - ...convertPatternFilter("paths", eventToken), - ...convertFilter("types", eventToken), - ...convertFilter("workflows", eventToken), - // workflow_call and workflow_dispatch share input parsing - ...convertEventWorkflowDispatchInputs(context, eventToken), - ...convertEventWorkflowCall(context, eventToken) - }; + if(eventName === "workflow_call") { + result[eventName] = { + ...convertPatternFilter("branches", eventToken), + ...convertPatternFilter("tags", eventToken), + ...convertPatternFilter("paths", eventToken), + ...convertFilter("types", eventToken), + ...convertFilter("workflows", eventToken), + ...convertEventWorkflowCall(context, eventToken) + }; + }else{ + result[eventName] = { + ...convertPatternFilter("branches", eventToken), + ...convertPatternFilter("tags", eventToken), + ...convertPatternFilter("paths", eventToken), + ...convertFilter("types", eventToken), + ...convertFilter("workflows", eventToken), + ...convertEventWorkflowDispatchInputs(context, eventToken), + }; + } } + + return result; } diff --git a/workflow-parser/src/model/converter/workflow-call.ts b/workflow-parser/src/model/converter/workflow-call.ts index bc699d1..0da7faf 100644 --- a/workflow-parser/src/model/converter/workflow-call.ts +++ b/workflow-parser/src/model/converter/workflow-call.ts @@ -1,7 +1,9 @@ import {TemplateContext} from "../../templates/template-context"; import {MappingToken, TemplateToken} from "../../templates/tokens"; import {isMapping} from "../../templates/tokens/type-guards"; -import {SecretConfig, WorkflowCallConfig} from "../workflow-template"; +import {SecretConfig, WorkflowCallConfig, InputConfig,InputType} from "../workflow-template"; +import {convertStringList} from "./string-list"; +import {ScalarToken} from "../../templates/tokens/scalar-token"; export function convertEventWorkflowCall(context: TemplateContext, token: MappingToken): WorkflowCallConfig { const result: WorkflowCallConfig = {}; @@ -11,7 +13,7 @@ export function convertEventWorkflowCall(context: TemplateContext, token: Mappin switch (key.value) { case "inputs": - // Ignore, these are handled by convertEventWorkflowDispatchInputs + result.inputs = convertWorkflowInputs(context, item.value.assertMapping("workflow dispatch inputs")); break; case "secrets": @@ -27,6 +29,95 @@ export function convertEventWorkflowCall(context: TemplateContext, token: Mappin return result; } + +export function convertWorkflowInputs( + context: TemplateContext, + token: MappingToken +): { + [inputName: string]: InputConfig; +} { + const result: {[inputName: string]: InputConfig} = {}; + + for (const item of token) { + const inputName = item.key.assertString("input name"); + const inputMapping = item.value.assertMapping("input configuration"); + + result[inputName.value] = convertWorkflowInput(context, inputMapping); + } + + return result; +} + +export function convertWorkflowInput(context: TemplateContext, token: MappingToken): InputConfig { + const result: InputConfig = { + type: InputType.string // Default to string + }; + + let defaultValue: undefined | ScalarToken; + + for (const item of token) { + const key = item.key.assertString("workflow dispatch input key"); + + switch (key.value) { + case "description": + result.description = item.value.assertString("input description").value; + break; + + case "required": + result.required = item.value.assertBoolean("input required").value; + break; + + case "default": + defaultValue = item.value.assertScalar("input default"); + break; + + case "type": + result.type = InputType[item.value.assertString("input type").value as keyof typeof InputType]; + break; + + case "options": + result.options = convertStringList("input options", item.value.assertSequence("input options")); + break; + + default: + context.error(item.key, `Invalid key '${key.value}'`); + } + } + + // Validate default value + if (defaultValue !== undefined) { + try { + switch (result.type) { + case InputType.boolean: + result.default = defaultValue.assertBoolean("input default").value; + + break; + + case InputType.string: + case InputType.choice: + case InputType.environment: + result.default = defaultValue.assertString("input default").value; + break; + } + } catch (e) { + context.error(defaultValue, e); + } + } + + // Validate `options` for `choice` type + if (result.type === InputType.choice) { + if (result.options === undefined || result.options.length === 0) { + context.error(token, "Missing 'options' for choice input"); + } + } else { + if (result.options !== undefined) { + context.error(token, "Input type is not 'choice', but 'options' is defined"); + } + } + + return result; +} + function convertWorkflowCallSecrets( context: TemplateContext, token: MappingToken