chore: adding the new if syntax and using the power of nunjucks

Signed-off-by: blam <ben@blam.sh
Signed-off-by: blam <ben@blam.sh>
This commit is contained in:
blam
2021-09-28 04:10:33 +02:00
parent 1ec5ef3699
commit c7b089a5ae
2 changed files with 86 additions and 1 deletions
@@ -60,6 +60,7 @@ describe('DefaultWorkflowRunner', () => {
description: 'Mock action for testing',
handler: async ctx => {
ctx.output('mock', 'backstage');
ctx.output('shouldRun', true);
},
});
@@ -85,7 +86,76 @@ describe('DefaultWorkflowRunner', () => {
});
describe('validation', () => {});
describe('running', () => {});
describe('conditionals', () => {
it('should execute steps conditionally', async () => {
const task = createMockTaskWithSpec({
apiVersion: 'backstage.io/v1beta3',
steps: [
{ id: 'test', name: 'test', action: 'output-action' },
{
id: 'conditional',
name: 'conditional',
action: 'output-action',
if: '${{ steps.test.output.shouldRun }}',
},
],
output: {
result: '${{ steps.conditional.output.mock }}',
},
parameters: {},
});
const { output } = await runner.execute(task);
expect(output.result).toBe('backstage');
});
it('should skips steps conditionally', async () => {
const task = createMockTaskWithSpec({
apiVersion: 'backstage.io/v1beta3',
steps: [
{ id: 'test', name: 'test', action: 'output-action' },
{
id: 'conditional',
name: 'conditional',
action: 'output-action',
if: '${{ not steps.test.output.shouldRun}}',
},
],
output: {
result: '${{ steps.conditional.output.mock }}',
},
parameters: {},
});
const { output } = await runner.execute(task);
expect(output.result).toBeUndefined();
});
it('should skips steps using the negating equals operator', async () => {
const task = createMockTaskWithSpec({
apiVersion: 'backstage.io/v1beta3',
steps: [
{ id: 'test', name: 'test', action: 'output-action' },
{
id: 'conditional',
name: 'conditional',
action: 'output-action',
if: '${{ steps.test.output.mock !== "backstage"}}',
},
],
output: {
result: '${{ steps.conditional.output.mock }}',
},
parameters: {},
});
const { output } = await runner.execute(task);
expect(output.result).toBeUndefined();
});
});
describe('templating', () => {
it('should template the input to an action', async () => {
@@ -30,6 +30,7 @@ import path from 'path';
import { JsonObject, JsonValue } from '@backstage/config';
import { InputError } from '@backstage/errors';
import { PassThrough } from 'stream';
import { isTruthy } from './helper';
type Options = {
workingDirectory: string;
@@ -92,6 +93,9 @@ export class DefaultWorkflowRunner implements WorkflowRunner {
try {
if (typeof value === 'string') {
const templated = this.nunjucks.renderString(value, context);
if (templated === '') {
return undefined;
}
try {
return JSON.parse(templated);
} catch {
@@ -147,6 +151,16 @@ export class DefaultWorkflowRunner implements WorkflowRunner {
for (const step of task.spec.steps) {
try {
if (step.if) {
const ifResult = await this.render(step.if, context);
if (!isTruthy(ifResult)) {
await task.emitLog(
`Skipping step ${step.id} because it's if condition was false`,
);
continue;
}
}
const action = this.options.actionRegistry.get(step.action);
const { taskLogger, streamLogger } = createStepLogger({ task, step });
@@ -189,6 +203,7 @@ export class DefaultWorkflowRunner implements WorkflowRunner {
stepId: step.id,
status: 'failed',
});
throw err;
}
}