Update scaffolder documentation

Co-authored-by: Ben Lambert <ben@blam.sh>
Signed-off-by: Johan Haals <johan.haals@gmail.com>
This commit is contained in:
Johan Haals
2021-03-01 11:30:13 +01:00
parent 41b044c81a
commit 78cfb21b1a
5 changed files with 328 additions and 153 deletions
@@ -522,49 +522,90 @@ consumed by the component, e.g. `artist-api`. This field is optional.
## Kind: Template
Describes the following entity kind:
The following describes the following entity kind:
| Field | Value |
| ------------ | ----------------------- |
| `apiVersion` | `backstage.io/v1alpha1` |
| `kind` | `Template` |
| Field | Value |
| ------------ | ---------------------- |
| `apiVersion` | `backstage.io/v1beta2` |
| `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/).
If you're looking for docs on `v1alpha1` you can find them
[here](../software-templates/legacy)
A template definition describes both the parameters that are rendered in the
frontend part of the scaffolding wizard, and the steps that are executed when
scaffolding that component.
Descriptor files for this kind may look as follows.
```yaml
apiVersion: backstage.io/v1alpha1
apiVersion: backstage.io/v1beta2
kind: Template
# some metadata about the template itself
metadata:
name: react-ssr-template
title: React SSR Template
description:
Next.js application skeleton for creating isomorphic web applications.
tags:
- recommended
- react
name: v1beta2-demo
title: Test Action template
description: scaffolder v1beta2 template demo
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
owner: backstage/techdocs-core
type: service
# these are the steps which are rendered in the frontend with the form input
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
- title: Choose a location
required:
- repoUrl
properties:
repoUrl:
title: Repository Location
type: string
ui:field: RepoUrlPicker
ui:options:
allowedHosts:
- github.com
# here's the steps that are executed in series in the scaffolder backend
steps:
- id: fetch-base
name: Fetch Base
action: fetch:cookiecutter
input:
url: ./template
values:
name: '{{ parameters.name }}'
- id: fetch-docs
name: Fetch Docs
action: fetch:plain
input:
targetPath: ./community
url: https://github.com/backstage/community/tree/main/backstage-community-sessions
- id: publish
name: Publish
action: publish:github
input:
allowedHosts: ['github.com']
description: 'This is {{ parameters.name }}'
repoUrl: '{{ parameters.repoUrl }}'
- id: register
name: Register
action: catalog:register
input:
repoContentsUrl: '{{ steps.publish.output.repoContentsUrl }}'
catalogInfoPath: '/catalog-info.yaml'
```
In addition to the [common envelope metadata](#common-to-all-kinds-the-metadata)
@@ -572,7 +613,7 @@ shape, this kind has the following structure.
### `apiVersion` and `kind` [required]
Exactly equal to `backstage.io/v1alpha1` and `Template`, respectively.
Exactly equal to `backstage.io/v1beta2` and `Template`, respectively.
### `metadata.title` [required]
@@ -605,31 +646,43 @@ The current set of well-known and common values for this field is:
- `website` - a website
- `library` - a software library, such as an npm module or a Java library
### `spec.templater` [required]
### `spec.parameters` [required]
The templating library that is supported by the template skeleton as a string,
e.g `cookiecutter`.
You can find out more about the `parameters` key
[here](../software-templates/writing-templates.md)
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.
### `spec.steps` [optional]
This key will be used to identify the correct templater which is registered into
the `TemplatersBuilder`.
You can find out more about the `steps` key
[here](../software-templates/writing-templates.md)
The values which are available by default are:
## Kind: APIis `JSONSchema` with some extra goodies for styling what it might
- `cookiecutter` - [cookiecutter](https://github.com/cookiecutter/cookiecutter).
look like in the frontend. For these steps we rely very heavily on this library:
https://github.com/rjsf-team/react-jsonschema-form. They have some great docs
too here: https://react-jsonschema-form.readthedocs.io/ and a playground where
you can play around with some examples here
https://rjsf-team.github.io/react-jsonschema-form
### `spec.path` [optional]
For example here is a simple parameters step
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`.
```yaml
- 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
```
This will set the `cwd` when running the templater to the folder path that you
specify relative to the `template.yaml` definition.
You can find out more [here](../software-templates/writing-templates.md)
This is also particularly useful when you have multiple template definitions in
the same repository but only a single `template.yaml` registered in backstage.
### `spec.steps` [optional]
## Kind: API
@@ -4,49 +4,80 @@ title: Adding your own Templates
description: Documentation on Adding your own Templates
---
Templates are stored in the **Service Catalog** under a kind `Template`. The
Templates are stored in the **Software Catalog** under a kind `Template`. The
minimum that is needed to define a template is a `template.yaml` file, but it
would be good to also have some files in there that can be templated in.
A simple `template.yaml` definition might look something like this:
```yaml
apiVersion: backstage.io/v1alpha1
apiVersion: backstage.io/v1beta2
kind: Template
# some metadata about the template itself
metadata:
# unique name per namespace for the template
name: react-ssr-template
# title of the template
title: React SSR Template
# a description of the template
description:
Next.js application skeleton for creating isomorphic web applications.
# some tags to display in the frontend
tags:
- recommended
- react
name: v1beta2-demo
title: Test Action template
description: scaffolder v1beta2 template demo
spec:
# which templater key to use in the templaters builder
templater: cookiecutter
# what does this template create
type: website
# if the template is not in the current directory where this definition is kept then specify
path: './template'
# the schema for the form which is displayed in the frontend.
# should follow JSON schema for forms: https://jsonforms.io/
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
owner: backstage/techdocs-core
type: service
# these are the steps which are rendered in the frontend with the form input
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
- title: Choose a location
required:
- repoUrl
properties:
repoUrl:
title: Repository Location
type: string
ui:field: RepoUrlPicker
ui:options:
allowedHosts:
- github.com
# here's the steps that are executed in series in the scaffolder backend
steps:
- id: fetch-base
name: Fetch Base
action: fetch:cookiecutter
input:
url: ./template
values:
name: '{{ parameters.name }}'
- id: fetch-docs
name: Fetch Docs
action: fetch:plain
input:
targetPath: ./community
url: https://github.com/backstage/community/tree/main/backstage-community-sessions
- id: publish
name: Publish
action: publish:github
input:
allowedHosts: ['github.com']
description: 'This is {{ parameters.name }}'
repoUrl: '{{ parameters.repoUrl }}'
- id: register
name: Register
action: catalog:register
input:
repoContentsUrl: '{{ steps.publish.output.repoContentsUrl }}'
catalogInfoPath: '/catalog-info.yaml'
```
[Template Entity](../software-catalog/descriptor-format.md#kind-template)
@@ -55,14 +86,6 @@ contains more information about the required fields.
Once we have a `template.yaml` ready, we can then add it to the service catalog
for use by the scaffolder.
_NOTE_: When the `publish` step is completed, it is currently assumed by the
scaffolder that the final repository should contain a `catalog-info.yaml` in
order to register this with the Catalog in Backstage.
Currently the catalog supports loading definitions from GitHub + Local Files. To
load from other places, not only will there need to be another preparer, but the
support to load the location will also need to be added to the Catalog.
You can add the template files to the catalog through
[static location configuration](../software-catalog/configuration.md#static-location-configuration),
for example:
@@ -76,52 +99,8 @@ catalog:
- allow: [Template]
```
Templates can also be added by posting the to the catalog directly. Note that if
you're doing this, you need to configure the catalog to allow template entities
to be ingested from any source, for example:
Or you can add the template using the `catalog-import` plugin, which unless
configured differently should be running on `/catalog-import`.
```yaml
catalog:
rules:
- allow: [Component, API, Template]
```
For loading from a file, the following command should work when the backend is
running:
```sh
curl \
--location \
--request POST 'localhost:7000/api/catalog/locations' \
--header 'Content-Type: application/json' \
--data-raw "{\"type\": \"file\", \"target\": \"${YOUR PATH HERE}/template.yaml\"}"
```
If loading from a Git location, you can run the following
```sh
curl \
--location \
--request POST 'localhost:7000/api/catalog/locations' \
--header 'Content-Type: application/json' \
--data-raw "{\"type\": \"github\", \"target\": \"https://${GITHUB URL}/${YOUR GITHUB ORG/REPO}/blob/master/${PATH TO FOLDER}/template.yaml\"}"
```
This should then have been added the catalog, and be listed under the create
page at http://localhost:3000/create.
The `type` field which is chosen in the request to add the `template.yaml` to
the Service Catalog here, will become the `PreparerKey` which will be used to
select the `Preparer` when creating a job.
### Adding form values in the Scaffolder Wizard
The `spec.schema` property in the
[Template Entity](../software-catalog/descriptor-format.md#kind-template) is a
`yaml` version of the JSON Form Schema standard.
Here you can define the key/values and then the wizard will convert this to a
form for the user to fill in when your template is selected.
You can find out much more about the standard and how to use it here:
https://jsonforms.io
For information about writing your own templates, you can check out the docs
[here](./writing-templates)
@@ -99,6 +99,7 @@ export default async function createPlugin({
logger,
config,
database,
reader,
}: PluginEnvironment) {
const cookiecutterTemplater = new CookieCutter();
const craTemplater = new CreateReactAppTemplater();
@@ -124,6 +125,7 @@ export default async function createPlugin({
dockerClient,
database,
catalogClient,
reader,
});
}
```
@@ -136,10 +138,11 @@ import scaffolder from './plugins/scaffolder';
const scaffolderEnv = useHotMemoize(module, () => createEnv('scaffolder'));
const service = createServiceBuilder(module)
.loadConfig(configReader)
/** several different routers */
.addRouter('/scaffolder', await scaffolder(scaffolderEnv));
const apiRouter = Router();
/* several router .use calls */
/* add this line */
apiRouter.use('/scaffolder', await scaffolder(scaffolderEnv));
```
### Adding Templates
@@ -170,14 +173,10 @@ catalog:
### Runtime Dependencies / Configuration
For the scaffolder backend plugin to function, it needs a GitHub access token,
and access to a running Docker daemon. You can create a GitHub access token
[here](https://github.com/settings/tokens/new), select `repo` scope only. Full
docs on creating private GitHub access tokens is available
[here](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token).
Note that the need for private GitHub access tokens will be replaced with GitHub
Apps integration further down the line by using the existing `integrations`
config.
For the scaffolder backend plugin to function, you'll need to setup the
integrations config in your `app-config.yaml`.
You can find help for different providers below.
> Note: Some of this configuration may already be set up as part of your
> `app-config.yaml`. We're moving away from the duplicated config for
@@ -220,6 +219,32 @@ integrations:
$env: GITLAB_TOKEN
```
#### BitBucket
For Bitbucket there are two authentication methods supported. Either `token` or
a combination of `appPassword` and `username`. It looks like either of the
following:
```yaml
integrations:
bitbucket:
- host: bitbucket.org
token:
$env: BITBUCKET_TOKEN
```
or
```yaml
integrations:
bitbucket:
- host: bitbucket.org
appPassword:
$env: BITBUCKET_APP_PASSWORD
username:
$env: BITBUCKET_USERNAME
```
#### Azure DevOps
For Azure DevOps we support both the preparer and publisher stage with the
+118
View File
@@ -0,0 +1,118 @@
---
id: template-legacy
title: Writing Templates (Legacy)
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.