diff --git a/docs/features/software-catalog/descriptor-format.md b/docs/features/software-catalog/descriptor-format.md index a9fc17ce75..926cfe5b9c 100644 --- a/docs/features/software-catalog/descriptor-format.md +++ b/docs/features/software-catalog/descriptor-format.md @@ -311,3 +311,114 @@ component, but there will always be one ultimate owner. Apart from being a string, the software catalog leaves the format of this field open to implementers to choose. Most commonly, it is set to the ID or email of a group of people in an organizational structure. + +## + +Describes the following entity kind: + +| Field | Value | +| -------------------- | ----------------------- | +| `apiVersion` | `backstage.io/v1alpha1` | +| `Kind: Templatekind` | `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 organisation 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/adding-templates.md b/docs/features/software-templates/adding-templates.md index e69de29bb2..e929ec4a97 100644 --- a/docs/features/software-templates/adding-templates.md +++ b/docs/features/software-templates/adding-templates.md @@ -0,0 +1,102 @@ +# Adding your own Templates + +Templates are stored in the **Service Catalog** under a kind `Template`. The +minimum that the a template skeleton needs is a `template.yaml` 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 +kind: Template +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 +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 specfiy + 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 +``` + +[Template Entity](../software-catalog/descriptor-format.md#kind-template) +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. + +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. + +For loading from a file the following command should work when the backend is +running: + +```sh +curl \ + --location \ + --request POST 'localhost:7000/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/catalog/locations' \ + --header 'Content-Type: application/json' \ + --data-raw "{\"type\": \"github\", \"target\": \"https://${YOUR GITHUB REPO}blob/master/${PATH TO FOLDER}/template.yaml\"}" +``` + +This should then have added the catalog, and also should now be listed under the +create page at http://localhost:3000/create. + +Alternatively, if you want to get setup with some mock templates that are +already provided for you, you can run the following to load those templates: + +``` +yarn lerna run mock-data +``` + +The `type` field which is chosen in the request to add the `template.yaml` to +the Service Catalog here, will be come 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 diff --git a/docs/features/software-templates/assets/added-to-the-catalog-list.png b/docs/features/software-templates/assets/added-to-the-catalog-list.png new file mode 100644 index 0000000000..4b544e51c1 Binary files /dev/null and b/docs/features/software-templates/assets/added-to-the-catalog-list.png differ diff --git a/docs/features/software-templates/assets/complete.png b/docs/features/software-templates/assets/complete.png new file mode 100644 index 0000000000..eee14fae0e Binary files /dev/null and b/docs/features/software-templates/assets/complete.png differ diff --git a/docs/features/software-templates/assets/create.png b/docs/features/software-templates/assets/create.png new file mode 100644 index 0000000000..8a2e92b9f4 Binary files /dev/null and b/docs/features/software-templates/assets/create.png differ diff --git a/docs/features/software-templates/assets/failed.png b/docs/features/software-templates/assets/failed.png new file mode 100644 index 0000000000..bca8c72d6a Binary files /dev/null and b/docs/features/software-templates/assets/failed.png differ diff --git a/docs/features/software-templates/assets/go-to-catalog.png b/docs/features/software-templates/assets/go-to-catalog.png new file mode 100644 index 0000000000..ae16230a02 Binary files /dev/null and b/docs/features/software-templates/assets/go-to-catalog.png differ diff --git a/docs/features/software-templates/assets/running.png b/docs/features/software-templates/assets/running.png new file mode 100644 index 0000000000..208376e059 Binary files /dev/null and b/docs/features/software-templates/assets/running.png differ diff --git a/docs/features/software-templates/assets/template-picked-2.png b/docs/features/software-templates/assets/template-picked-2.png new file mode 100644 index 0000000000..685e356ee8 Binary files /dev/null and b/docs/features/software-templates/assets/template-picked-2.png differ diff --git a/docs/features/software-templates/assets/template-picked.png b/docs/features/software-templates/assets/template-picked.png new file mode 100644 index 0000000000..1094acec4a Binary files /dev/null and b/docs/features/software-templates/assets/template-picked.png differ diff --git a/docs/features/software-templates/configure-templates.md b/docs/features/software-templates/configure-templates.md deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/features/software-templates/extending/create-your-own-preparer.md b/docs/features/software-templates/extending/create-your-own-preparer.md new file mode 100644 index 0000000000..4e45bef535 --- /dev/null +++ b/docs/features/software-templates/extending/create-your-own-preparer.md @@ -0,0 +1,97 @@ +# Create your own Preparer + +Preparers are responsible for reading the location of the definition of a +[Template Entity](../../software-catalog/descriptor-format.md#kind-template) and +making a temporary folder with the contents of the selected skeleton. + +Currently, we provide two different providers that can parse two different +location protocols: + +- `file://` +- `github://` + +These two are added to the `PreparersBuilder` and then passed into the +`createRouter` function of the `@spotify/plugin-scaffolder-backend` + +An full example backend can be found +[here](https://github.com/spotify/backstage/blob/d91c10f654475a60829fa33a5c81018e517a319a/packages/backend/src/plugins/scaffolder.ts), +but it looks something like the following + +```ts +import { + createRouter, + FilePreparer, + GithubPreparer, + Preparers, +} from '@backstage/plugin-scaffolder-backend'; +import type { PluginEnvironment } from '../types'; + +export default async function createPlugin({ logger }: PluginEnvironment) { + const preparers = new Preparers(); + + const filePreparer = new FilePreparer(); + const githubPreparer = new GithubPreparer(); + + preparers.register('file', filePreparer); + preparers.register('github', githubPreparer); + + return await createRouter({ + preparers, + templaters, + logger, + }); +} +``` + +As you can see in the above code, a `PreparerBuilder` is created, and then two +of the `preparers` are registered with the different protocols that they accept. + +The `protocol` is set on the +[Template Entity](../../software-catalog/descriptor-format.md#kind-template) +when added to the service catalog. You can see more about this `PreparerKey` +here in [Register your own template](../adding-templates.md) + +**note:** Currently the catalog supports loading definitions from Github + Local +Files, which translate into the two `PreparerKeys` `file` and `github`. 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. + +### Creating your own Preparer to add to the `PreparerBuilder` + +All preparers need to implement the `PreparerBase` type. + +That type looks like the following: + +```ts +export type PreparerBase = { + prepare( + template: TemplateEntityV1alpha1, + opts: { logger: Logger }, + ): Promise; +}; +``` + +The `prepare` function will be given the +[Template Entity](../../software-catalog/descriptor-format.md#kind-template) +along with the source of where the `template.yaml` was loaded from under the +`metedata.annotations.managed-by-location` property. + +Now it's up to you to implement a function which can go and fetch the skeleton +and put the contents into a temporary directory and return that directory path. + +Some good examples exist here: + +- https://github.com/spotify/backstage/blob/master/plugins/scaffolder-backend/src/scaffolder/stages/prepare/file.ts +- https://github.com/spotify/backstage/blob/master/plugins/scaffolder-backend/src/scaffolder/stages/prepare/github.ts + +### Registerinng your own Preparer + +You can register the preparer that you have created with the `PreparerBuilder` +by using the `PreparerKey` from the Catalog, for example like this: + +```ts +const preparers = new Preparers(); +preparers.register('gcs', new GoogleCloudStoragePreparer()); +``` + +And then pass this in to the `createRouter` function. diff --git a/docs/features/software-templates/extending/create-your-own-publisher.md b/docs/features/software-templates/extending/create-your-own-publisher.md new file mode 100644 index 0000000000..8baf604e01 --- /dev/null +++ b/docs/features/software-templates/extending/create-your-own-publisher.md @@ -0,0 +1,92 @@ +# Create your own Publisher + +Publishers are responsible for pushing and storing the templated skeleton after +the values have been templated by the `Templater`. See +[Create your own templater](./create-your-own-templater.md) for more info. + +They recieve a directory or location where the templater has sucessfully run on, +and is now ready to store somewhere. They also get given some other options +which are sent from the frontend, such as the `storePath` which is a string of +where the frontend thinks we should save this templated folder. + +Currently we provide the following `publishers`: + +- `github` + +This publisher is passed through to the `createRouter` function of the +`@spotify/plugin-scaffolder-backend`. Currently only one publisher is supported, +but PR's are always welcome. + +An full example backend can be found +[here](https://github.com/spotify/backstage/blob/d91c10f654475a60829fa33a5c81018e517a319a/packages/backend/src/plugins/scaffolder.ts), +but it looks something like the following + +```ts +import { + createRouter, + GithubPublisher, +} from '@backstage/plugin-scaffolder-backend'; +import { Octokit } from '@octokit/rest'; +import type { PluginEnvironment } from '../types'; + +export default async function createPlugin({ logger }: PluginEnvironment) { + const githubClient = new Octokit({ auth: process.env.GITHUB_ACCESS_TOKEN }); + const publisher = new GithubPublisher({ client: githubClient }); + + return await createRouter({ + publisher, + logger, + }); +} +``` + +The publisher will always be called with the location from the selected +`Preparer`. + +### Create your own Publisher and register it with the Scaffolder + +All `publishers` need to implement the `PublisherBase` type. + +That type looks like the following: + +```ts +export type PublisherBase = { + publish(opts: { + entity: TemplateEntityV1alpha1; + values: RequiredTemplateValues & Record; + directory: string; + }): Promise<{ remoteUrl: string }>; +}; +``` + +The `publisher` function will be called with an `options` object which contains +the following: + +- `entity` - the + [Template Entity](../../software-catalog/descriptor-format.md#kind-template) + which is currently being scaffolded +- `values` - a json object which will resemble the `spec.schema` from the + [Template Entity](../../software-catalog/descriptor-format.md#kind-template) + which is defined here under spec.schema`. More info can be found here + [Register your own template](../adding-templates.md#adding-form-values-in-the-scaffolder-wizard) +- `directory` - a string containing the returned path from the `templater`. See + more information here in + [Create your own templater](./create-your-own-templater.md) + +Now it's up to you to implement the `publish` function and return +`{ remoteUrl: string }` which can be used to identify the finished product. + +Some good examples exist here: + +- https://github.com/spotify/backstage/blob/master/plugins/scaffolder-backend/src/scaffolder/stages/publish/github.ts + +### Registering your own Publisher + +Currently, we only support one `publisher` (PR's welcome), but you can register +any single `publisher` with the `createRouter`. + +```ts +return await createRouter({ + publisher: new MyGitlabPublisher(), +}); +``` diff --git a/docs/features/software-templates/extending/create-your-own-templater.md b/docs/features/software-templates/extending/create-your-own-templater.md new file mode 100644 index 0000000000..fd3b7d395f --- /dev/null +++ b/docs/features/software-templates/extending/create-your-own-templater.md @@ -0,0 +1,146 @@ +# Creating your own Templater + +Templaters are responsible for taking the directory path for the skeleton +returned by the preparers, and then executing the templating command on top of +the file and returning the completed template path. This may or may not be the +same directory as the input directory. + +They also recieve additional values from the frontend, which can be used to +interpolate into the skeleton files. + +Currently we provide the following templaters: + +- `cookiecutter` + +This templater is added the `TemplaterBuilder` and then passed into the +`createRouter` function of the `@spotify/plugin-scaffolder-backend` + +An full example backend can be found +[here](https://github.com/spotify/backstage/blob/d91c10f654475a60829fa33a5c81018e517a319a/packages/backend/src/plugins/scaffolder.ts), +but it looks something like the following + +```ts +import { + CookieCutter, + createRouter, + Templaters, +} from '@backstage/plugin-scaffolder-backend'; +import type { PluginEnvironment } from '../types'; + +export default async function createPlugin({ logger }: PluginEnvironment) { + const templaters = new Templaters(); + const cookiecutterTemplater = new CookieCutter(); + templaters.register('cookiecutter', cookiecutterTemplater); + + return await createRouter({ + templaters, + }); +} +``` + +As you can see in the above code a `TemplaterBuilder` is created and the default +`cookiecutter` `templater` is registered under the key `cookicutter`. + +This `TemplaterKey` is used to select the correct templater from the +`spec.templater` in the +[Template Entity](../software-catalog/descriptor-format.md#kind-template). + +If you wish to add a new templater you'll need to register it with the +`TemplaterBuilder`. + +### Creating your own Templater to add to the `TemplaterBuilder` + +All templaters need to implement the `TemplaterBase` type. + +That type looks like the following: + +```ts +export type TemplaterRunOptions = { + directory: string; + values: RequiredTemplateValues & Record; + logStream?: Writable; + dockerClient: Docker; +}; + +export type TemplaterBase = { + run(opts: TemplaterRunOptions): Promise; +}; +``` + +The `run` function will be given a `TemplaterRunOptions` object which is as +follows: + +- `directory`- the skeleton directory returned from the `Preparer`, more info at + [Create your own preparer](./create-your-own-preparer.md). +- `values` - a json object which will resemble the `spec.schema` from the + [Template Entity](../software-catalog/descriptor-format.md#kind-template) + which is defined here under spec.schema`. More info can be found here + [Register your own template](./register-your-own-template.md#adding-form-values-in-the-scaffolder-wizard) +- `logStream` - a stream that you can write to for displaying in the frontend. +- `dockerClient` - a [dockerode](https://github.com/apocas/dockerode) client to + be able to run docker containers. + +_note_ currently the templaters that we provide are basically docker action +containers that are run on top of the skeleton folder. This keeps dependencies +to a minimal for running backstage scaffolder, but you don't /have/ to use +docker. You could create your own templater that spins up an EC2 instance and +downloads the folder and does everything using an AMI if you want. It's entirely +up to you! + +Now it's up to you to implement the `run` function, and then return a +`TemplaterRunResult` which is `{ resultDir: string }`. + +Some good examples exist here: + +- https://github.com/spotify/backstage/blob/master/plugins/scaffolder-backend/src/scaffolder/stages/templater/cookiecutter.ts + +### Registering your own Templater + +If you try to process a +[Template Entity](../../software-catalog/descriptor-format.md#kind-template) +with a new `spec.templater` value, you'll need to register that with the +`TemplaterBuilder`. + +For example let's say you have the following +[Template Entity](../../software-catalog/descriptor-format.md#kind-template): + +```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: handlebars + 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 +``` + +You see that the `spec.templater` is set as `handlebars`, you'll need to +register this with the `TemplaterBuilder` like so: + +```ts +const templaters = new Templaters(); +templaters.register('handlebars', new HandlebarsTemplater()); +``` + +And then pass this in to the `createRouter` function. diff --git a/docs/features/software-templates/extending/index.md b/docs/features/software-templates/extending/index.md new file mode 100644 index 0000000000..a55128c57d --- /dev/null +++ b/docs/features/software-templates/extending/index.md @@ -0,0 +1,87 @@ +## Extending the Scaffolder + +Welcome. Take a seat. You're at the Scaffolder Documentation. + +So - You wanna create stuff inside your company from some prebaked templates? +You're at the right place. + +This guide is gonna take you through how the Scaffolder in Backstage works. +We'll dive into some jargon and run through whats going on in the backend to be +able to create these templates. There's also more guides that you might find +useful at the bottom of this document. At it's core, theres 3 simple stages. + +1. Pick a skeleton +2. Template some variables into the skeleton +3. Send the templated skeleton somewhere + +These three steps are translated to the folllowing stages under the hood in the +scaffolder that you will need to know: + +1. Prepare +2. Template +3. Publish + +Each of these steps can be configured for your own use case, but we provide some +sensible defaults too. + +Lets dive a little deeper into these phases. + +### Glossary and Jargon + +**Preparer** - The preparer is responsible for fetching the skeleton code and +placing it into a directory and then will return that directory. It is +registered with the `Preparers` with a particular type, which is then used in +the router to pick the correct `Preparer` to run for the `Template` entity. + +**Templater** - The templater is responsible for actually running the chosen +templater on top of the previously returned temporary directory from the +**Preprarer**. We advise making these docker containers as it can keep all +dependencies, for example Cookiecutter, self contained and not a dependency on +the host machine. + +**Publisher** - The publisher is responsible for taking the finished directory, +and publishing it to a remote registry. This could be a Git repository or +something similar. Right now, the scaffolder only supports one publishing method +for the entire lifecycle, but it could be configured from the frontend and +passed through to the scaffolder backend. + +### How it works + +The main of the heavy lifting is done in the +[router.ts](https://github.com/spotify/backstage/blob/master/plugins/scaffolder-backend/src/service/router.ts#L93) +file in the `scaffolder-backend` plugin. + +There are 2 routes defined in the router. `POST /v1/jobs` and +`GET /v1/job/:jobId` + +To create a scaffolding job, a JSON object containing the +[Template Entity](../../software-catalog/descriptor-format.md#kind-template) + +additional templating values must be posted as the post body. + +```js +{ + "template": { + "apiVersion": "backstage/v1alpha1", + "kind": "Template", + // more stuff here + }, + "values": { + "component_id": "test", + "description": "somethingelse" + } +} +``` + +The values should represent something that is valid with the `schema` part of +the [Template Entity](../../software-catalog/descriptor-format.md#kind-template) + +Once that has been posted, a job will be setup with different stages. And the +job processor will complete each stage before moving onto the next stage, whilst +collecting logs and mutating the running job. + +Here's some futher reading that you might find useful: + +- [Adding your own Template](../adding-templates.md) +- [Creating your own Templater](./create-your-own-templater.md) +- [Creating your own Publisher](./create-your-own-publisher.md) +- [Creating your own Preparer](./create-your-own-preparer.md) diff --git a/docs/features/software-templates/index.md b/docs/features/software-templates/index.md index e69de29bb2..04ae53accb 100644 --- a/docs/features/software-templates/index.md +++ b/docs/features/software-templates/index.md @@ -0,0 +1,59 @@ +# Software Templates + +The Software Templates part of Backstage is a tool that can help you create +Components inside Backstage. It by default has the ability to load skeletons of +code, template in some variables and then publish the template to some location +like GitHub. + +### Getting Started + +The Software Templates are available under `/create`, and if you've followed +[Getting Started with Backstage](../../getting-started), you should be able to +reach `http://localhost:3000/create`. + +You should get something that looks similar to this: + +![Create Image](./assets/create.png) + +### Choose a template + +When you select a template that you want to create, you'll be taken to the next +page which may or may not look different for each template. Each template can +ask for different input variables, and they are then passed to the templater +internally. + +![Enter some variables](./assets/template-picked.png) + +After filling in these variables, you'll get some more fields to fill out which +are required for backstage usage. The owner, which is a `user` in the backstage +system, and the `storePath` which right now must be a Github Organisation and a +non-existing github repository name in the format `organistaion/reponame`. + +![Enter backstage vars](./assets/template-picked-1.png) + +### Run! + +Once you've entered values and confirmed, you'll then get a modal with live +progress of what is currently happening with the creation of your template. + +![Templating Running](./assets/running.png) + +It shouldn't take too long, and you'll have a success screen! + +![Templating Complete](./assets/complete.png) + +If it fails, you'll be able to click on each section to get the log from the +step that failed which can be helpful to debug. + +![Templating failed](./assets/failed.png) + +### View Component in Catalog + +When it's been created you'll see the `View in Catalog` button, which will take +you to the registered component in the catalog: + +![Catalog](./assets/go-to-catalog.png) + +And then you'll also be able to see it in the Catalog View table + +![Catalog](./assets/added-to-the-catalog-list.png) diff --git a/mkdocs.yml b/mkdocs.yml index 7c5a672636..6015e1c19d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -32,6 +32,11 @@ nav: - Overview: 'features/software-templates/index.md' - Configure templates: 'features/software-templates/configure-templates.md' - Adding templates: 'features/software-templates/adding-templates.md' + - Extending the Scaffolder: + - Overview: 'features/software-templates/extending/index.md' + - Create your own Templater: 'features/software-templates/extending/create-your-own-templater.md' + - Create your own Publisher: 'features/software-templates/extending/create-your-own-publisher.md' + - Create your own Preparer: 'features/software-templates/extending/create-your-own-preparer.md' - Docs-like-code: - Overview: 'features/techdocs/README.md' - Getting Started: 'features/techdocs/getting-started.md' diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/template.yaml b/plugins/scaffolder-backend/sample-templates/react-ssr-template/template.yaml index 363d488448..71f75c7695 100644 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/template.yaml +++ b/plugins/scaffolder-backend/sample-templates/react-ssr-template/template.yaml @@ -8,6 +8,7 @@ metadata: - Recommended - React spec: + owner: web@example.com templater: cookiecutter type: website path: '.' diff --git a/plugins/scaffolder-backend/sample-templates/springboot-template/template.yaml b/plugins/scaffolder-backend/sample-templates/springboot-template/template.yaml index 19ec7935d9..0fefce37b9 100644 --- a/plugins/scaffolder-backend/sample-templates/springboot-template/template.yaml +++ b/plugins/scaffolder-backend/sample-templates/springboot-template/template.yaml @@ -8,6 +8,7 @@ metadata: - Recommended - Java spec: + owner: service@example.com templater: cookiecutter type: service path: '.' diff --git a/plugins/scaffolder-backend/src/scaffolder/stages/publish/github.ts b/plugins/scaffolder-backend/src/scaffolder/stages/publish/github.ts index eba7def9af..5fd64d69fc 100644 --- a/plugins/scaffolder-backend/src/scaffolder/stages/publish/github.ts +++ b/plugins/scaffolder-backend/src/scaffolder/stages/publish/github.ts @@ -14,14 +14,14 @@ * limitations under the License. */ -import { Publisher } from './types'; +import { PublisherBase } from './types'; import { Octokit } from '@octokit/rest'; import { JsonValue } from '@backstage/config'; import { RequiredTemplateValues } from '../templater'; import { Repository, Remote, Signature, Cred } from 'nodegit'; -export class GithubPublisher implements Publisher { +export class GithubPublisher implements PublisherBase { private client: Octokit; constructor({ client }: { client: Octokit }) { this.client = client; diff --git a/plugins/scaffolder-backend/src/scaffolder/stages/publish/types.ts b/plugins/scaffolder-backend/src/scaffolder/stages/publish/types.ts index 17b357a4ef..5d4e9dd521 100644 --- a/plugins/scaffolder-backend/src/scaffolder/stages/publish/types.ts +++ b/plugins/scaffolder-backend/src/scaffolder/stages/publish/types.ts @@ -21,7 +21,7 @@ import { JsonValue } from '@backstage/config'; * Publisher is in charge of taking a folder created by * the templater, and pushing it to a remote storage */ -export type Publisher = { +export type PublisherBase = { /** * * @param opts object containing the template entity from the service diff --git a/plugins/scaffolder-backend/src/service/router.ts b/plugins/scaffolder-backend/src/service/router.ts index 225662142f..fcfd5765a1 100644 --- a/plugins/scaffolder-backend/src/service/router.ts +++ b/plugins/scaffolder-backend/src/service/router.ts @@ -26,13 +26,13 @@ import { RequiredTemplateValues, StageContext, TemplaterBuilder, - Publisher, + PublisherBase, } from '../scaffolder'; export interface RouterOptions { preparers: PreparerBuilder; templaters: TemplaterBuilder; - publisher: Publisher; + publisher: PublisherBase; logger: Logger; dockerClient: Docker; @@ -55,18 +55,6 @@ export async function createRouter( const jobProcessor = new JobProcessor(); router - .get('/v1/job/:jobId/stage/:index/log', ({ params }, res) => { - const job = jobProcessor.get(params.jobId); - - if (!job) { - res.status(404).send({ error: 'job not found' }); - return; - } - - const { log } = job.stages[Number(params.index)] ?? { log: [] }; - - res.send(log.join('')); - }) .get('/v1/job/:jobId', ({ params }, res) => { const job = jobProcessor.get(params.jobId); @@ -126,7 +114,7 @@ export async function createRouter( { name: 'Publish template', handler: async (ctx: StageContext<{ resultDir: string }>) => { - ctx.logger.info('Should not store the template'); + ctx.logger.info('Will now store the template'); const { remoteUrl } = await publisher.publish({ entity: ctx.entity, values: ctx.values,