From 37ab71200193ab9ea08dcea6918cec18583dd3e8 Mon Sep 17 00:00:00 2001 From: Juan Pablo Garcia Ripa Date: Sat, 11 Jan 2025 12:00:19 +0100 Subject: [PATCH] fix: add validation for the `each` values Signed-off-by: Juan Pablo Garcia Ripa --- .changeset/fair-rocks-dream.md | 5 +++++ .../tasks/NunjucksWorkflowRunner.test.ts | 21 +++++++++++++++++++ .../tasks/NunjucksWorkflowRunner.ts | 20 ++++++++++++------ 3 files changed, 40 insertions(+), 6 deletions(-) create mode 100644 .changeset/fair-rocks-dream.md diff --git a/.changeset/fair-rocks-dream.md b/.changeset/fair-rocks-dream.md new file mode 100644 index 0000000000..4d33a60bcd --- /dev/null +++ b/.changeset/fair-rocks-dream.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +add validation for `each` values diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts index 7e204d35df..31ba7195b2 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts @@ -988,6 +988,27 @@ describe('NunjucksWorkflowRunner', () => { ); expect(fakeActionHandler).not.toHaveBeenCalled(); }); + + it('should validate each parameter renders to a valid value', async () => { + const task = createMockTaskWithSpec({ + apiVersion: 'scaffolder.backstage.io/v1beta3', + steps: [ + { + id: 'test', + name: 'name', + each: '${{parameters.data}}', + action: 'jest-validated-action', + input: { foo: '${{each.value}}' }, + }, + ], + output: {}, + parameters: {}, + }); + await expect(runner.execute(task)).rejects.toThrow( + 'Invalid each value passed to action jest-validated-action, "${{parameters.data}}" cannot be resolved to a value', + ); + expect(fakeActionHandler).not.toHaveBeenCalled(); + }); }); describe('secrets', () => { diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts index ad9d85cb2d..9865f4db87 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts @@ -304,13 +304,21 @@ export class NunjucksWorkflowRunner implements WorkflowRunner { return; } } + + const resolvedEach = + step.each && this.render(step.each, context, renderTemplate); + + if (step.each && !resolvedEach) { + throw new InputError( + `Invalid each value passed to action ${action.id}, "${step.each}" cannot be resolved to a value`, + ); + } + const iterations = ( - step.each - ? Object.entries(this.render(step.each, context, renderTemplate)).map( - ([key, value]) => ({ - each: { key, value }, - }), - ) + resolvedEach + ? Object.entries(resolvedEach).map(([key, value]) => ({ + each: { key, value }, + })) : [{}] ).map(i => ({ ...i,