From 2384a499629320e59cc492958f5c2614074ec6bd Mon Sep 17 00:00:00 2001 From: Steven Billington Date: Wed, 24 Apr 2024 14:29:33 -0400 Subject: [PATCH] Making docs updates for software templates. Signed-off-by: Steven Billington --- .../software-templates/input-examples.md | 20 ++++++++++- .../writing-custom-actions.md | 34 +++++++++++++++++-- .../software-templates/writing-templates.md | 29 +++++++++++++++- 3 files changed, 78 insertions(+), 5 deletions(-) diff --git a/docs/features/software-templates/input-examples.md b/docs/features/software-templates/input-examples.md index a95cee24f4..50495b1784 100644 --- a/docs/features/software-templates/input-examples.md +++ b/docs/features/software-templates/input-examples.md @@ -181,9 +181,11 @@ parameters: ## Use parameters as condition in steps +Conditions use Javascript equality operators. + ```yaml - name: Only development environments - if: ${{ parameters.environment === "staging" and parameters.environment === "development" }} + if: ${{ parameters.environment === "staging" or parameters.environment === "development" }} action: debug:log input: message: 'development step' @@ -193,6 +195,12 @@ parameters: action: debug:log input: message: 'production step' + +- name: Non-production environments + if: ${{ parameters.environment !== "prod" and parameters.environment !== "production" }} + action: debug:log + input: + message: 'non-production step' ``` ## Use parameters as conditional for fields @@ -218,10 +226,15 @@ parameters: lastName: title: Last Name type: string + # You can use additional fields of parameters within conditional parameters such as required. + required: + - lastName ``` ## Conditionally set parameters +The `if` keyword within the parameter uses [nunjucks templating](https://mozilla.github.io/nunjucks/templating.html#if). The `not` keyword is unavailable; instead, use javascript equality. + ```yaml spec: parameters: @@ -237,4 +250,9 @@ spec: action: fetch:template input: url: ${{ parameters.path if parameters.path else '/root' }} + - id: fetch_not_example + name: Fetch template not example + action: fetch:template + input: + url: ${{ '/root' if parameters.path !== true else parameters.path }} ``` diff --git a/docs/features/software-templates/writing-custom-actions.md b/docs/features/software-templates/writing-custom-actions.md index 92ff092948..96b2540527 100644 --- a/docs/features/software-templates/writing-custom-actions.md +++ b/docs/features/software-templates/writing-custom-actions.md @@ -32,6 +32,7 @@ import { z } from 'zod'; export const createNewFileAction = () => { return createTemplateAction({ id: 'acme:file:create', + description: 'Create an Acme file.', schema: { input: z.object({ contents: z.string().describe('The contents of the file'), @@ -59,9 +60,10 @@ for reference. The `createTemplateAction` takes an object which specifies the following: -- `id` - a unique ID for your custom action. We encourage you to namespace these +- `id` - A unique ID for your custom action. We encourage you to namespace these in some way so that they won't collide with future built-in actions that we may ship with the `scaffolder-backend` plugin. +- `description` - An optional field to describe the purpose of the action. This will populate in the `/create/actions` endpoint. - `schema.input` - A `zod` or JSON schema object for input values to your function - `schema.output` - A `zod` or JSON schema object for values which are output from the function using `ctx.output` @@ -76,6 +78,7 @@ import { writeFile } from 'fs'; export const createNewFileAction = () => { return createTemplateAction<{ contents: string; filename: string }>({ id: 'acme:file:create', + description: 'Create an Acme file.', schema: { input: { required: ['contents', 'filename'], @@ -114,7 +117,7 @@ We follow `provider:entity:verb` or as close to this as possible for our built i Also feel free to use your company name to namespace them if you prefer too, for example `acme:file:create` like above. -Prefer to use `camelCase` over `snake-case` for these actions if possible, which leads to better reading and writing of template entity definitions. +Prefer to use `camelCase` over `snake_case` or `kebab-case` for these actions if possible, which leads to better reading and writing of template entity definitions. > We're aware that there are some exceptions to this, but try to follow as close as possible. We'll be working on migrating these in the repository over time too. @@ -139,6 +142,8 @@ argument. It looks like the following: ## Registering Custom Actions +### Register Action With Previous Backend System, Backstage Version < 1.25.x + Once you have your Custom Action ready for usage with the scaffolder, you'll need to pass this into the `scaffolder-backend` `createRouter` function. You should have something similar to the below in @@ -189,7 +194,7 @@ export default async function createPlugin( } ``` -### Register Action With New Backend System +### Register Action With New Backend System, Backstage Version >= 1.25.0 To register your new custom action in the New Backend System you will need to create a backend module. Here is a very simplified example of how to do that: @@ -225,6 +230,29 @@ backend.add(import('@backstage/plugin-scaffolder-backend/alpha')); backend.add(scaffolderModuleCustomExtensions()); ``` +If your custom action requires core services such as `config` or `cache` they can be imported in the dependencies and passed to the custom action function. + +```ts title="packages/backend/src/index.ts" +import { + coreServices, + createBackendModule, +} from '@backstage/backend-plugin-api'; + +... + + env.registerInit({ + deps: { + scaffolder: scaffolderActionsExtensionPoint, + cache: coreServices.cache, + config: coreServices.rootConfig, + }, + async init({ scaffolder, cache, config }) { + scaffolder.addActions( + customActionNeedingCacheAndConfig({ cache: cache, config: config }), + ); + }) +``` + ## List of custom action packages Here is a list of Open Source custom actions that you can add to your Backstage diff --git a/docs/features/software-templates/writing-templates.md b/docs/features/software-templates/writing-templates.md index ad542ba4a3..1e289d2409 100644 --- a/docs/features/software-templates/writing-templates.md +++ b/docs/features/software-templates/writing-templates.md @@ -311,10 +311,37 @@ spec: ``` If you have a feature flag `experimental-feature` active then -your first step would be shown. The same goes for the nested properties in the +your first set of parameter fields would be shown. The same goes for the nested properties in the spec. Make sure to use the key `backstage:featureFlag` in your templates if you want to use this functionality. +Feature Flags cannot be used in `spec.steps[].if`(the conditional on whether to execute an step/action). But you can use feature flags to display parameters that allow for skipping steps. + +```yaml +spec: + type: website + owner: team-a + parameters: + - name: Enter some stuff + description: Enter some stuff + backstage:featureFlag: experimental-feature + properties: + skipStep: + type: boolean + title: Whether or not to skip a step. + default: false + restOfParameters: + ... + steps: + - id: skipMe + name: A step to skip if the feature flag is turned on and the user selects true + action: debug:log + if: ${{ parameters.skipStep }} + input: + message: | + ... +``` + ### The Repository Picker In order to make working with repository providers easier, we've built a custom