diff --git a/.changeset/.changeset/rude-gifts-pay.md b/.changeset/.changeset/rude-gifts-pay.md new file mode 100644 index 0000000000..4440f2ffc1 --- /dev/null +++ b/.changeset/.changeset/rude-gifts-pay.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Show action example yaml on the scaffolder actions documentation page. diff --git a/.changeset/metal-nails-punch.md b/.changeset/metal-nails-punch.md new file mode 100644 index 0000000000..07265d1343 --- /dev/null +++ b/.changeset/metal-nails-punch.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +Changes to provide examples alongside scaffolder task actions. diff --git a/plugins/scaffolder-backend/api-report.md b/plugins/scaffolder-backend/api-report.md index 69ef893dc3..73b6177c6a 100644 --- a/plugins/scaffolder-backend/api-report.md +++ b/plugins/scaffolder-backend/api-report.md @@ -843,6 +843,10 @@ export class TaskWorker { export type TemplateAction = { id: string; description?: string; + examples?: { + description: string; + example: string; + }[]; supportsDryRun?: boolean; schema?: { input?: Schema; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.ts index 4b9f883706..e31f3355a6 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.ts @@ -19,6 +19,28 @@ import { ScmIntegrations } from '@backstage/integration'; import { CatalogApi } from '@backstage/catalog-client'; import { stringifyEntityRef } from '@backstage/catalog-model'; import { createTemplateAction } from '../../createTemplateAction'; +import yaml from 'yaml'; + +const id = 'catalog:register'; + +const examples = [ + { + description: 'Register With the catalog', + example: yaml.stringify({ + steps: [ + { + action: id, + id: 'register-with-catalog', + name: 'Register with the catalog', + input: { + catalogInfoUrl: + 'http://github.com/backstage/backstage/blob/master/catalog-info.yaml', + }, + }, + ], + }), + }, +]; /** * Registers entities from a catalog descriptor file in the workspace into the software catalog. @@ -34,9 +56,10 @@ export function createCatalogRegisterAction(options: { | { catalogInfoUrl: string; optional?: boolean } | { repoContentsUrl: string; catalogInfoPath?: string; optional?: boolean } >({ - id: 'catalog:register', + id, description: 'Registers entities from a catalog descriptor file in the workspace into the software catalog.', + examples, schema: { input: { oneOf: [ diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.ts index da758898dc..5257839f2d 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.ts @@ -20,14 +20,47 @@ import * as yaml from 'yaml'; import { Entity } from '@backstage/catalog-model'; import { resolveSafeChildPath } from '@backstage/backend-common'; +const id = 'catalog:write'; + +const examples = [ + { + description: 'Write a catalog yaml file', + example: yaml.stringify({ + steps: [ + { + action: id, + id: 'create-catalog-info-file', + name: 'Create catalog file', + input: { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + name: 'test', + annotations: {}, + }, + spec: { + type: 'service', + lifecycle: 'production', + owner: 'default/owner', + }, + }, + }, + }, + ], + }), + }, +]; + /** * Writes a catalog descriptor file containing the provided entity to a path in the workspace. * @public */ export function createCatalogWriteAction() { return createTemplateAction<{ filePath?: string; entity: Entity }>({ - id: 'catalog:write', + id, description: 'Writes the catalog-info.yaml for your template', + examples, schema: { input: { type: 'object', diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/log.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/log.ts index 99d030b772..79e555eb05 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/log.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/log.ts @@ -17,6 +17,27 @@ import { readdir, stat } from 'fs-extra'; import { relative, join } from 'path'; import { createTemplateAction } from '../../createTemplateAction'; +import yaml from 'yaml'; + +const id = 'debug:log'; + +const examples = [ + { + description: 'Write a debug message', + example: yaml.stringify({ + steps: [ + { + action: id, + id: 'write-debug-line', + name: 'Write log line', + input: { + message: 'Hello, there', + }, + }, + ], + }), + }, +]; /** * Writes a message into the log or lists all files in the workspace @@ -30,9 +51,10 @@ import { createTemplateAction } from '../../createTemplateAction'; */ export function createDebugLogAction() { return createTemplateAction<{ message?: string; listWorkspace?: boolean }>({ - id: 'debug:log', + id, description: 'Writes a message into the log or lists all files in the workspace.', + examples, schema: { input: { type: 'object', diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/types.ts b/plugins/scaffolder-backend/src/scaffolder/actions/types.ts index 666f7a0d50..0912cc038b 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/types.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/types.ts @@ -66,6 +66,7 @@ export type ActionContext = { export type TemplateAction = { id: string; description?: string; + examples?: { description: string; example: string }[]; supportsDryRun?: boolean; schema?: { input?: Schema; diff --git a/plugins/scaffolder-backend/src/service/router.ts b/plugins/scaffolder-backend/src/service/router.ts index e741961ddc..9ff8d43625 100644 --- a/plugins/scaffolder-backend/src/service/router.ts +++ b/plugins/scaffolder-backend/src/service/router.ts @@ -292,6 +292,7 @@ export async function createRouter( return { id: action.id, description: action.description, + examples: action.examples, schema: action.schema, }; }); diff --git a/plugins/scaffolder/api-report.md b/plugins/scaffolder/api-report.md index 3fe1208ba9..6a029af6bf 100644 --- a/plugins/scaffolder/api-report.md +++ b/plugins/scaffolder/api-report.md @@ -38,6 +38,23 @@ import { UIOptionsType } from '@rjsf/utils'; import { UiSchema } from '@rjsf/utils'; import { z } from 'zod'; +// @public +export type Action = { + id: string; + description?: string; + schema?: { + input?: JSONSchema7; + output?: JSONSchema7; + }; + examples?: ActionExample[]; +}; + +// @public +export type ActionExample = { + description: string; + example: string; +}; + // @alpha export function createNextScaffolderFieldExtension< TReturnValue = unknown, @@ -188,14 +205,7 @@ export interface LayoutOptions

{ export type LayoutTemplate = FormProps_2['ObjectFieldTemplate']; // @public -export type ListActionsResponse = Array<{ - id: string; - description?: string; - schema?: { - input?: JSONSchema7; - output?: JSONSchema7; - }; -}>; +export type ListActionsResponse = Array; // @public export type LogEvent = { diff --git a/plugins/scaffolder/src/components/ActionsPage/ActionsPage.tsx b/plugins/scaffolder/src/components/ActionsPage/ActionsPage.tsx index 29951d7cb1..7a16337d09 100644 --- a/plugins/scaffolder/src/components/ActionsPage/ActionsPage.tsx +++ b/plugins/scaffolder/src/components/ActionsPage/ActionsPage.tsx @@ -27,6 +27,7 @@ import { TableContainer, TableHead, TableRow, + Grid, makeStyles, } from '@material-ui/core'; import { JSONSchema7, JSONSchema7Definition } from 'json-schema'; @@ -39,7 +40,11 @@ import { Header, Page, ErrorPage, + Table as BackstageTable, + TableColumn, + CodeSnippet, } from '@backstage/core-components'; +import { ActionExample } from '../../types'; const useStyles = makeStyles(theme => ({ code: { @@ -67,6 +72,29 @@ const useStyles = makeStyles(theme => ({ }, })); +const examplesColumns: TableColumn[] = [ + { + title: 'Description', + field: 'description', + width: '20%', + }, + { + title: 'Example', + render: ({ example }) => { + return ( + + + + ); + }, + }, +]; + export const ActionsPage = () => { const api = useApi(scaffolderApiRef); const classes = useStyles(); @@ -180,6 +208,24 @@ export const ActionsPage = () => { {renderTable(action.schema.output)} )} + {action.examples && ( + + Examples + + + )} ); }); diff --git a/plugins/scaffolder/src/index.ts b/plugins/scaffolder/src/index.ts index 1ed1346176..ae994191ce 100644 --- a/plugins/scaffolder/src/index.ts +++ b/plugins/scaffolder/src/index.ts @@ -22,6 +22,8 @@ export { scaffolderApiRef, ScaffolderClient } from './api'; export type { + Action, + ActionExample, ListActionsResponse, LogEvent, ScaffolderApi, diff --git a/plugins/scaffolder/src/types.ts b/plugins/scaffolder/src/types.ts index acb0f0e114..422661b896 100644 --- a/plugins/scaffolder/src/types.ts +++ b/plugins/scaffolder/src/types.ts @@ -43,18 +43,36 @@ export type ScaffolderTask = { }; /** - * The response shape for the `listActions` call to the `scaffolder-backend` + * A single action example * * @public */ -export type ListActionsResponse = Array<{ +export type ActionExample = { + description: string; + example: string; +}; + +/** + * The response shape for a single action in the `listActions` call to the `scaffolder-backend` + * + * @public + */ +export type Action = { id: string; description?: string; schema?: { input?: JSONSchema7; output?: JSONSchema7; }; -}>; + examples?: ActionExample[]; +}; + +/** + * The response shape for the `listActions` call to the `scaffolder-backend` + * + * @public + */ +export type ListActionsResponse = Array; /** @public */ export type ScaffolderOutputLink = {