diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts index 0ef0846ddb..1cf3f90774 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts @@ -24,6 +24,7 @@ import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import { TaskContext, TaskSecrets } from './types'; import { TaskSpec } from '@backstage/plugin-scaffolder-common'; +import { UserEntity } from '@backstage/catalog-model'; // The Stream module is lazy loaded, so make sure it's in the module cache before mocking fs void winston.transports.Stream; @@ -558,8 +559,8 @@ describe('DefaultWorkflowRunner', () => { }); }); - describe('filters', () => { - it('provides the parseRepoUrl filter', async () => { + describe('user', () => { + it('allows access to the user entity at the templating level', async () => { const task = createMockTaskWithSpec({ apiVersion: 'scaffolder.backstage.io/v1beta3', steps: [ @@ -587,4 +588,34 @@ describe('DefaultWorkflowRunner', () => { }); }); }); + + describe('filters', () => { + it('provides the parseRepoUrl filter', async () => { + const task = createMockTaskWithSpec({ + apiVersion: 'scaffolder.backstage.io/v1beta3', + steps: [ + { + id: 'test', + name: 'name', + action: 'output-action', + input: {}, + }, + ], + user: { + entity: { metadata: { name: 'bob' } } as UserEntity, + ref: 'user:default/guest', + }, + output: { + foo: '${{ user.entity.metadata.name }} ${{ user.ref }}', + }, + parameters: { + repoUrl: 'github.com?repo=repo&owner=owner', + }, + }); + + const { output } = await runner.execute(task); + + expect(output.foo).toEqual('bob user:default/guest'); + }); + }); }); diff --git a/plugins/scaffolder-common/src/TaskSpec.ts b/plugins/scaffolder-common/src/TaskSpec.ts index e745964ff7..4ba43092ae 100644 --- a/plugins/scaffolder-common/src/TaskSpec.ts +++ b/plugins/scaffolder-common/src/TaskSpec.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import { UserEntity } from '@backstage/catalog-model'; import { JsonValue, JsonObject } from '@backstage/types'; /** @@ -91,6 +92,19 @@ export interface TaskSpecV1beta3 { * Some information about the template that is stored on the task spec. */ templateInfo?: TemplateInfo; + /** + * Some decoration of the author of the task that should be available in the context + */ + user?: { + /** + * The decorated entity from the Catalog + */ + entity?: UserEntity; + /** + * An entity ref for the author of the task + */ + ref?: string; + }; } /** diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper copy.tsx b/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper copy.tsx deleted file mode 100644 index f864e9ee09..0000000000 --- a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper copy.tsx +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2022 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { - Stepper as MuiStepper, - Step as MuiStep, - StepLabel as MuiStepLabel, - Button, - makeStyles, -} from '@material-ui/core'; -import { withTheme } from '@rjsf/core'; -import { Theme as MuiTheme } from '@rjsf/material-ui'; -import React, { useMemo, useState } from 'react'; -import { FieldExtensionOptions } from '../../../extensions'; -import { TemplateParameterSchema } from '../../../types'; -import { useTemplateSchema } from './useTemplateSchema'; - -const useStyles = makeStyles(theme => ({ - backButton: { - marginRight: theme.spacing(1), - }, - footer: { - display: 'flex', - flexDirection: 'row', - justifyContent: 'right', - }, - formWrapper: { - padding: theme.spacing(2), - }, -})); - -export interface StepperProps { - manifest: TemplateParameterSchema; - extensions: FieldExtensionOptions[]; -} - -const Form = withTheme(MuiTheme); - -export const Stepper = (props: StepperProps) => { - const { steps } = useTemplateSchema(props.manifest); - const [activeStep, setActiveStep] = useState(0); - const styles = useStyles(); - - const extensions = useMemo(() => { - return Object.fromEntries( - props.extensions.map(({ name, component }) => [name, component]), - ); - }, [props.extensions]); - - const handleBack = () => { - setActiveStep(prevActiveStep => prevActiveStep - 1); - }; - const handleNext = () => { - setActiveStep(prevActiveStep => prevActiveStep + 1); - }; - - return ( - <> - - {steps.map((step, index) => ( - - {step.title} - - ))} - -
-
-
- - -
-
-
- - ); -};