Merge pull request #29612 from Parsifal-M/docs/software-templates-pt2
[Docs] Software Templates Part 2
This commit is contained in:
@@ -10,15 +10,19 @@ git repository.
|
||||
|
||||
## Action Modules
|
||||
|
||||
There are also several modules available for various SCM tools:
|
||||
There are several action modules that are available to be added:
|
||||
|
||||
- Azure DevOps: `@backstage/plugin-scaffolder-backend-module-azure`
|
||||
- Bitbucket Cloud: `@backstage/plugin-scaffolder-backend-module-bitbucket-cloud`
|
||||
- Bitbucket Server: `@backstage/plugin-scaffolder-backend-module-bitbucket-server`
|
||||
- Gerrit: `@backstage/plugin-scaffolder-backend-module-gerrit`
|
||||
- Gitea: `@backstage/plugin-scaffolder-backend-module-gitea`
|
||||
- GitHub: `@backstage/plugin-scaffolder-backend-module-github`
|
||||
- GitLab: `@backstage/plugin-scaffolder-backend-module-gitlab`
|
||||
- [Azure DevOps](https://github.com/backstage/backstage/tree/master/plugins/scaffolder-backend-module-azure): `@backstage/plugin-scaffolder-backend-module-azure`
|
||||
- [Bitbucket Cloud](https://github.com/backstage/backstage/tree/master/plugins/scaffolder-backend-module-bitbucket-cloud): `@backstage/plugin-scaffolder-backend-module-bitbucket-cloud`
|
||||
- [Bitbucket Server](https://github.com/backstage/backstage/tree/master/plugins/scaffolder-backend-module-bitbucket-server): `@backstage/plugin-scaffolder-backend-module-bitbucket-server`
|
||||
- [Gerrit](https://github.com/backstage/backstage/tree/master/plugins/scaffolder-backend-module-gerrit): `@backstage/plugin-scaffolder-backend-module-gerrit`
|
||||
- [Gitea](https://github.com/backstage/backstage/tree/master/plugins/scaffolder-backend-module-gitea): `@backstage/plugin-scaffolder-backend-module-gitea`
|
||||
- [GitHub](https://github.com/backstage/backstage/tree/master/plugins/scaffolder-backend-module-github): `@backstage/plugin-scaffolder-backend-module-github`
|
||||
- [GitLab](https://github.com/backstage/backstage/tree/master/plugins/scaffolder-backend-module-gitlab): `@backstage/plugin-scaffolder-backend-module-gitlab`
|
||||
- [Rails](https://github.com/backstage/backstage/tree/master/plugins/scaffolder-backend-module-rails): `@backstage/plugin-scaffolder-backend-module-rails`
|
||||
- [Yeoman](https://github.com/backstage/backstage/tree/master/plugins/scaffolder-backend-module-yeoman): `@backstage/plugin-scaffolder-backend-module-yeoman`
|
||||
- [Sentry](https://github.com/backstage/backstage/tree/master/plugins/scaffolder-backend-module-sentry): `@backstage/plugin-scaffolder-backend-module-sentry`
|
||||
- [Cookiecutter](https://github.com/backstage/backstage/tree/master/plugins/scaffolder-backend-module-cookiecutter): `@backstage/plugin-scaffolder-backend-module-cookiecutter`
|
||||
|
||||
## Installing Action Modules
|
||||
|
||||
@@ -37,7 +41,6 @@ const backend = createBackend();
|
||||
|
||||
backend.add(import('@backstage/plugin-app-backend'));
|
||||
|
||||
// catalog plugin
|
||||
backend.add(import('@backstage/plugin-catalog-backend'));
|
||||
backend.add(
|
||||
import('@backstage/plugin-catalog-backend-module-scaffolder-entity-model'),
|
||||
@@ -51,12 +54,6 @@ backend.add(import('@backstage/plugin-scaffolder-backend-module-github'));
|
||||
backend.start();
|
||||
```
|
||||
|
||||
:::note Note
|
||||
|
||||
This is a simplified example of what your backend may look like, you may have more code in here then this.
|
||||
|
||||
:::
|
||||
|
||||
## Listing Actions
|
||||
|
||||
A list of all registered actions can be found under `/create/actions`. For local
|
||||
|
||||
@@ -78,11 +78,11 @@ Once you have more than a few software templates you may want to customize your
|
||||
accomplish this by creating `groups` and passing them to your `ScaffolderPage`
|
||||
like below
|
||||
|
||||
```
|
||||
```tsx
|
||||
<ScaffolderPage
|
||||
groups={[
|
||||
{
|
||||
title: "Recommended",
|
||||
title: 'Recommended',
|
||||
filter: entity =>
|
||||
entity?.metadata?.tags?.includes('recommended') ?? false,
|
||||
},
|
||||
@@ -96,6 +96,7 @@ top of the page above any other templates not filtered by this group or others.
|
||||
You can also further customize groups by passing in a `titleComponent` instead
|
||||
of a `title` which will be a component to use as the header instead of just the
|
||||
default `ContentHeader` with the `title` set as it's value.
|
||||
|
||||

|
||||
|
||||
There is also an option to hide some templates.
|
||||
|
||||
@@ -12,6 +12,8 @@ It is important to remember that all examples are based on [react-jsonschema-for
|
||||
|
||||
### Simple input with basic validations
|
||||
|
||||
We can use a `pattern` to validate the input. The `pattern` is a regular expression that the input must match.
|
||||
|
||||
```yaml
|
||||
parameters:
|
||||
- title: Fill in some steps
|
||||
@@ -28,6 +30,8 @@ parameters:
|
||||
|
||||
#### Custom validation error message
|
||||
|
||||
This example shows how to customize the error message shown when the `pattern` validation fails.
|
||||
|
||||
```yaml
|
||||
parameters:
|
||||
- title: Fill in some steps
|
||||
@@ -47,6 +51,8 @@ parameters:
|
||||
|
||||
### Multi line text input
|
||||
|
||||
If you need to insert a multi-line string, you can use the `ui:widget: textarea` option. This will create a text area input instead of a single line input.
|
||||
|
||||
```yaml
|
||||
parameters:
|
||||
- title: Fill in some steps
|
||||
@@ -74,6 +80,8 @@ parameters:
|
||||
|
||||
### Array with custom titles
|
||||
|
||||
In the example below the user will see the `enumNames` instead of the `enum` values, making it easier to read.
|
||||
|
||||
```yaml
|
||||
parameters:
|
||||
- title: Fill in some steps
|
||||
@@ -103,6 +111,8 @@ parameters:
|
||||
|
||||
### A multiple choices list
|
||||
|
||||
This is a simple multiple choice list.
|
||||
|
||||
```yaml
|
||||
parameters:
|
||||
- title: Fill in some steps
|
||||
@@ -122,6 +132,8 @@ parameters:
|
||||
|
||||
### Array with another types
|
||||
|
||||
In the example below, it will create an array of custom objects. Once you add one, you will see an object where each one contains 3 fields, "How are you?", "Is it sunny?" and "Anything else?".
|
||||
|
||||
```yaml
|
||||
parameters:
|
||||
- title: Fill in some steps
|
||||
@@ -138,19 +150,19 @@ parameters:
|
||||
type: object
|
||||
properties:
|
||||
array:
|
||||
title: Array string with default value
|
||||
title: How are you?
|
||||
type: string
|
||||
default: value3
|
||||
default: good
|
||||
enum:
|
||||
- value1
|
||||
- value2
|
||||
- value3
|
||||
- good
|
||||
- okay
|
||||
- great
|
||||
flag:
|
||||
title: Boolean flag
|
||||
title: Is it sunny?
|
||||
type: boolean
|
||||
ui:widget: radio
|
||||
someInput:
|
||||
title: Simple text input
|
||||
title: Anything else?
|
||||
type: string
|
||||
```
|
||||
|
||||
@@ -158,6 +170,8 @@ parameters:
|
||||
|
||||
### Boolean
|
||||
|
||||
This adds a simple checkbox to the form. The value will be `true` or `false`.
|
||||
|
||||
```yaml
|
||||
parameters:
|
||||
- title: Fill in some steps
|
||||
@@ -169,6 +183,8 @@ parameters:
|
||||
|
||||
### Boolean Yes or No options
|
||||
|
||||
This example shows how to use a radio button instead of a checkbox with `Yes` or `No` options.
|
||||
|
||||
```yaml
|
||||
parameters:
|
||||
- title: Fill in some steps
|
||||
@@ -181,6 +197,8 @@ parameters:
|
||||
|
||||
### Boolean multiple options
|
||||
|
||||
You can create multiple checkboxes with different options. The example below shows how to create a list of features that can be enabled or disabled for example.
|
||||
|
||||
```yaml
|
||||
parameters:
|
||||
- title: Fill in some steps
|
||||
@@ -200,6 +218,8 @@ parameters:
|
||||
|
||||
## Markdown text blocks
|
||||
|
||||
Its possible to render markdown text blocks in the form. This is useful to add some help text or instructions for the user.
|
||||
|
||||
```yaml
|
||||
parameters:
|
||||
- title: Fill in some steps
|
||||
@@ -217,7 +237,7 @@ parameters:
|
||||
|
||||
## Use parameters as condition in steps
|
||||
|
||||
Conditions use Javascript equality operators.
|
||||
Its possible to conditionally run steps based on the value of a parameter. In the example below, we trigger the steps depending on the value of the `environment` parameter.
|
||||
|
||||
```yaml
|
||||
- name: Only development environments
|
||||
@@ -241,6 +261,8 @@ Conditions use Javascript equality operators.
|
||||
|
||||
## Use parameters as conditional for fields
|
||||
|
||||
Its also possible to conditionally show fields based on the value of a parameter. In the example below, we show the `lastName` field only if the `includeName` parameter is set to `true`.
|
||||
|
||||
```yaml
|
||||
parameters:
|
||||
- title: Fill in some steps
|
||||
@@ -269,6 +291,9 @@ parameters:
|
||||
|
||||
### Multiple conditional fields with custom ordering
|
||||
|
||||
In this example, we show how to conditionally show multiple fields based on the value of a parameter. The `ui:order` property is used to control the order of the fields in the form.
|
||||
In this case, we show the `lastName` and `address` fields only if the `includeName` and `includeAddress` parameters are set to `true`.
|
||||
|
||||
```yaml
|
||||
parameters:
|
||||
- title: Fill in some steps
|
||||
@@ -349,12 +374,16 @@ Testing of this functionality is not yet supported using _create/edit_. In addit
|
||||
|
||||
:::
|
||||
|
||||
Its possible to use placeholders to reference remote files. This is useful when you have some standard parameters or actions that you want to reuse across multiple templates.
|
||||
|
||||
### template.yaml
|
||||
|
||||
In our template, we use the `$yaml` placeholder to reference the `parameters.yaml` and `action.yaml` files. The `parameters.yaml` file contains some parameters that we want to use in our template, and the `action.yaml` file contains the action that we want to run.
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
parameters:
|
||||
- $yaml: https://github.com/example/path/to/example.yaml
|
||||
- $yaml: https://github.com/example/path/to/parameters.yaml # This would become the parameters as referenced in the parameters.yaml file
|
||||
- title: Fill in some steps
|
||||
properties:
|
||||
path:
|
||||
@@ -362,7 +391,7 @@ spec:
|
||||
type: string
|
||||
|
||||
steps:
|
||||
- $yaml: https://github.com/example/path/to/action.yaml
|
||||
- $yaml: https://github.com/example/path/to/action.yaml # This would become the publish action as referenced in the action.yaml file
|
||||
|
||||
- id: fetch
|
||||
name: Fetch template
|
||||
@@ -371,7 +400,9 @@ spec:
|
||||
url: ${{ parameters.path if parameters.path else '/root' }}
|
||||
```
|
||||
|
||||
### example.yaml
|
||||
### parameters.yaml
|
||||
|
||||
The `url` parameter will be added to the template.
|
||||
|
||||
```yaml
|
||||
title: Provide simple information
|
||||
@@ -385,6 +416,8 @@ properties:
|
||||
|
||||
### action.yaml
|
||||
|
||||
The `publish:github` action will be included in our template.
|
||||
|
||||
```yaml
|
||||
id: publish
|
||||
name: Publish files
|
||||
|
||||
@@ -25,7 +25,7 @@ setup process, allowing you to focus on your actions' unique functionality.
|
||||
Start by using the `yarn backstage-cli new` command to generate a scaffolder module. This command sets up the necessary
|
||||
boilerplate code, providing a smooth start:
|
||||
|
||||
```
|
||||
```sh
|
||||
$ yarn backstage-cli new
|
||||
? What do you want to create?
|
||||
plugin-common - A new isomorphic common plugin package
|
||||
@@ -34,8 +34,6 @@ $ yarn backstage-cli new
|
||||
> scaffolder-module - An module exporting custom actions for @backstage/plugin-scaffolder-backend
|
||||
```
|
||||
|
||||
You can find a [list](../../tooling/cli/03-commands.md) of all commands provided by the Backstage CLI.
|
||||
|
||||
When prompted, select the option to generate a scaffolder module. This creates a solid foundation for your custom
|
||||
action. Enter the name of the module you wish to create, and the CLI will generate the required files and directory
|
||||
structure.
|
||||
@@ -87,7 +85,7 @@ 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`
|
||||
@@ -151,9 +149,6 @@ Also feel free to use your company name to namespace them if you prefer too, for
|
||||
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.
|
||||
|
||||
### Adding a TemplateExample
|
||||
|
||||
A TemplateExample is a predefined structure that can be used to create custom actions in your software templates. It
|
||||
@@ -185,9 +180,23 @@ export const examples: TemplateExample[] = [
|
||||
];
|
||||
```
|
||||
|
||||
Add the example to the `createTemplateAction` under the object property `examples`:
|
||||
Add the example to `createTemplateAction` by including the `examples` property:
|
||||
|
||||
`return createTemplateAction<{ contents: string; filename: string }>({id: 'acme:file:create', description: 'Create an Acme file', examples, ...};`
|
||||
```ts
|
||||
return createTemplateAction({
|
||||
id: 'acme:file:create',
|
||||
description: 'Create an Acme file',
|
||||
schema: {
|
||||
input: {
|
||||
contents: d => d.string().describe('The contents of the file'),
|
||||
filename: d =>
|
||||
d.string().describe('The filename of the file that will be created'),
|
||||
},
|
||||
},
|
||||
examples,
|
||||
// ...rest of the action configuration
|
||||
});
|
||||
```
|
||||
|
||||
### The context object
|
||||
|
||||
@@ -275,9 +284,7 @@ env.registerInit({
|
||||
|
||||
### Using Checkpoints in Custom Actions (Experimental)
|
||||
|
||||
Idempotent action could be achieved via the usage of checkpoints.
|
||||
|
||||
Example:
|
||||
Idempotent action could be achieved via the usage of checkpoints, for example:
|
||||
|
||||
```ts title="plugins/my-company-scaffolder-actions-plugin/src/vendor/my-custom-action.ts"
|
||||
const res = await ctx.checkpoint?.({
|
||||
@@ -305,78 +312,9 @@ If you'll preserve the same key, and you'll try to restart the affected task, it
|
||||
The cached result will not match with the expected updated return type.
|
||||
By changing the key, you'll invalidate the cache of the checkpoint.
|
||||
|
||||
### Register Custom Actions with the Legacy Backend System
|
||||
## Contributed Community Actions
|
||||
|
||||
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
|
||||
`packages/backend/src/plugins/scaffolder.ts`
|
||||
You can find a list of community-contributed and open-source actions by:
|
||||
|
||||
```ts
|
||||
return await createRouter({
|
||||
catalogClient,
|
||||
logger: env.logger,
|
||||
config: env.config,
|
||||
database: env.database,
|
||||
reader: env.reader,
|
||||
});
|
||||
```
|
||||
|
||||
There's another property you can pass here, which is an array of `actions` which
|
||||
will set the available actions that the scaffolder has access to.
|
||||
|
||||
```ts
|
||||
import { createBuiltinActions } from '@backstage/plugin-scaffolder-backend';
|
||||
import { ScmIntegrations } from '@backstage/integration';
|
||||
import { createNewFileAction } from './scaffolder/actions/custom';
|
||||
|
||||
export default async function createPlugin(
|
||||
env: PluginEnvironment,
|
||||
): Promise<Router> {
|
||||
const catalogClient = new CatalogClient({ discoveryApi: env.discovery });
|
||||
const integrations = ScmIntegrations.fromConfig(env.config);
|
||||
|
||||
const builtInActions = createBuiltinActions({
|
||||
integrations,
|
||||
catalogClient,
|
||||
config: env.config,
|
||||
reader: env.reader,
|
||||
});
|
||||
|
||||
const actions = [...builtInActions, createNewFileAction()];
|
||||
|
||||
return createRouter({
|
||||
actions,
|
||||
catalogClient: catalogClient,
|
||||
logger: env.logger,
|
||||
config: env.config,
|
||||
database: env.database,
|
||||
reader: env.reader,
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
## List of custom action packages
|
||||
|
||||
Here is a list of Open Source custom actions that you can add to your Backstage
|
||||
scaffolder backend:
|
||||
|
||||
| Name | Package | Owner |
|
||||
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ |
|
||||
| Yeoman | [plugin-scaffolder-backend-module-yeoman](https://www.npmjs.com/package/@backstage/plugin-scaffolder-backend-module-yeoman) | [Backstage](https://backstage.io) |
|
||||
| Cookiecutter | [plugin-scaffolder-backend-module-cookiecutter](https://www.npmjs.com/package/@backstage/plugin-scaffolder-backend-module-cookiecutter) | [Backstage](https://backstage.io) |
|
||||
| Rails | [plugin-scaffolder-backend-module-rails](https://www.npmjs.com/package/@backstage/plugin-scaffolder-backend-module-rails) | [Backstage](https://backstage.io) |
|
||||
| HTTP requests | [scaffolder-backend-module-http-request](https://www.npmjs.com/package/@roadiehq/scaffolder-backend-module-http-request) | [Roadie](https://roadie.io) |
|
||||
| Utility actions | [scaffolder-backend-module-utils](https://www.npmjs.com/package/@roadiehq/scaffolder-backend-module-utils) | [Roadie](https://roadie.io) |
|
||||
| AWS cli actions | [scaffolder-backend-module-aws](https://www.npmjs.com/package/@roadiehq/scaffolder-backend-module-aws) | [Roadie](https://roadie.io) |
|
||||
| Scaffolder .NET Actions | [plugin-scaffolder-dotnet-backend](https://www.npmjs.com/package/@plusultra/plugin-scaffolder-dotnet-backend) | [Alef Carlos](https://github.com/alefcarlos) |
|
||||
| Scaffolder Git Actions | [plugin-scaffolder-git-actions](https://www.npmjs.com/package/@mdude2314/backstage-plugin-scaffolder-git-actions) | [Drew Hill](https://github.com/arhill05) |
|
||||
| Azure Pipeline Actions | [scaffolder-backend-module-azure-pipelines](https://www.npmjs.com/package/@parfuemerie-douglas/scaffolder-backend-module-azure-pipelines) | [Parfümerie Douglas](https://github.com/Parfuemerie-Douglas) |
|
||||
| Azure Repository Actions | [scaffolder-backend-module-azure-repositories](https://www.npmjs.com/package/@parfuemerie-douglas/scaffolder-backend-module-azure-repositories) | [Parfümerie Douglas](https://github.com/Parfuemerie-Douglas) |
|
||||
| Snyk Import Project | [plugin-scaffolder-backend-module-snyk](https://www.npmjs.com/package/@ma11hewthomas/plugin-scaffolder-backend-module-snyk) | [Matthew Thomas](https://github.com/Ma11hewThomas) |
|
||||
| JSON Merge Actions | [plugin-scaffolder-json-merge-actions](https://www.npmjs.com/package/@mdude2314/backstage-plugin-scaffolder-json-merge-actions) | [Drew Hill](https://github.com/arhill05) |
|
||||
| NPM Actions | [plugin-scaffolder-npm-actions](https://www.npmjs.com/package/@mdude2314/backstage-plugin-scaffolder-npm-actions) | [Drew Hill](https://github.com/arhill05) |
|
||||
| Slack Actions | [plugin-scaffolder-backend-module-slack](https://www.npmjs.com/package/@mdude2314/backstage-plugin-scaffolder-backend-module-slack) | [Drew Hill](https://github.com/arhill05) |
|
||||
| Microsoft Teams Actions | [plugin-scaffolder-backend-module-ms-teams](https://www.npmjs.com/package/@grvpandey11/backstage-plugin-scaffolder-backend-module-ms-teams) | [Gaurav Pandey](https://github.com/grvpandey11) |
|
||||
|
||||
Have fun! 🚀
|
||||
- Going to the [Backstage Plugin Directory](https://backstage.io/plugins/) and filter by `scaffolder`!
|
||||
- Checking out the [Community Plugins Repo](https://github.com/backstage/community-plugins)!
|
||||
|
||||
@@ -4,8 +4,7 @@ title: Writing Templates
|
||||
description: Details around creating your own custom Software Templates
|
||||
---
|
||||
|
||||
Templates are stored in the **Software Catalog** under a kind `Template`. You
|
||||
can create your own templates with a small `yaml` definition which describes the
|
||||
You can create your own templates with a small `yaml` definition which describes the
|
||||
template and its metadata, along with some input variables that your template
|
||||
will need, and then a list of actions which are then executed by the scaffolding
|
||||
service.
|
||||
|
||||
Reference in New Issue
Block a user