From 808d30cc307bb2ec5118153718d99e9f508ad520 Mon Sep 17 00:00:00 2001 From: blam Date: Tue, 28 Sep 2021 20:29:19 +0200 Subject: [PATCH] docs: removing older documentation for now Signed-off-by: blam --- docs/features/software-templates/legacy.md | 117 ------ .../migrating-from-v1alpha1-to-v1beta2.md | 333 ------------------ .../migrating-from-v1beta2-to-v1beta3.md | 148 ++++++++ microsite/sidebars.json | 3 +- 4 files changed, 149 insertions(+), 452 deletions(-) delete mode 100644 docs/features/software-templates/legacy.md delete mode 100644 docs/features/software-templates/migrating-from-v1alpha1-to-v1beta2.md create mode 100644 docs/features/software-templates/migrating-from-v1beta2-to-v1beta3.md diff --git a/docs/features/software-templates/legacy.md b/docs/features/software-templates/legacy.md deleted file mode 100644 index 49f3e21904..0000000000 --- a/docs/features/software-templates/legacy.md +++ /dev/null @@ -1,117 +0,0 @@ ---- -id: template-legacy -title: Writing Templates (Legacy) -# prettier-ignore -description: Old documentation describing the backstage.io/v1alpha1 format of the Template Schema ---- - -## Kind: Template - -Describes the following entity kind: - -| Field | Value | -| ------------ | ----------------------- | -| `apiVersion` | `backstage.io/v1alpha1` | -| `kind` | `Template` | - -A Template describes a skeleton for use with the Scaffolder. It is used for -describing what templating library is supported, and also for documenting the -variables that the template requires using -[JSON Forms Schema](https://jsonforms.io/). - -Descriptor files for this kind may look as follows. - -```yaml -apiVersion: backstage.io/v1alpha1 -kind: Template -metadata: - name: react-ssr-template - title: React SSR Template - description: - Next.js application skeleton for creating isomorphic web applications. - tags: - - recommended - - react -spec: - owner: web@example.com - templater: cookiecutter - type: website - path: '.' - schema: - required: - - component_id - - description - properties: - component_id: - title: Name - type: string - description: Unique name of the component - description: - title: Description - type: string - description: Description of the component -``` - -In addition to the [common envelope metadata](#common-to-all-kinds-the-metadata) -shape, this kind has the following structure. - -### `apiVersion` and `kind` [required] - -Exactly equal to `backstage.io/v1alpha1` and `Template`, respectively. - -### `metadata.title` [required] - -The nice display name for the template as a string, e.g. `React SSR Template`. -This field is required as is used to reference the template to the user instead -of the `metadata.name` field. - -### `metadata.tags` [optional] - -A list of strings that can be associated with the template, e.g. -`['recommended', 'react']`. - -This list will also be used in the frontend to display to the user so you can -potentially search and group templates by these tags. - -### `spec.type` [optional] - -The type of component as a string, e.g. `website`. This field is optional but -recommended. - -The software catalog accepts any type value, but an organization should take -great care to establish a proper taxonomy for these. Tools including Backstage -itself may read this field and behave differently depending on its value. For -example, a website type component may present tooling in the Backstage interface -that is specific to just websites. - -The current set of well-known and common values for this field is: - -- `service` - a backend service, typically exposing an API -- `website` - a website -- `library` - a software library, such as an npm module or a Java library - -### `spec.templater` [required] - -The templating library that is supported by the template skeleton as a string, -e.g `cookiecutter`. - -Different skeletons will use different templating syntax, so it's common that -the template will need to be run with a particular piece of software. - -This key will be used to identify the correct templater which is registered into -the `TemplatersBuilder`. - -The values which are available by default are: - -- `cookiecutter` - [cookiecutter](https://github.com/cookiecutter/cookiecutter). - -### `spec.path` [optional] - -The string location where the templater should be run if it is not on the same -level as the `template.yaml` definition, e.g. `./cookiecutter/skeleton`. - -This will set the `cwd` when running the templater to the folder path that you -specify relative to the `template.yaml` definition. - -This is also particularly useful when you have multiple template definitions in -the same repository but only a single `template.yaml` registered in backstage. diff --git a/docs/features/software-templates/migrating-from-v1alpha1-to-v1beta2.md b/docs/features/software-templates/migrating-from-v1alpha1-to-v1beta2.md deleted file mode 100644 index 58d88e8e9e..0000000000 --- a/docs/features/software-templates/migrating-from-v1alpha1-to-v1beta2.md +++ /dev/null @@ -1,333 +0,0 @@ ---- -id: migrating-from-v1alpha1-to-v1beta2 -title: Migrating to v1beta2 templates -# prettier-ignore -description: How to move your old templates from v1alpha1 to the more declarative v1beta2 ---- - -# What's new? - -Previously, the scaffolder was very restricted in what you could do when -creating new software components from templates. There were three scaffolding -steps which was pretty hard to extend and add new functionality to, difficult to -re-use logic between templates. There used to be a fixed pipeline of -`preparers`, `templaters`, and `publishers`, which were defined by the backend -and needed to be run for each template. This is now changed, to give the -template total control over what should be executed as part of the templating -run. This makes templates a little more declarative as you can now register -different `actions` or `functions` with the `scaffolder-backend` which you then -can decide how, and in what order, to run using the template definition YAML -file. - -We've also made some improvements, and added some helpers to work with -cookiecutter. The skeleton for a template can now be stored in a different place -to where your entity definition is: previously you needed to have your -`template.yaml` next to the skeleton source (`{{cookiecutter.component_id}}` -directory), but now that's not the case. Part of the changes with the `v1beta2` -syntax is that you can grab your template source from any repository, and re-use -them between templates. - -We've also renamed the `schema` property to `parameters` as this makes more -sense when using them as parameters to the actions or steps that you've setup -for your templates. There's the added benefit that you can now assign an array -to the `parameters` property, which will then give you multiple steps in the UI, -so you can split apart your input parameters and group them as needed rather -than having one long list of input fields. - -## The `parameters` property - -The `schema` key has now been renamed to `parameters` with a few more features. -You can pass an array now to break apart the input form into different steps in -the UI. You can also specify `ui:schema` fields that are passed along to -[`react-jsonschema-form`](https://rjsf-team.github.io/react-jsonschema-form/) -inline with the JSON schema. - -```yaml -spec: - parameters: - - title: Fill in some steps - required: - - name - properties: - name: - title: Name - type: string - description: Unique name of the component - ui:autofocus: true - ui:options: - rows: 5 -``` - -## The `steps` property - -`v1beta2` template syntax introduces the new `steps` property, which is an array -of `actions` that the scaffolder will run in combination with the user input -that is declared in the `schema`. Actions look like the following: - -```yaml -spec: - steps: - - id: publish # a unique id for the step, can be anything you like - name: Publish # a user friendly name for the step, this is what is shown in the frontend - action: publish:github # the action ID that has been registered with the scaffolder-backend - input: # parameters that are passed as input to the action handler function - allowedHosts: ['github.com'] - description: 'This is {{ parameters.name }}' # handlebars templating is supported with the values from the parameters section in the same file. - repoUrl: '{{ parameters.repoUrl }}' -``` - -# Migrating a `v1alpha1` template - -## The template definition (.yaml) - -### `parameters` - -Because of the changes to invert the control to the `template.yaml` definition -for running the workflow, we need to adjust the `schema` property and we also -now need to define what the template is actually going to do as part of the -template run. - -A simple migration would move the following yaml: - -```yaml -apiVersion: backstage.io/v1alpha1 -kind: Template -metadata: - name: react-ssr-template - title: React SSR Template - description: Create a website powered with Next.js - tags: - - recommended - - react -spec: - owner: web@example.com - templater: cookiecutter - type: website - path: '.' - schema: - required: - - component_id - - description - properties: - component_id: - title: Name - type: string - description: Unique name of the component - description: - title: Description - type: string - description: Help others understand what this website is for. -``` - -To something that looks like the following: - -```yaml -apiVersion: backstage.io/v1beta2 -kind: Template -metadata: - name: react-ssr-template - title: React SSR Template - description: Create a website powered with Next.js - tags: - - recommended - - react -spec: - owner: web@example.com - type: website - parameters: - - title: Add some input - required: - - component_id - - description - properties: - component_id: - title: Name - type: string - description: Unique name of the component - description: - title: Description - type: string - description: Help others understand what this website is for. - - title: Some more additional info that was previously provided automatically - required: - - owner - - repoUrl - properties: - owner: - title: Owner - type: string - description: Owner of the component - ui:field: OwnerPicker - ui:options: - allowedKinds: - - Group - - title: Choose a location - repoUrl: - title: Repository Location - type: string - ui:field: RepoUrlPicker - ui:options: - allowedHosts: - - github.com -``` - -There are a few things to note here. On the `alpha` version, the second step of -the template flow in the frontend was provided by Backstage for free, so we used -to collect the user input for the `owner` field and the `repositoryUrl` that you -were going to publish to. Now because `actions` can have any workflow they like, -it doesn't make sense to still provide these fields for every scaffolding -workflow, as you might not need these anymore. That's why we now manually add -those fields back into the template parameters that are shown to the user: - -```yaml - - title: Some more additional info that was previously provided automatically - required: - - owner - - repoUrl - properties: - owner: - title: Owner - type: string - description: Owner of the component - ui:field: OwnerPicker - ui:options: - allowedKinds: - - Group - - title: Choose a location - repoUrl: - title: Repository Location - type: string - ui:field: RepoUrlPicker - ui:options: - allowedHosts: - - github.com -``` - -Maybe you also don't need to publish to `github.com`, you should replace this -with your VCS provider URL that is listed in your `integrations` config instead. - -### `steps` - -So now we should have all the required information that we need from the user in -a much more extensible way. We now need to tell the scaffolder what to do with -these parameters and what to do with the user input. - -We've made templating using `cookiecutter` a little simpler. You don't need to -store the `cookiecutter` skeleton in the same directory as the `template.yaml` -definition, it can live wherever you like - maybe a shared repository somewhere -so you can re-use the skeletons but apply different actions for different -templates depending on your use case. - -We also no longer need to have a directory called -`{{cookiecutter.component_id}}`. This is because now we can't ensure that -`component_id` will be a parameter that is provided from the frontend, this -could break `cookiecutter`. If your directory structure used to look like this: - -``` -my-awesome-template - -> {{cookiecutter.component_id}} - -> file.txt - -> some_more_files.ts - -> hooks - -> post_gen_project.sh - -> template.yaml -``` - -We now recommend that you move to the following structure: - -``` -my-awesome-template - -> skeleton - -> file.txt - -> some_more_files.ts - -> template.yaml -``` - -This migration renames the skeleton folder to something more semantic, and also -drops support for `cookiecutter` hooks. We've dropped support for `cookiecutter` -hooks for now, as hopefully everything that is stored in these hooks can be -moved to `actions` instead, and for security reasons, it's more secure to run -trusted code that you ship with Backstage as an action rather than some script -that can be pulled in from anywhere which doesn't get vetted first. It's a -pretty big security risk that those scripts will be run on Backstage instances -inside your infrastructure, especially `.sh` files. - -If you really need hooks and can't find a suitable solution by using actions -please reach out to us through a ticket and we'll see what we can do to assist -:) - -You'll notice that we removed the `templater` property from the `spec` -definition in the template `yaml`, so there's no way to define that this is a -`cookiecutter` `templater`. - -We've created a built-in action that you can use which will when run, go grab a -directory from anywhere and run `cookiecutter` on top of it, and then extract -the contents into the working directory for the scaffolder. - -Adding the `steps` for a simple template should look something like the -following: - -```yaml -spec: - steps: - # this action will go use cookiecutter to template some files into the working directory - - id: template # an ID for the templating step - name: Create skeleton # A user friendly name for the action - action: fetch:cookiecutter - input: - url: ./skeleton # this is the directory for your skeleton files. - # If it's located next to the `template.yaml` then you can use a relative path, - # otherwise you can use absolute URLs that point at the VCS: https://github.com/backstage/backstage/tree/master/some_folder_somewhere - values: - # for each value that you need to pass to cookiecutter, they should be listed here and set in this values object. - # You can use the handlebars templating syntax to pull them from the input parameters listed in the same file - name: '{{ parameters.name }}' - owner: '{{ parameters.owner }}' - destination: '{{ parseRepoUrl parameters.repoUrl }}' - - # this action is for publishing the working directory to the VCS - - id: publish - name: Publish - action: publish:github - input: - allowedHosts: ['github.com'] - description: 'This is {{ parameters.name }}' - repoUrl: '{{ parameters.repoUrl }}' - - # this action will then register the created component in Backstage - - id: register - name: Register - action: catalog:register - input: - repoContentsUrl: '{{ steps.publish.output.repoContentsUrl }}' - catalogInfoPath: '/catalog-info.yaml' -``` - -### `output` - -Steps can output values, and so can the template itself. This is good for -returning values to the frontend, so we can make the buttons like -`Go to catalog` and `Go to repo` work correctly. You can add the following to -your `template.yaml` to make sure you return the right values from the steps: - -```yaml -spec: - output: - remoteUrl: '{{ steps.publish.output.remoteUrl }}' - entityRef: '{{ steps.register.output.entityRef }}' -``` - -Or you can return a `links` array with text and a URL explicitly: - -```yaml -spec: - output: - links: - - url: '{{steps.publish.output.remoteUrl}}' - title: 'Go to Repo' -``` - -## Questions? - -If you have any questions or feedback, please reach out to us on GitHub or -Discord and we will do our best to help! diff --git a/docs/features/software-templates/migrating-from-v1beta2-to-v1beta3.md b/docs/features/software-templates/migrating-from-v1beta2-to-v1beta3.md new file mode 100644 index 0000000000..8ccacfa301 --- /dev/null +++ b/docs/features/software-templates/migrating-from-v1beta2-to-v1beta3.md @@ -0,0 +1,148 @@ +--- +id: migrating-from-v1beta2-to-v1beta3 +title: Migrating to v1beta3 templates +# prettier-ignore +description: How to migrate your existing templates to beta3 syntax +--- + +# What's new? + +Well then, here we are! 🚀 + +Backstage has had many forms of templating languages throughout different +plugins and different systems. We've had `cookiecutter` syntax in templates, and +we also had `handlebars` templating in the `kind: Template`. Then we wanted to +remove the additional dependency on `cookiecutter` for `Software Templates` out +of the box, so we introduced `nunjucks` as an alternative in `fetch:template` +action which is based on the `jinja2` syntax so they're pretty similar. In an +effort to reduce confusion and unify on to one templating language, we're +officially deprecating support for `handlebars` templating in the +`kind: Template` entities with version `backstage.io/v1beta3` and moving to +using `nunjucks` instead. + +This provides us a lot of built in `filters` (`handlebars` helpers), that as +Template authors will give you much more flexibility out of the box, and also +open up sharing of filters in the `entity` and the actual `skeleton` too, and +removing the slight differences between the two languages. + +We've also removed a lot of the built in helpers that we shipped with +`handlebars`, as they're now supported as first class citizens by either +`nunjucks` or the new `scaffolder` when using `backstage.io/v1beta3` +`apiVersion` + +The migration path is pretty simple, and we've removed some of the pain points +from writing the `handlebars` templates too. Let's go through what's new and how +to upgrade. + +## `${{ }}` instead of `"{{ }}"` + +One really big readability and cause for confusing was the fact that with +`handlebars` and `yaml` was that you always had to wrap your templating strings +in quotes in `yaml` so that it didn't try to parse it as a `json` object and +fail. This was pretty annoying, as it also meant that all things look like +strings. Now that's no longer the case, you can now remove the `""` and take +advantage of writing nice `yaml` files that just work. + +```diff + spec: + steps: + input: + allowedHosts: ['github.com'] +- description: 'This is {{ parameters.name }}' ++ description: This is ${{ parameters.name }} +- repoUrl: '{{ parameters.repoUrl }}' ++ repoUrl: ${{ parameters.repoUrl }} +``` + +## No more `eq` or `not` helper + +These helpers are no longer needed with the more expressive `api` that +`nunjucks` provides. You can simply use the built-in `nunjucks` and `jinja2` +style operators. + +```diff + spec: + steps: + input: +- if: '{{ eq parameters.value "backstage" }}' ++ if: ${{ parameters.value === "backstage" }} + ... + +``` + +And then for the `not` + +```diff + spec: + steps: + input: +- if: '{{ not parameters.value "backstage" }}' ++ if: ${{ parameters.value !== "backstage" }} + ... + +``` + +Much better right? ✨ + +## No more `json` helper + +This helper is no longer needed, as we've added support for complex values and +supporting the additional primitive values now rather than everything being a +`string`. This means that now that you can pass around `parameters` and it +should all work as expected and keep the type that has been declared in the +input schema. + +```diff + spec: + parameters: + test: + type: number + name: Test Number + address: + type: object + required: + - line1 + properties: + line1:🙏 + type: string + name: Line 1 + line2: + type: string + name: Line 2 + + steps: + - id: test step + action: run:something + input: +- address: '{{ json parameters.address }}' ++ address: ${{ parameters.address }} +- number: '{{ parameters.number }}' ++ number: ${{ parameters.number }} # this will now make sure that the type of number is a number now 🙏 + +``` + +## `parseRepoUrl` is now a `filter` + +All calls to `parseRepoUrl` are now a `jinja2` `filter`, which means you'll need +to update the syntax. + +```diff + spec: + steps: + input: +- repoUrl: '{{ parseRepoUrl parameters.repoUrl }}' ++ repoUrl: ${{ parameters.repoUrl | parseRepoUrl }} + ... +``` + +Now we have complex value support here too, expect that this `filter` will go +away in future versions and the `RepoUrlPicker` will return an object so +`parameters.repoUrl` will already be a +`{ host: string; owner: string; repo: string }` 🚀 + +### Summary + +Of course, we're always available on [discord](https://discord.gg/MUpMjP2) if +you're stuck or something's not working as expected. You can also +[raise an issue](https://github.com/backstage/backstage/issues/new/choose) with +feedback or bugs! diff --git a/microsite/sidebars.json b/microsite/sidebars.json index c269f8ac8f..cdbfdccec3 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -78,8 +78,7 @@ "features/software-templates/builtin-actions", "features/software-templates/writing-custom-actions", "features/software-templates/writing-custom-field-extensions", - "features/software-templates/template-legacy", - "features/software-templates/migrating-from-v1alpha1-to-v1beta2" + "features/software-templates/migrating-from-v1beta2-to-v1beta3" ] }, {