Merge branch 'master' into atlassian-auth

Signed-off-by: Daniel Deloff <44780793+rv-ddeloff@users.noreply.github.com>
This commit is contained in:
Daniel Deloff
2021-10-20 22:07:38 -04:00
483 changed files with 11199 additions and 3918 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-auth-backend': patch
---
Require that audience URLs for Okta authentication start with https
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/core-components': patch
---
Switched to relying on the built-in support for async loading in `react-syntax-highlighter`. This should provide further improvements to async rendering and lazy loading, and avoid test flakiness that was happening because of the significant number or resources being loaded in lazily all at once.
+15
View File
@@ -0,0 +1,15 @@
---
'@backstage/create-app': patch
---
Removed the included `jest` configuration from the root `package.json` as the `transformModules` option no longer exists.
To apply this change to an existing app, make the follow change to the root `package.json`:
```diff
- "jest": {
- "transformModules": [
- "@asyncapi/react-component"
- ]
- }
```
-8
View File
@@ -1,8 +0,0 @@
---
'@backstage/plugin-auth-backend': patch
---
AWS-ALB: update provider to the latest changes described [here](https://backstage.io/docs/auth/identity-resolver).
This removes the `ExperimentalIdentityResolver` type in favor of `SignInResolver` and `AuthHandler`.
The AWS ALB provider can now be configured in the same way as the Google provider in the example.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-auth-backend': patch
---
Fix a bug preventing an access token to be refreshed a second time with the GitHub provider.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/config-loader': patch
---
Configuration schema errors are now filtered using the provided visibility option. This means that schema errors due to missing backend configuration will no longer break frontend builds.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-api-docs': patch
---
Bump `swagger-ui-react` to `^4.0.0-rc.3`.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/techdocs-common': patch
---
Use docs/README.md or README.md as fallback if docs/index.md is missing
+9
View File
@@ -0,0 +1,9 @@
---
'@backstage/plugin-techdocs': patch
---
Add `<EntityListDocsGrid>` as an alternative to `<EntityListDocsTable>` that
shows a grid of card instead of table.
Extend `<DocsCardGrid>` to display the entity title of the entity instead of the
name if available.
+6
View File
@@ -0,0 +1,6 @@
---
'@backstage/plugin-techdocs': patch
'@backstage/plugin-techdocs-backend': patch
---
Display entity title (if defined) in titles of TechDocs search results
-19
View File
@@ -1,19 +0,0 @@
---
'@backstage/create-app': patch
---
The scaffolder plugin has just released the beta 3 version of software templates, which replaces the handlebars templating syntax. As part of this change, the template entity schema is no longer included in the core catalog-model as with previous versions. The decoupling of the template entities version will allow us to more easily make updates in the future.
In order to use the new beta 3 templates, the following changes are **required** for any existing installation, inside `packages/backend/src/plugins/catalog.ts`:
```diff
+import { ScaffolderEntitiesProcessor } from '@backstage/plugin-scaffolder-backend';
...
const builder = await CatalogBuilder.create(env);
+ builder.addProcessor(new ScaffolderEntitiesProcessor());
const { processingEngine, router } = await builder.build();
```
If you're interested in learning more about creating custom kinds, please check out the [extending the model](https://backstage.io/docs/features/software-catalog/extending-the-model) documentation.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-fossa': patch
---
Add `entitiesFilter` option to `FossaPage` to filter entities displayed in the table.
-7
View File
@@ -1,7 +0,0 @@
---
'@backstage/core-app-api': patch
'@backstage/core-components': patch
'@backstage/theme': patch
---
Internal refactor to avoid importing all of `@material-ui/core`.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-backend': patch
---
Take CatalogParser in account when processing file locations.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/core-components': patch
---
update the null check to use the optional chaining operator in case of non-null assertion operator is not working in function extractInitials(values: string)
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-graphiql': patch
---
Add experimental `experimentalInstallationRecipe` to `package.json`.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-backend': patch
---
Minor rearrangement of `Stitcher` to clarify the scope of one stitch round
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/core-components': patch
---
Resolve a warning in `<Button>` related to not using `React.forwardRef`.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/cli': patch
---
add a --from <location> option to the plugin install command
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-sentry': patch
---
fix: parameter name on call to sentry api
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-catalog': patch
---
Support `material-ui` overrides in SystemDiagramCard and EmptityLinksEmptyState components
-15
View File
@@ -1,15 +0,0 @@
---
'@backstage/plugin-home': patch
---
Adds a `<WelcomeTitle>` component that shows a playful greeting on the home page.
To use it, pass it to the home page header:
```typescript
<Page themeId="home">
<Header title={<WelcomeTitle />} pageTitleOverride="Home">
<HomepageTimer />
</Header>
</Page>
```
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-api-docs': patch
---
Remove unused dependency on material-icons/font
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-user-settings': patch
---
Align grid height
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/core-components': patch
---
Fixed invalid wrap in DismissableBanner component
-6
View File
@@ -1,6 +0,0 @@
---
'@backstage/core-components': minor
'@backstage/plugin-catalog-graph': minor
---
Add documentation and more type safety around DependencyGraph
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-common': patch
---
Add "rate limit exceeded" to error from GithubUrlReader if that is the cause of a read failure
-9
View File
@@ -1,9 +0,0 @@
---
'@backstage/plugin-catalog-backend': minor
---
This continues the deprecation of classes used by the legacy catalog engine. New deprecations can be viewed in this [PR](https://github.com/backstage/backstage/pull/7500) or in the API reference documentation.
The `batchAddOrUpdateEntities` method of the `EntitiesCatalog` interface has been marked as optional and is being deprecated. It is still implemented and required to be implemented by the legacy catalog classes, but was never implemented in the new catalog.
This change is only relevant if you are consuming the `EntitiesCatalog` interface directly, in which case you will get a type error that you need to resolve. It can otherwise be ignored.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-catalog-backend': patch
---
Fixes a bug in the catalog where entities were not being marked as orphaned.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/core-components': patch
---
Fix search in Firefox. When the search was performed by pressing enter, the query parameter was first set but then reverted back.
-11
View File
@@ -1,11 +0,0 @@
---
'@backstage/core-components': patch
---
Change the Table search field placeholder to "Filter" and change icon accordingly
We had feedback that users expected the catalog table search field to have more sophisticated behaviour
than simple filtering. This change sets the search field placeholder to read "Filter"
to avoid confusion with the search feature. The icon is updated to match. This change is applied
generally in core-components so this change is made consistently across the app given the search
field is present on all pages via the sidebar.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/cli': patch
---
Bump sucrase to version 3.20.2
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-api-docs': patch
---
Add actions props to the ApiExplorerPage
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-auth-backend': patch
---
Added extra configuration parameters for active directory file system identity
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/cli': patch
---
Add semicolon in template to make prettier happy
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-azure-devops-backend': patch
---
Updates function for mapping RepoBuilds to handle undefined properties
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-code-coverage-backend': patch
---
check for existence of lines property in files
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-graph': patch
---
Capture analytics events for clicks in the graph.
+14
View File
@@ -0,0 +1,14 @@
---
'@backstage/create-app': minor
---
Removed `@backstage/plugin-welcome`, no new updates to the packages will be
published in the future.
The welcome plugin was used by early alpha versions of Backstage, but today only
contained a simple page with welcome instructions. It was superseded by
`@backstage/plugin-home` which can be used to build a homepage customized to the
needs of your organization.
If it's still used in your app, remove the dependency from your `package.json`
as well as left over code.
+7
View File
@@ -0,0 +1,7 @@
---
'@backstage/errors': patch
---
Two new helpers have been added that make it easier to migrate to considering thrown errors to be of the type `unknown` in TypeScript. The helpers are `assertError` and `isError`, and can be called to make sure that an unknown value conforms to the shape of an `ErrorLike` object. The `assertError` function is a type-guard that throws in the case of a mismatch, while `isError` returns false.
A new error constructor has also been added, `ForwardedError`, which can be used to add context to a forwarded error. It requires both a message and a cause, and inherits the `name` property from the `cause`.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-jenkins': patch
---
Sort Jenkins build by timestamp in `CITable`
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-search': patch
---
SearchBar component to accept optional placeholder prop
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-git-release-manager': patch
---
Minor internal type improvement
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/core-components': minor
---
The syntax highlighting library used by the `CodeSnippet` component is now lazy loaded. This most likely has no effect on existing code, but may break tests as the content of the `CodeSnippet` is now rendered asynchronously.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-catalog-backend': patch
---
This change refactors the internal package structure to remove the `next` catalog folder that was used during the implementation and testing phase of the new catalog engine. The implementation is now the default and is therefore restructured to no longer be packaged under `next/`. This refactor does not change catalog imports from other parts of the project.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/cli': patch
---
Bump mini-css-extract-plugin to v2
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/cli': patch
---
Update default backend ESLint configuration to allow usage of `__dirname` in tests.
-7
View File
@@ -1,7 +0,0 @@
---
'@backstage/cli': patch
---
Add an experimental `install <plugin>` command.
Given a `pluginId`, the command looks for NPM packages matching `@backstage/plugin-{pluginId}` or `backstage-plugin-{pluginId}` or `{pluginId}`. It looks for the `experimentalInstallationRecipe` in their `package.json` for the steps of installation. Detailed documentation and API Spec to follow (and to be decided as well).
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-azure-devops-backend': patch
---
Expands the Azure DevOps backend plugin to provide pull request data to be used by the front end plugin
@@ -0,0 +1,5 @@
---
'@backstage/plugin-techdocs': patch
---
Only replace the shadow dom if the content is changed to avoid a flickering UI.
+22
View File
@@ -0,0 +1,22 @@
---
'@backstage/backend-common': patch
'@backstage/cli': patch
'@backstage/config-loader': patch
'@backstage/core-app-api': patch
'@backstage/core-components': patch
'@backstage/core-plugin-api': patch
'@backstage/create-app': patch
'@backstage/techdocs-common': patch
'@backstage/plugin-auth-backend': patch
'@backstage/plugin-catalog': patch
'@backstage/plugin-catalog-backend': patch
'@backstage/plugin-catalog-backend-module-ldap': patch
'@backstage/plugin-catalog-import': patch
'@backstage/plugin-catalog-react': patch
'@backstage/plugin-code-coverage-backend': patch
'@backstage/plugin-kubernetes-backend': patch
'@backstage/plugin-scaffolder-backend': patch
'@backstage/plugin-techdocs-backend': patch
---
Internal updates to apply more strict checks to throw errors.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-backend': patch
---
Use entity title (if defined) as title of documents indexed by `DefaultCatalogCollator`
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-home': patch
---
Fix `<ComponentTabs>` to display only the selected tab, not the other way around.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/catalog-model': patch
---
Improved documentation for exported symbols.
-6
View File
@@ -1,6 +0,0 @@
---
'@backstage/plugin-kubernetes-backend': patch
'@backstage/plugin-kubernetes': patch
---
Refactor kubernetes fetcher to reduce boilerplate code
-37
View File
@@ -1,37 +0,0 @@
---
'@backstage/plugin-home': patch
---
Added HeaderWorldClock to the Home plugin which is a copy of the HomepageTimer from core-components that has been updated to use props over static config from app-config.yaml. To use HeaderWorldClock you'll need to create an array of ClockConfig like this:
```ts
const clockConfigs: ClockConfig[] = [
{
label: 'NYC',
timeZone: 'America/New_York',
},
{
label: 'UTC',
timeZone: 'UTC',
},
{
label: 'STO',
timeZone: 'Europe/Stockholm',
},
{
label: 'TYO',
timeZone: 'Asia/Tokyo',
},
];
```
Then you can pass `clockConfigs` into the HeaderWorldClock like this:
```ts
<Page themeId="home">
<Header title="Home">
<HeaderWorldClock clockConfigs={clockConfigs} />
</Header>
<Content>...</Content>
</Page>
```
+15
View File
@@ -0,0 +1,15 @@
---
'@backstage/cli': minor
---
The Jest configuration that's included with the Backstage CLI has received several changes.
As a part of migrating to more widespread usage of ESM modules, the default configuration now transforms all source files everywhere, including those within `node_modules`. Due to this change the existing `transformModules` option has been removed and will be ignored. There is also a list of known packages that do not require transforms in the CLI, which will evolve over time. If needed there will also be an option to add packages to this list in the future, but it is not included yet to avoid clutter.
To counteract the slowdown of the additional transforms that have been introduced, the default configuration has also been reworked to enable caching across different packages. Previously each package in a Backstage monorepo would have its own isolated Jest cache, but it is now shared between packages that have a similar enough Jest configuration.
Another change that will speed up test execution is that the transformer for `.esm.js` files has been switched. It used to be an ESM transformer based on Babel, but it is also done by sucrase now since it is significantly faster.
The changes above are not strictly breaking as all tests should still work. It may however cause excessive slowdowns in projects that have configured custom transforms in the `jest` field within `package.json` files. In this case it is either best to consider removing the custom transforms, or overriding the `transformIgnorePatterns` to instead use Jest's default `'/node_modules/'` pattern.
This change also removes the `@backstage/cli/config/jestEsmTransform.js` transform, which can be replaced by using the `@backstage/cli/config/sucraseEsmTransform.js` transform instead.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-catalog-react': patch
---
Support `material-ui` overrides in plugin-catalog-react components
-6
View File
@@ -1,6 +0,0 @@
---
'@backstage/plugin-catalog': patch
'@backstage/plugin-catalog-react': patch
---
added sorting in entity `Name` column by `metadata.title` if present
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/core-components': patch
---
Deprecated HomepageTimer in favor of HeaderWorldClock which is found in the [home plugin](https://github.com/backstage/backstage/tree/master/plugins/home)
-25
View File
@@ -1,25 +0,0 @@
---
'@backstage/plugin-kubernetes-backend': patch
---
Enable customization of services used by the kubernetes backend plugin
The createRouter function has been deprecated in favor of a KubernetesBuilder object.
Here's how you should upgrade your projects when configuring the Kubernetes backend plugin.
in your `packages/backend/src/plugins/kubernetes.ts` file for instance:
```typescript
import { KubernetesBuilder } from '@backstage/plugin-kubernetes-backend';
import { PluginEnvironment } from '../types';
export default async function createPlugin({
logger,
config,
}: PluginEnvironment) {
const { router } = await KubernetesBuilder.createBuilder({
logger,
config,
}).build();
return router;
}
```
+2 -2
View File
@@ -140,7 +140,7 @@ jobs:
- name: test changed packages
if: ${{ steps.yarn-lock.outcome == 'success' }}
run: yarn lerna -- run test --since origin/master -- --coverage
run: yarn lerna -- run test --since origin/master -- --coverage --runInBand
env:
BACKSTAGE_TEST_DATABASE_POSTGRES13_CONNECTION_STRING: postgresql://postgres:postgres@localhost:${{ job.services.postgres13.ports[5432] }}
BACKSTAGE_TEST_DATABASE_POSTGRES9_CONNECTION_STRING: postgresql://postgres:postgres@localhost:${{ job.services.postgres9.ports[5432] }}
@@ -149,7 +149,7 @@ jobs:
- name: test all packages (and upload coverage)
if: ${{ steps.yarn-lock.outcome == 'failure' }}
run: |
yarn lerna -- run test -- --coverage
yarn lerna -- run test -- --coverage --runInBand
bash <(curl -s https://codecov.io/bash) -N $(git rev-parse FETCH_HEAD)
env:
BACKSTAGE_TEST_DATABASE_POSTGRES13_CONNECTION_STRING: postgresql://postgres:postgres@localhost:${{ job.services.postgres13.ports[5432] }}
+1 -1
View File
@@ -116,7 +116,7 @@ jobs:
- name: test (and upload coverage)
run: |
yarn lerna -- run test -- --coverage
yarn lerna -- run test -- --coverage --runInBand
bash <(curl -s https://codecov.io/bash)
# Upload code coverage for some specific flags. Also see .codecov.yml
bash <(curl -s https://codecov.io/bash) -f packages/core-app-api/coverage/* -F core-app-api
@@ -47,5 +47,5 @@ sentry:
organization: {{ .Values.appConfig.sentry.organization | quote }}
techdocs:
generators:
techdocs: 'local'
generator:
runIn: 'local'
@@ -32,7 +32,7 @@ spec:
ports:
- containerPort: {{ .Values.frontend.containerPort }}
resources:
{{- toYaml .Values.backend.resources | nindent 12 }}
{{- toYaml .Values.frontend.resources | nindent 12 }}
envFrom:
- configMapRef:
name: {{ include "backstage.fullname" . }}-app-env
+4 -4
View File
@@ -113,10 +113,10 @@ search engines.
## Plugins Integrated with Search
| Plugin | Support Status |
| -------- | -------------- |
| Catalog | ✅ |
| TechDocs | ✅ |
| Plugin | Support Status |
| -------------------------------------------------------------- | -------------- |
| Catalog | ✅ |
| [TechDocs](./how-to-guides.md#how-to-index-techdocs-documents) | ✅ |
[Reach out to us](#get-involved) if you want to chat about support for more
plugins integrated to search.
+52
View File
@@ -44,3 +44,55 @@ const app = createApp({
],
});
```
## How to index TechDocs documents
The TechDocs plugin has supported integrations to Search, meaning that it
provides a default collator ready to be used.
The purpose of this guide is to walk you through how to register the
[DefaultTechDocsCollator](https://github.com/backstage/backstage/blob/master/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.ts)
in your App, so that you can get TechDocs documents indexed.
If you have been through the
[Getting Started with Search guide](https://backstage.io/docs/features/search/getting-started),
you should have the `packages/backend/src/plugins/search.ts` file available. If
so, you can go ahead and follow this guide - if not, start by going through the
getting started guide.
1. Import the DefaultTechDocsCollator from `@backstage/plugin-techdocs-backend`.
```typescript
import { DefaultTechDocsCollator } from '@backstage/plugin-techdocs-backend';
```
2. Register the DefaultTechDocsCollator with the IndexBuilder.
```typescript
indexBuilder.addCollator({
defaultRefreshIntervalSeconds: 600,
collator: DefaultTechDocsCollator.fromConfig(config, {
discovery,
logger,
}),
});
```
You should now have your TechDocs documents indexed to your search engine of
choice!
If you want your users to be able to filter down to the techdocs type when
searching, you can update your `SearchPage.tsx` file in
`packages/app/src/components/search` by adding `techdocs` to the list of values
of the `SearchType` component.
```tsx
<Paper className={classes.filters}>
<SearchType
values={['techdocs', 'software-catalog']}
name="type"
defaultValue="software-catalog"
/>
...
</Paper>
```
@@ -620,9 +620,6 @@ The following describes the following entity kind:
| `apiVersion` | `backstage.io/v1beta2` |
| `kind` | `Template` |
If you're looking for docs on `v1alpha1` you can find them
[here](../software-templates/legacy.md)
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.
-117
View File
@@ -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.
@@ -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!
@@ -0,0 +1,156 @@
---
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 `apiVersion` `scaffolder.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 `scaffolder.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.
## `backstage.io/v1beta2` -> `scaffolder.backstage.io/v1beta3`
The most important change is that you'll need to switch over the `apiVersion` in
your templates to the new one.
```diff
kind: Template
- apiVersion: backstage.io/v1beta2
+ apiVersion: scaffolder.backstage.io/v1beta3
```
## `${{ }}` instead of `"{{ }}"`
One really big readability issue and cause for confusion was the fact that with
`handlebars` and `yaml` 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` helpers
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 🙏
```
## `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!
@@ -5,11 +5,12 @@ sidebar_label: Creating and Publishing Documentation
description: Guidance on how to create and publish documentation
---
This section will guide you through:
This section will guide you through how to:
- [Create a basic documentation setup](#create-a-basic-documentation-setup)
- [Use any software template](#use-any-software-template)
- [Use the documentation template](#use-the-documentation-template)
- [Manually add documentation setup to already existing repository](#manually-add-documentation-setup-to-already-existing-repository)
- [Enable documentation for an already existing entity](#enable-documentation-for-an-already-existing-entity)
- [Writing and previewing your documentation](#writing-and-previewing-your-documentation)
## Prerequisites
@@ -21,29 +22,47 @@ This section will guide you through:
If you have an existing repository that you'd like to add documentation to, skip
to the
[Manually add documentation setup](#manually-add-documentation-setup-to-already-existing-repository)
section below. Otherwise, continue reading to start a documentation repo from
scratch.
[Enable documentation for an already existing entity setup](#enable-documentation-for-an-already-existing-entity)
section below. Otherwise, continue reading to create a new software entity
including documentation from scratch.
### Use any software template
TechDocs is built on top of the
[docs like code approach](https://www.docslikecode.com/about/). This, in short,
means that you should keep documentation close to the code.
Your Backstage app has a set of software templates added by default. All of
these software templates include everything you need to get your TechDocs site
up and running and to start writing your documentation.
If you have created software templates that do not include documentation by
default, we highly recommend you to set that up. Follow our how-to guide
[How to add documentation setup to your software templates](./how-to-guides.md#how-to-add-the-documentation-setup-to-your-software-templates)
to get started.
### Use the documentation template
Your working Backstage instance should by default have a documentation template
added. If not, copy the catalog locations from the
There could be _some_ situations where you don't want to keep your docs close to
your code, but still want to publish documentation - for example, an onboarding
tutorial. For this use case, we have put together a documentation template. Your
Backstage instance should by default have a documentation template added. If
not, copy the catalog locations from the
[create-app template](https://github.com/backstage/backstage/blob/master/packages/create-app/templates/default-app/app-config.yaml.hbs)
to add the documentation template. The template creates a component with only
TechDocs configuration and default markdown files as below mentioned in manual
documentation setup, and is otherwise empty.
to add the documentation template. The template creates a component with
**only** TechDocs configuration and default markdown files, and is otherwise
empty.
![Documentation Template](../../assets/techdocs/documentation-template.png)
Create an entity from the documentation template and you will get the needed
setup for free.
### Manually add documentation setup to already existing repository
### Enable documentation for an already existing entity
Prerequisites:
- An existing component
- An existing entity
[registered in backstage](../software-catalog/index.md#adding-components-to-the-catalog)
(e.g. via a `catalog-info.yaml` file).
@@ -72,11 +91,11 @@ metadata:
The
[`backstage.io/techdocs-ref` annotation](../software-catalog/well-known-annotations.md#backstageiotechdocs-ref)
is used by TechDocs to download the documentation source files for generating an
Entity's TechDocs site.
entity's TechDocs site.
Create a `/docs` folder in the root of the project with at least an `index.md`
file. _(If you add more markdown files, make sure to update the nav in the
mkdocs.yml file to get a proper navigation for your documentation.)_
Create a `/docs` folder in the root of your repository with at least an
`index.md` file in it. _(If you add more markdown files, make sure to update the
nav in the mkdocs.yml file to get a proper navigation for your documentation.)_
> Note - Although `docs` is a popular directory name for storing documentation,
> it can be renamed to something else and can be configured by `mkdocs.yml`. See
@@ -95,9 +114,10 @@ updated documentation next time you run Backstage!
## Writing and previewing your documentation
Using the `techdocs-cli` you can preview your docs inside a local Backstage
instance and get live reload on changes. This is useful when you want to preview
your documentation while writing.
Using the [techdocs-cli](https://github.com/backstage/techdocs-cli) you can
preview your docs inside a local Backstage instance and get live reload on
changes. This is useful when you want to preview your documentation while
writing.
To do this you can run:
+2 -2
View File
@@ -215,10 +215,10 @@ techdocs:
publisher:
type: 'local'
generator:
techdocs: local
runIn: local
```
Setting `generators.techdocs` to `local` means you will have to make sure your
Setting `generator.runIn` to `local` means you will have to make sure your
environment is compatible with techdocs.
You will have to install the `mkdocs` and `mkdocs-techdocs-core` package from
+74 -1
View File
@@ -110,7 +110,8 @@ TechDocs uses a composability pattern similar to the Search and Catalog plugins
in Backstage. While a default table experience, similar to the one provided by
the Catalog plugin, is made available for ease-of-use, it's possible for you to
provide a completely custom experience, tailored to the needs of your
organization.
organization. For example, TechDocs comes with an alternative grid based layout
(`<EntityListDocsGrid>`).
This is done in your `app` package. By default, you might see something like
this in your `App.tsx`:
@@ -348,3 +349,75 @@ const app = createApp({
],
});
```
## How to add the documentation setup to your software templates
[Software Templates](https://backstage.io/docs/features/software-templates/software-templates-index)
in Backstage is a tool that can help your users to create new components out of
already configured templates. It comes with a set of default templates to use,
but you can also
[add your own templates](https://backstage.io/docs/features/software-templates/adding-templates).
If you have your own templates set up, we highly recommend that you include the
required setup for TechDocs in those templates. When creating a new component,
your users will then get a TechDocs site up and running automatically, ready for
them to start writing technical documentation.
The purpose of this how-to guide is to walk you through how to add the required
configuration and some default markdown files to your new template. You can use
the
[react-ssr-template](https://github.com/backstage/software-templates/tree/main/scaffolder-templates/react-ssr-template)
as a reference when walking through the steps.
Prerequisites:
- An existing software template including a `template.yaml` together with a
skeleton folder including at least a `catalog-info.yaml`.
1. Update your component's entity description by adding the following lines to
the `catalog-info.yaml` in your skeleton folder.
```yaml
annotations:
backstage.io/techdocs-ref: dir:.
```
The
[`backstage.io/techdocs-ref` annotation](../software-catalog/well-known-annotations.md#backstageiotechdocs-ref)
is used by TechDocs to download the documentation source files for generating an
entity's TechDocs site.
2. Create an `mkdocs.yml` file in the root of your skeleton folder with the
following content:
```yaml
site_name: ${{values.component_id}}
site_description: ${{values.description}}
nav:
- Introduction: index.md
plugins:
- techdocs-core
```
3. Create a `/docs` folder in the skeleton folder with at least an `index.md`
file in it.
The `docs/index.md` can for example have the following content:
```md
# ${{ values.component_id }}
${{ values.description }}
## Getting started
Start writing your documentation by adding more markdown (.md) files to this
folder (/docs) or replace the content in this file.
```
> Note: The values of `site_name`, `component_id` and `site_description` depends
> on how you have configured your `template.yaml`
Done! You now have support for TechDocs in your own software template!
+1 -1
View File
@@ -96,7 +96,7 @@ yarn start # Start serving the example app, use --check to include type checks a
yarn storybook # Start local storybook, useful for working on components in @backstage/core-components
yarn workspace @backstage/plugin-welcome start # Serve welcome plugin only, also supports --check
yarn workspace @backstage/plugin-api-docs start # Serve api-docs plugin only, also supports --check
yarn tsc # Run typecheck, use --watch for watch mode
yarn tsc:full # Run full type checking, for example without skipLibCheck, use in CI
+1 -1
View File
@@ -287,7 +287,7 @@ describe('SomeComponent', () => {
await waitFor(() => {
expect(apiSpy.getEvents()[0]).toMatchObject({
action: 'expected action',
subject: 'expected subject'',
subject: 'expected subject',
attributes: {
foo: 'bar',
},
+1 -1
View File
@@ -1,7 +1,7 @@
---
title: GKE Usage
author: BESTSELLER
authorUrl: bestsellerit.com
authorUrl: https://bestsellerit.com
category: Discovery
description: This plugin will show you the cost and resource usage of your application within Google Kubernetes Engine (GKE).
documentation: https://github.com/BESTSELLER/backstage-plugin-gkeusage/blob/master/README.md
+1 -1
View File
@@ -1,7 +1,7 @@
---
title: Harbor
author: BESTSELLER
authorUrl: bestsellerit.com
authorUrl: https://bestsellerit.com
category: Discovery
description: This plugin will show you information about Docker images within the Harbor cloud native registry.
documentation: https://github.com/BESTSELLER/backstage-plugin-harbor/blob/master/README.md
+1 -2
View File
@@ -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"
]
},
{
-5
View File
@@ -85,10 +85,5 @@
"*.md": [
"node ./scripts/check-docs-quality"
]
},
"jest": {
"transformModules": [
"@asyncapi/react-component"
]
}
}
+43
View File
@@ -1,5 +1,48 @@
# example-app
## 0.2.50
### Patch Changes
- Updated dependencies
- @backstage/plugin-catalog-react@0.6.0
- @backstage/plugin-catalog@0.7.1
- @backstage/plugin-api-docs@0.6.12
- @backstage/plugin-scaffolder@0.11.8
- @backstage/core-app-api@0.1.17
- @backstage/core-components@0.7.0
- @backstage/theme@0.2.11
- @backstage/plugin-graphiql@0.2.20
- @backstage/cli@0.7.16
- @backstage/plugin-home@0.4.4
- @backstage/plugin-catalog-graph@0.2.0
- @backstage/plugin-search@0.4.15
- @backstage/plugin-techdocs@0.12.2
- @backstage/plugin-kubernetes@0.4.17
- @backstage/plugin-azure-devops@0.1.1
- @backstage/plugin-badges@0.2.13
- @backstage/plugin-catalog-import@0.7.2
- @backstage/plugin-circleci@0.2.27
- @backstage/plugin-cloudbuild@0.2.27
- @backstage/plugin-code-coverage@0.1.15
- @backstage/plugin-explore@0.3.20
- @backstage/plugin-github-actions@0.4.22
- @backstage/plugin-jenkins@0.5.10
- @backstage/plugin-kafka@0.2.19
- @backstage/plugin-lighthouse@0.2.29
- @backstage/plugin-org@0.3.27
- @backstage/plugin-pagerduty@0.3.17
- @backstage/plugin-rollbar@0.3.18
- @backstage/plugin-sentry@0.3.25
- @backstage/plugin-todo@0.1.14
- @backstage/integration-react@0.1.12
- @backstage/plugin-cost-insights@0.11.10
- @backstage/plugin-gcp-projects@0.3.8
- @backstage/plugin-newrelic@0.3.8
- @backstage/plugin-shortcuts@0.1.12
- @backstage/plugin-tech-radar@0.4.11
- @backstage/plugin-user-settings@0.3.9
## 0.2.49
### Patch Changes
+39 -39
View File
@@ -1,49 +1,49 @@
{
"name": "example-app",
"version": "0.2.49",
"version": "0.2.50",
"private": true,
"bundled": true,
"dependencies": {
"@backstage/catalog-model": "^0.9.4",
"@backstage/cli": "^0.7.15",
"@backstage/core-app-api": "^0.1.16",
"@backstage/core-components": "^0.6.1",
"@backstage/cli": "^0.7.16",
"@backstage/core-app-api": "^0.1.17",
"@backstage/core-components": "^0.7.0",
"@backstage/core-plugin-api": "^0.1.10",
"@backstage/integration-react": "^0.1.11",
"@backstage/plugin-api-docs": "^0.6.11",
"@backstage/plugin-azure-devops": "^0.1.0",
"@backstage/plugin-badges": "^0.2.12",
"@backstage/plugin-catalog": "^0.7.0",
"@backstage/plugin-catalog-graph": "^0.1.3",
"@backstage/plugin-catalog-import": "^0.7.1",
"@backstage/plugin-catalog-react": "^0.5.2",
"@backstage/plugin-circleci": "^0.2.26",
"@backstage/plugin-cloudbuild": "^0.2.26",
"@backstage/plugin-code-coverage": "^0.1.14",
"@backstage/plugin-cost-insights": "^0.11.9",
"@backstage/plugin-explore": "^0.3.19",
"@backstage/plugin-gcp-projects": "^0.3.7",
"@backstage/plugin-github-actions": "^0.4.21",
"@backstage/plugin-graphiql": "^0.2.19",
"@backstage/plugin-home": "^0.4.3",
"@backstage/plugin-jenkins": "^0.5.9",
"@backstage/plugin-kafka": "^0.2.18",
"@backstage/plugin-kubernetes": "^0.4.16",
"@backstage/plugin-lighthouse": "^0.2.28",
"@backstage/plugin-newrelic": "^0.3.7",
"@backstage/plugin-org": "^0.3.26",
"@backstage/plugin-pagerduty": "0.3.16",
"@backstage/plugin-rollbar": "^0.3.17",
"@backstage/plugin-scaffolder": "^0.11.7",
"@backstage/plugin-search": "^0.4.14",
"@backstage/plugin-sentry": "^0.3.24",
"@backstage/plugin-shortcuts": "^0.1.11",
"@backstage/plugin-tech-radar": "^0.4.10",
"@backstage/plugin-techdocs": "^0.12.1",
"@backstage/plugin-todo": "^0.1.13",
"@backstage/plugin-user-settings": "^0.3.8",
"@backstage/integration-react": "^0.1.12",
"@backstage/plugin-api-docs": "^0.6.12",
"@backstage/plugin-azure-devops": "^0.1.1",
"@backstage/plugin-badges": "^0.2.13",
"@backstage/plugin-catalog": "^0.7.1",
"@backstage/plugin-catalog-graph": "^0.2.0",
"@backstage/plugin-catalog-import": "^0.7.2",
"@backstage/plugin-catalog-react": "^0.6.0",
"@backstage/plugin-circleci": "^0.2.27",
"@backstage/plugin-cloudbuild": "^0.2.27",
"@backstage/plugin-code-coverage": "^0.1.15",
"@backstage/plugin-cost-insights": "^0.11.10",
"@backstage/plugin-explore": "^0.3.20",
"@backstage/plugin-gcp-projects": "^0.3.8",
"@backstage/plugin-github-actions": "^0.4.22",
"@backstage/plugin-graphiql": "^0.2.20",
"@backstage/plugin-home": "^0.4.4",
"@backstage/plugin-jenkins": "^0.5.10",
"@backstage/plugin-kafka": "^0.2.19",
"@backstage/plugin-kubernetes": "^0.4.17",
"@backstage/plugin-lighthouse": "^0.2.29",
"@backstage/plugin-newrelic": "^0.3.8",
"@backstage/plugin-org": "^0.3.27",
"@backstage/plugin-pagerduty": "0.3.17",
"@backstage/plugin-rollbar": "^0.3.18",
"@backstage/plugin-scaffolder": "^0.11.8",
"@backstage/plugin-search": "^0.4.15",
"@backstage/plugin-sentry": "^0.3.25",
"@backstage/plugin-shortcuts": "^0.1.12",
"@backstage/plugin-tech-radar": "^0.4.11",
"@backstage/plugin-techdocs": "^0.12.2",
"@backstage/plugin-todo": "^0.1.14",
"@backstage/plugin-user-settings": "^0.3.9",
"@backstage/search-common": "^0.2.0",
"@backstage/theme": "^0.2.10",
"@backstage/theme": "^0.2.11",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.57",
@@ -63,7 +63,7 @@
"zen-observable": "^0.8.15"
},
"devDependencies": {
"@backstage/test-utils": "^0.1.18",
"@backstage/test-utils": "^0.1.19",
"@rjsf/core": "^3.0.0",
"@testing-library/cypress": "^7.0.1",
"@testing-library/jest-dom": "^5.10.1",
@@ -14,13 +14,17 @@
* limitations under the License.
*/
import React from 'react';
import { EntityLayout } from '@backstage/plugin-catalog';
import { EntityProvider } from '@backstage/plugin-catalog-react';
import { renderInTestApp } from '@backstage/test-utils';
import { cicdContent } from './EntityPage';
import { githubActionsApiRef } from '@backstage/plugin-github-actions';
import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
import { EntityLayout } from '@backstage/plugin-catalog';
import {
DefaultStarredEntitiesApi,
EntityProvider,
starredEntitiesApiRef,
} from '@backstage/plugin-catalog-react';
import { githubActionsApiRef } from '@backstage/plugin-github-actions';
import { MockStorageApi, renderInTestApp } from '@backstage/test-utils';
import React from 'react';
import { cicdContent } from './EntityPage';
describe('EntityPage Test', () => {
const entity = {
@@ -48,7 +52,10 @@ describe('EntityPage Test', () => {
downloadJobLogsForWorkflowRun: jest.fn(),
} as jest.Mocked<typeof githubActionsApiRef.T>;
const apis = ApiRegistry.with(githubActionsApiRef, mockedApi);
const apis = ApiRegistry.with(githubActionsApiRef, mockedApi).with(
starredEntitiesApiRef,
new DefaultStarredEntitiesApi({ storageApi: MockStorageApi.create() }),
);
describe('cicdContent', () => {
it('Should render GitHub Actions View', async () => {
@@ -17,6 +17,7 @@
import knexFactory, { Knex } from 'knex';
import { Config } from '@backstage/config';
import { ForwardedError } from '@backstage/errors';
import { mergeDatabaseConfig } from '../config';
import { DatabaseConnector } from '../types';
import defaultNameOverride from './defaultNameOverride';
@@ -94,8 +95,7 @@ function requirePgConnectionString() {
try {
return require('pg-connection-string').parse;
} catch (e) {
const message = `Postgres: Install 'pg-connection-string'`;
throw new Error(`${message}\n${e.message}`);
throw new ForwardedError("Postgres: Install 'pg-connection-string'", e);
}
}
@@ -167,7 +167,7 @@ describe('AwsS3UrlReader', () => {
),
).rejects.toThrow(
Error(
`Could not retrieve file from S3: not a valid AWS S3 URL: https://test-bucket.s3.us-east-2.NOTamazonaws.com/file.yaml`,
`Could not retrieve file from S3; caused by Error: not a valid AWS S3 URL: https://test-bucket.s3.us-east-2.NOTamazonaws.com/file.yaml`,
),
);
});
@@ -216,7 +216,7 @@ describe('AwsS3UrlReader', () => {
),
).rejects.toThrow(
Error(
`Could not retrieve file from S3: not a valid AWS S3 URL: https://test-bucket.s3.us-east-2.NOTamazonaws.com/file.yaml`,
`Could not retrieve file from S3; caused by Error: not a valid AWS S3 URL: https://test-bucket.s3.us-east-2.NOTamazonaws.com/file.yaml`,
),
);
});
@@ -27,6 +27,7 @@ import {
} from './types';
import getRawBody from 'raw-body';
import { AwsS3Integration, ScmIntegrations } from '@backstage/integration';
import { ForwardedError } from '@backstage/errors';
import { ListObjectsV2Output, ObjectList } from 'aws-sdk/clients/s3';
const parseURL = (
@@ -162,7 +163,7 @@ export class AwsS3UrlReader implements UrlReader {
etag: etag,
};
} catch (e) {
throw new Error(`Could not retrieve file from S3: ${e.message}`);
throw new ForwardedError('Could not retrieve file from S3', e);
}
}
@@ -203,7 +204,7 @@ export class AwsS3UrlReader implements UrlReader {
return await this.deps.treeResponseFactory.fromReadableArray(responses);
} catch (e) {
throw new Error(`Could not retrieve file tree from S3: ${e.message}`);
throw new ForwardedError('Could not retrieve file tree from S3', e);
}
}
@@ -221,6 +221,32 @@ describe('GithubUrlReader', () => {
).rejects.toThrow(NotModifiedError);
});
it('should throw Error with ratelimit exceeded if GitHub responds with 403 and rate limit is exceeded', async () => {
expect.assertions(1);
worker.use(
rest.get(
'https://ghe.github.com/api/v3/repos/backstage/mock/tree/contents/',
(_req, res, ctx) => {
return res(
ctx.status(403),
ctx.set('X-RateLimit-Remaining', '0'),
ctx.body(
'{"message": "API rate limit exceeded for xxx.xxx.xxx.xxx..."}',
),
);
},
),
);
await expect(
gheProcessor.readUrl(
'https://github.com/backstage/mock/tree/blob/main',
{ etag: 'foo' },
),
).rejects.toThrow(/rate limit exceeded/);
});
it('should return etag from the response', async () => {
(mockCredentialsProvider.getCredentials as jest.Mock).mockResolvedValue({
headers: {
@@ -126,10 +126,21 @@ export class GithubUrlReader implements UrlReader {
};
}
const message = `${url} could not be read as ${ghUrl}, ${response.status} ${response.statusText}`;
let message = `${url} could not be read as ${ghUrl}, ${response.status} ${response.statusText}`;
if (response.status === 404) {
throw new NotFoundError(message);
}
// GitHub returns a 403 response with a couple of headers indicating rate
// limit status. See more in the GitHub docs:
// https://docs.github.com/en/rest/overview/resources-in-the-rest-api#rate-limiting
if (
response.status === 403 &&
response.headers.get('X-RateLimit-Remaining') === '0'
) {
message += ' (rate limit exceeded)';
}
throw new Error(message);
}
@@ -15,6 +15,7 @@
*/
import { ConfigReader } from '@backstage/config';
import { isError } from '@backstage/errors';
import { getVoidLogger } from '../logging';
import { UrlReaders } from './UrlReaders';
@@ -71,7 +72,10 @@ function withRetries(count: number, fn: () => Promise<void>) {
error = err;
}
}
if (!error.message.match(/rate limit|Too Many Requests/)) {
if (
isError(error) &&
!error.message.match(/rate limit|Too Many Requests/)
) {
throw error;
} else {
console.warn('Request was rate limited', error);
@@ -16,6 +16,7 @@
import Docker from 'dockerode';
import fs from 'fs-extra';
import { ForwardedError } from '@backstage/errors';
import { PassThrough } from 'stream';
import { ContainerRunner, RunContainerOptions } from './ContainerRunner';
@@ -45,8 +46,9 @@ export class DockerContainerRunner implements ContainerRunner {
try {
await this.dockerClient.ping();
} catch (e) {
throw new Error(
`This operation requires Docker. Docker does not appear to be available. Docker.ping() failed with: ${e.message}`,
throw new ForwardedError(
'This operation requires Docker. Docker does not appear to be available. Docker.ping() failed with',
e,
);
}
+14
View File
@@ -1,5 +1,19 @@
# example-backend
## 0.2.50
### Patch Changes
- Updated dependencies
- @backstage/plugin-auth-backend@0.4.4
- @backstage/integration@0.6.8
- @backstage/plugin-scaffolder-backend@0.15.8
- @backstage/plugin-catalog-backend@0.17.0
- @backstage/plugin-azure-devops-backend@0.1.2
- @backstage/plugin-code-coverage-backend@0.1.13
- @backstage/plugin-kubernetes-backend@0.3.17
- example-app@0.2.50
## 0.2.49
### Patch Changes
+10 -10
View File
@@ -1,6 +1,6 @@
{
"name": "example-backend",
"version": "0.2.49",
"version": "0.2.50",
"main": "dist/index.cjs.js",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -28,20 +28,20 @@
"@backstage/catalog-client": "^0.5.0",
"@backstage/catalog-model": "^0.9.4",
"@backstage/config": "^0.1.10",
"@backstage/integration": "^0.6.7",
"@backstage/integration": "^0.6.8",
"@backstage/plugin-app-backend": "^0.3.16",
"@backstage/plugin-auth-backend": "^0.4.3",
"@backstage/plugin-azure-devops-backend": "^0.1.1",
"@backstage/plugin-auth-backend": "^0.4.4",
"@backstage/plugin-azure-devops-backend": "^0.1.2",
"@backstage/plugin-badges-backend": "^0.1.11",
"@backstage/plugin-catalog-backend": "^0.16.0",
"@backstage/plugin-code-coverage-backend": "^0.1.12",
"@backstage/plugin-catalog-backend": "^0.17.0",
"@backstage/plugin-code-coverage-backend": "^0.1.13",
"@backstage/plugin-graphql-backend": "^0.1.9",
"@backstage/plugin-jenkins-backend": "^0.1.6",
"@backstage/plugin-kubernetes-backend": "^0.3.16",
"@backstage/plugin-kubernetes-backend": "^0.3.17",
"@backstage/plugin-kafka-backend": "^0.2.10",
"@backstage/plugin-proxy-backend": "^0.2.13",
"@backstage/plugin-rollbar-backend": "^0.1.15",
"@backstage/plugin-scaffolder-backend": "^0.15.7",
"@backstage/plugin-scaffolder-backend": "^0.15.8",
"@backstage/plugin-scaffolder-backend-module-rails": "^0.1.5",
"@backstage/plugin-search-backend": "^0.2.6",
"@backstage/plugin-search-backend-node": "^0.4.2",
@@ -53,7 +53,7 @@
"@octokit/rest": "^18.5.3",
"azure-devops-node-api": "^11.0.1",
"dockerode": "^3.2.1",
"example-app": "^0.2.49",
"example-app": "^0.2.50",
"express": "^4.17.1",
"express-promise-router": "^4.1.0",
"express-prom-bundle": "^6.3.6",
@@ -65,7 +65,7 @@
"winston": "^3.2.1"
},
"devDependencies": {
"@backstage/cli": "^0.7.15",
"@backstage/cli": "^0.7.16",
"@types/dockerode": "^3.2.1",
"@types/express": "^4.17.6",
"@types/express-serve-static-core": "^4.17.5"
+43 -47
View File
@@ -9,12 +9,12 @@ import { JsonValue } from '@backstage/config';
import { SerializedError } from '@backstage/errors';
import * as yup from 'yup';
// @public @deprecated (undocumented)
// @public @deprecated
export const analyzeLocationSchema: yup.SchemaOf<{
location: LocationSpec;
}>;
// @public (undocumented)
// @public
interface ApiEntityV1alpha1 extends Entity {
// (undocumented)
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
@@ -32,7 +32,7 @@ interface ApiEntityV1alpha1 extends Entity {
export { ApiEntityV1alpha1 as ApiEntity };
export { ApiEntityV1alpha1 };
// @public (undocumented)
// @public
export const apiEntityV1alpha1Validator: KindValidator;
// @public
@@ -58,7 +58,7 @@ export function compareEntityToRef(
context?: EntityRefContext,
): boolean;
// @public (undocumented)
// @public
interface ComponentEntityV1alpha1 extends Entity {
// (undocumented)
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
@@ -79,7 +79,7 @@ interface ComponentEntityV1alpha1 extends Entity {
export { ComponentEntityV1alpha1 as ComponentEntity };
export { ComponentEntityV1alpha1 };
// @public (undocumented)
// @public
export const componentEntityV1alpha1Validator: KindValidator;
// @public
@@ -89,7 +89,7 @@ export class DefaultNamespaceEntityPolicy implements EntityPolicy {
enforce(entity: Entity): Promise<Entity>;
}
// @public (undocumented)
// @public
interface DomainEntityV1alpha1 extends Entity {
// (undocumented)
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
@@ -103,10 +103,10 @@ interface DomainEntityV1alpha1 extends Entity {
export { DomainEntityV1alpha1 as DomainEntity };
export { DomainEntityV1alpha1 };
// @public (undocumented)
// @public
export const domainEntityV1alpha1Validator: KindValidator;
// @public (undocumented)
// @public
export const EDIT_URL_ANNOTATION = 'backstage.io/edit-url';
// @public
@@ -181,7 +181,7 @@ export type EntityName = {
name: string;
};
// @public (undocumented)
// @public
export const EntityPolicies: {
allOf(policies: EntityPolicy[]): EntityPolicy;
oneOf(policies: EntityPolicy[]): EntityPolicy;
@@ -250,7 +250,7 @@ export function getEntitySourceLocation(entity: Entity): {
target: string;
};
// @public (undocumented)
// @public
interface GroupEntityV1alpha1 extends Entity {
// (undocumented)
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
@@ -272,10 +272,10 @@ interface GroupEntityV1alpha1 extends Entity {
export { GroupEntityV1alpha1 as GroupEntity };
export { GroupEntityV1alpha1 };
// @public (undocumented)
// @public
export const groupEntityV1alpha1Validator: KindValidator;
// @public (undocumented)
// @public
export type JSONSchema = JSONSchema7 & {
[key in string]?: JsonValue;
};
@@ -305,16 +305,16 @@ export class KubernetesValidatorFunctions {
static isValidObjectName(value: unknown): boolean;
}
// @public (undocumented)
// @public
type Location_2 = {
id: string;
} & LocationSpec;
export { Location_2 as Location };
// @public (undocumented)
// @public
export const LOCATION_ANNOTATION = 'backstage.io/managed-by-location';
// @public (undocumented)
// @public
interface LocationEntityV1alpha1 extends Entity {
// (undocumented)
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
@@ -330,23 +330,23 @@ interface LocationEntityV1alpha1 extends Entity {
export { LocationEntityV1alpha1 as LocationEntity };
export { LocationEntityV1alpha1 };
// @public (undocumented)
// @public
export const locationEntityV1alpha1Validator: KindValidator;
// @public @deprecated (undocumented)
// @public @deprecated
export const locationSchema: yup.SchemaOf<Location_2>;
// @public (undocumented)
// @public
export type LocationSpec = {
type: string;
target: string;
presence?: 'optional' | 'required';
};
// @public @deprecated (undocumented)
// @public @deprecated
export const locationSpecSchema: yup.SchemaOf<LocationSpec>;
// @public (undocumented)
// @public
export function makeValidator(overrides?: Partial<Validators>): Validators;
// @public
@@ -356,7 +356,7 @@ export class NoForeignRootFieldsEntityPolicy implements EntityPolicy {
enforce(entity: Entity): Promise<Entity>;
}
// @public (undocumented)
// @public
export const ORIGIN_LOCATION_ANNOTATION =
'backstage.io/managed-by-origin-location';
@@ -373,13 +373,9 @@ export function parseEntityRef(
defaultKind: string;
defaultNamespace: string;
},
): {
kind: string;
namespace: string;
name: string;
};
): EntityName;
// @public (undocumented)
// @public
export function parseEntityRef(
ref: EntityRef,
context?: {
@@ -391,7 +387,7 @@ export function parseEntityRef(
name: string;
};
// @public (undocumented)
// @public
export function parseEntityRef(
ref: EntityRef,
context?: {
@@ -409,28 +405,28 @@ export function parseLocationReference(ref: string): {
target: string;
};
// @public (undocumented)
// @public
export const RELATION_API_CONSUMED_BY = 'apiConsumedBy';
// @public (undocumented)
// @public
export const RELATION_API_PROVIDED_BY = 'apiProvidedBy';
// @public (undocumented)
// @public
export const RELATION_CHILD_OF = 'childOf';
// @public
export const RELATION_CONSUMES_API = 'consumesApi';
// @public (undocumented)
// @public
export const RELATION_DEPENDENCY_OF = 'dependencyOf';
// @public
export const RELATION_DEPENDS_ON = 'dependsOn';
// @public (undocumented)
// @public
export const RELATION_HAS_MEMBER = 'hasMember';
// @public (undocumented)
// @public
export const RELATION_HAS_PART = 'hasPart';
// @public
@@ -439,7 +435,7 @@ export const RELATION_MEMBER_OF = 'memberOf';
// @public
export const RELATION_OWNED_BY = 'ownedBy';
// @public (undocumented)
// @public
export const RELATION_OWNER_OF = 'ownerOf';
// @public
@@ -448,10 +444,10 @@ export const RELATION_PARENT_OF = 'parentOf';
// @public
export const RELATION_PART_OF = 'partOf';
// @public (undocumented)
// @public
export const RELATION_PROVIDES_API = 'providesApi';
// @public (undocumented)
// @public
interface ResourceEntityV1alpha1 extends Entity {
// (undocumented)
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
@@ -468,7 +464,7 @@ interface ResourceEntityV1alpha1 extends Entity {
export { ResourceEntityV1alpha1 as ResourceEntity };
export { ResourceEntityV1alpha1 };
// @public (undocumented)
// @public
export const resourceEntityV1alpha1Validator: KindValidator;
// @public
@@ -488,7 +484,7 @@ export function serializeEntityRef(
},
): EntityRef;
// @public (undocumented)
// @public
export const SOURCE_LOCATION_ANNOTATION = 'backstage.io/source-location';
// @public
@@ -508,7 +504,7 @@ export function stringifyLocationReference(ref: {
target: string;
}): string;
// @public (undocumented)
// @public
interface SystemEntityV1alpha1 extends Entity {
// (undocumented)
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
@@ -523,10 +519,10 @@ interface SystemEntityV1alpha1 extends Entity {
export { SystemEntityV1alpha1 as SystemEntity };
export { SystemEntityV1alpha1 };
// @public (undocumented)
// @public
export const systemEntityV1alpha1Validator: KindValidator;
// @public (undocumented)
// @public
export interface TemplateEntityV1beta2 extends Entity {
// (undocumented)
apiVersion: 'backstage.io/v1beta2';
@@ -550,7 +546,7 @@ export interface TemplateEntityV1beta2 extends Entity {
};
}
// @public (undocumented)
// @public
export const templateEntityV1beta2Validator: KindValidator;
// @alpha
@@ -569,7 +565,7 @@ export type UNSTABLE_EntityStatusItem = {
// @alpha
export type UNSTABLE_EntityStatusLevel = 'info' | 'warning' | 'error';
// @public (undocumented)
// @public
interface UserEntityV1alpha1 extends Entity {
// (undocumented)
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
@@ -588,10 +584,10 @@ interface UserEntityV1alpha1 extends Entity {
export { UserEntityV1alpha1 as UserEntity };
export { UserEntityV1alpha1 };
// @public (undocumented)
// @public
export const userEntityV1alpha1Validator: KindValidator;
// @public (undocumented)
// @public
export type Validators = {
isValidApiVersion(value: unknown): boolean;
isValidKind(value: unknown): boolean;
@@ -609,5 +605,5 @@ export const VIEW_URL_ANNOTATION = 'backstage.io/view-url';
// Warnings were encountered during analysis:
//
// src/entity/Entity.d.ts:38:5 - (ae-incompatible-release-tags) The symbol "status" is marked as @public, but its signature references "UNSTABLE_EntityStatus" which is marked as @alpha
// src/entity/Entity.d.ts:41:5 - (ae-incompatible-release-tags) The symbol "status" is marked as @public, but its signature references "UNSTABLE_EntityStatus" which is marked as @alpha
```
+5 -1
View File
@@ -52,7 +52,11 @@ class AnyEntityPolicy implements EntityPolicy {
}
}
/** @public */
/**
* Provides helpers for enforcing a set of {@link EntityPolicy} in an `and`/`or` expression.
*
* @public
*/
export const EntityPolicies = {
allOf(policies: EntityPolicy[]): EntityPolicy {
return new AllEntityPolicies(policies);
+10 -3
View File
@@ -21,8 +21,11 @@ import { UNSTABLE_EntityStatus } from './EntityStatus';
/**
* The parts of the format that's common to all versions/kinds of entity.
*
* @remarks
*
* See also:
* {@link https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/}
* @public
* @see https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/
*/
export type Entity = {
/**
@@ -63,9 +66,13 @@ export type Entity = {
/**
* Metadata fields common to all versions/kinds of entity.
*
* @remarks
*
* See also:
* {@link https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#objectmeta-v1-meta}
* {@link https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/}
*
* @public
* @see https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#objectmeta-v1-meta
* @see https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/
*/
export type EntityMeta = JsonObject & {
/**
@@ -33,10 +33,15 @@ export const ENTITY_META_GENERATED_FIELDS = [
] as const;
/**
* Annotations for linking to entity from catalog pages.
* Annotation for linking to entity page from catalog pages.
*
* @public
*/
export const VIEW_URL_ANNOTATION = 'backstage.io/view-url';
/** @public */
/**
* Annotation for linking to entity edit page from catalog pages.
*
* @public
*/
export const EDIT_URL_ANNOTATION = 'backstage.io/edit-url';
@@ -27,6 +27,8 @@ import { Entity } from '../Entity';
* Ensures that the format of individual fields of the entity envelope
* is valid.
*
* @remarks
*
* This does not take into account machine generated fields such as uid, etag
* and generation.
*
@@ -24,6 +24,8 @@ import { EntityPolicy } from './types';
/**
* Ensures that the entity spec is valid according to a schema.
*
* @remarks
*
* This should be the first policy in the list, to ensure that other downstream
* policies can work with a structure that is at least valid in therms of the
* typescript type.
+25 -8
View File
@@ -69,6 +69,8 @@ export type EntityRefContext = {
* Parses an entity reference, either on string or compound form, and always
* returns a complete entity name including kind, namespace and name.
*
* @remarks
*
* This function automatically assumes the default namespace "default" unless
* otherwise specified as part of the options, and will throw an error if no
* kind was specified in the input reference and no default kind was given.
@@ -100,7 +102,9 @@ export function parseEntityName(
* Parses an entity reference, either on string or compound form, and returns
* a structure with a name, and optional kind and namespace.
*
* The options object can contain default values for the kind and namespace,
* @remarks
*
* The context object can contain default values for the kind and namespace,
* that will be used if the input reference did not specify any.
*
* @public
@@ -111,12 +115,12 @@ export function parseEntityName(
export function parseEntityRef(
ref: EntityRef,
context?: { defaultKind: string; defaultNamespace: string },
): {
kind: string;
namespace: string;
name: string;
};
/** @public */
): EntityName;
/**
* parseEntityRef with optional Kind.
*
* @public
*/
export function parseEntityRef(
ref: EntityRef,
context?: { defaultKind: string },
@@ -125,7 +129,11 @@ export function parseEntityRef(
namespace?: string;
name: string;
};
/** @public */
/**
* parseEntityRef with optional Namespace.
*
* @public
*/
export function parseEntityRef(
ref: EntityRef,
context?: { defaultNamespace: string },
@@ -134,6 +142,11 @@ export function parseEntityRef(
namespace: string;
name: string;
};
/**
* parseEntityRef with optional Kind and Namespace.
*
* @public
*/
export function parseEntityRef(
ref: EntityRef,
context: EntityRefContext = {},
@@ -223,6 +236,8 @@ export function serializeEntityRef(
* Takes an entity or entity name/reference, and returns the string form of an
* entity ref.
*
* @remarks
*
* This function creates a canonical and unique reference to the entity, converting
* all parts of the name to lowercase and inserts the default namespace if needed.
* It is typically not the best way to represent the entity reference to the user.
@@ -256,6 +271,8 @@ export function stringifyEntityRef(
/**
* Compares an entity to either a string reference or a compound reference.
*
* @remarks
*
* The comparison is case insensitive, and all of kind, namespace, and name
* must match (after applying the optional context to the ref).
*
@@ -43,6 +43,8 @@ export function generateEntityEtag(): string {
* Checks whether there are any significant changes going from the previous to
* the next version of this entity.
*
* @remarks
*
* Significance, in this case, means that we do not compare generated fields
* such as uid, etag and generation.
*
@@ -98,6 +100,8 @@ export function entityHasChanges(previous: Entity, next: Entity): boolean {
* Takes an old revision of an entity and a new desired state, and merges
* them into a complete new state.
*
* @remarks
*
* The previous revision is expected to be a complete model loaded from the
* catalog, including the uid, etag and generation fields.
*

Some files were not shown because too many files have changed in this diff Show More