Merge branch 'master' into mob/use-entity-list-provider-in-scaffolder-page
Signed-off-by: Tim Hansen <timbonicus@gmail.com>
This commit is contained in:
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend': patch
|
||||
---
|
||||
|
||||
Fix `catalog:write` on windows systems
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/core-app-api': patch
|
||||
---
|
||||
|
||||
Reintroduce export of `defaultConfigLoader`.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-cost-insights': patch
|
||||
---
|
||||
|
||||
Replaced moment and dayjs with Luxon
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-auth-backend': patch
|
||||
---
|
||||
|
||||
Show better error message when configs defined under auth.providers.<provider> are undefined.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-catalog': patch
|
||||
---
|
||||
|
||||
Get rid of flex console warning for IconLink
|
||||
@@ -57,6 +57,7 @@ deadnaming
|
||||
debounce
|
||||
Debounce
|
||||
declaratively
|
||||
deduplicated
|
||||
deps
|
||||
destructured
|
||||
dev
|
||||
@@ -121,6 +122,7 @@ Knex
|
||||
kubectl
|
||||
kubernetes
|
||||
kubernetes
|
||||
ldap
|
||||
learnings
|
||||
Leasot
|
||||
lerna
|
||||
@@ -272,6 +274,7 @@ transpilation
|
||||
transpiled
|
||||
truthy
|
||||
ui
|
||||
unbreak
|
||||
unmanaged
|
||||
unregister
|
||||
unregistration
|
||||
|
||||
+4
-2
@@ -1,7 +1,7 @@
|
||||
| Organization | Contact | Description of Use |
|
||||
| ------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [Spotify](https://www.spotify.com) | [@leemills83](https://github.com/leemills83) | Main interface towards all of Spotify's infrastructure and technical documentation. |
|
||||
| [bol.com](https://www.bol.com) | [@RoyJacobs](https://github.com/RoyJacobs) | Initial work being done to unify platform tooling. |
|
||||
| [bol.com](https://www.bol.com) | [@sagacity](https://github.com/sagacity) | Initial work being done to unify platform tooling. |
|
||||
| [DFDS](https://www.dfds.com) | [@carlsendk](https://github.com/carlsendk) | V2 self-service platform. |
|
||||
| [Roadie](https://roadie.io) | [@dtuite](https://github.com/dtuite) | Hosted, managed Backstage with easy set-up |
|
||||
| [Roku](https://www.roku.com) | [@timurista](https://github.com/timurista) | Initial work on Cloud engineering service platform. |
|
||||
@@ -32,5 +32,7 @@
|
||||
| [PagerDuty](https://www.pagerduty.com/) | [Mark Shaw](https://github.com/markshawtoronto) | Developer portal, initially focused on software templates and tech-docs. |
|
||||
| [MoonShiner](https://moonshiner.at) | [Fabian Hippmann](https://github.com/FabianHippmann) | Developer portal - helps us keep track of our customer projects, onboard new developers & improve our development process 🌕🚀🧑🚀 |
|
||||
| [FundApps](https://www.fundapps.co/) | [Elliot Greenwood](https://github.com/egnwd) | Developer Portal - A place for us to keep track of our projects and documentation for all services and processes |
|
||||
| [DAZN](https://dazn.com/) | [Lou Bichard](https://twitter.com/loujaybee), [Marco Crivellaro](https://github.com/crivetechie) | Ingesting all of DAZN's repos for the catalog, migrating our internal platform apps (pull request boards, release information, inner source marketplace etc) to Backstage plugins (where applicable). |
|
||||
| [DAZN](https://dazn.com/) | [Lou Bichard](https://twitter.com/loujaybee), [Marco Crivellaro](https://github.com/crivetechie), [Alex Hollerith](mailto:alex.hollerith@dazn.com) | Ingesting all of DAZN's repos for the catalog, migrating our internal platform apps (pull request boards, release information, inner source marketplace etc) to Backstage plugins (where applicable). |
|
||||
| [HelloFresh](https://www.hellofresh.de/) | [@iammuho](https://github.com/iammuho), [@ElenaForester](https://github.com/ElenaForester), [@diegomarangoni](https://github.com/diegomarangoni) | Our developer portal at HelloFresh - Spread across an organisation of 500+ engineers globally. |
|
||||
| [FactSet](https://www.factset.com/) | [@kuangp](https://github.com/kuangp) | Developer portal to provide discoverability to all internal components, APIs, documentation, and scaffold templates with integrations to our internal infrastructure tools. |
|
||||
| [Workrise](https://www.workrise.com/) | [Michael Rode](https://github.com/michaelrode) | Developer portal, main gateway to our infrastructure, documentation and internal tooling. |
|
||||
|
||||
@@ -12,15 +12,15 @@
|
||||
|
||||
## What is Backstage?
|
||||
|
||||
[Backstage](https://backstage.io/) is an open platform for building developer portals. Powered by a centralized service catalog, Backstage restores order to your microservices and infrastructure and enables your product teams to ship high-quality code quickly — without compromising autonomy.
|
||||
[Backstage](https://backstage.io/) is an open platform for building developer portals. Powered by a centralized software catalog, Backstage restores order to your microservices and infrastructure and enables your product teams to ship high-quality code quickly — without compromising autonomy.
|
||||
|
||||
Backstage unifies all your infrastructure tooling, services, and documentation to create a streamlined development environment from end to end.
|
||||
|
||||

|
||||

|
||||
|
||||
Out of the box, Backstage includes:
|
||||
|
||||
- [Backstage Service Catalog](https://backstage.io/docs/features/software-catalog/software-catalog-overview) for managing all your software (microservices, libraries, data pipelines, websites, ML models, etc.)
|
||||
- [Backstage Software Catalog](https://backstage.io/docs/features/software-catalog/software-catalog-overview) for managing all your software (microservices, libraries, data pipelines, websites, ML models, etc.)
|
||||
- [Backstage Software Templates](https://backstage.io/docs/features/software-templates/software-templates-index) for quickly spinning up new projects and standardizing your tooling with your organization’s best practices
|
||||
- [Backstage TechDocs](https://backstage.io/docs/features/techdocs/techdocs-overview) for making it easy to create, maintain, find, and use technical documentation, using a "docs like code" approach
|
||||
- Plus, a growing ecosystem of [open source plugins](https://github.com/backstage/backstage/tree/master/plugins) that further expand Backstage’s customizability and functionality
|
||||
@@ -38,7 +38,7 @@ Check out [the documentation](https://backstage.io/docs/getting-started) on how
|
||||
## Documentation
|
||||
|
||||
- [Main documentation](https://backstage.io/docs)
|
||||
- [Service Catalog](https://backstage.io/docs/features/software-catalog/software-catalog-overview)
|
||||
- [Software Catalog](https://backstage.io/docs/features/software-catalog/software-catalog-overview)
|
||||
- [Architecture](https://backstage.io/docs/overview/architecture-overview) ([Decisions](https://backstage.io/docs/architecture-decisions/adrs-overview))
|
||||
- [Designing for Backstage](https://backstage.io/docs/dls/design)
|
||||
- [Storybook - UI components](https://backstage.io/storybook)
|
||||
|
||||
@@ -26,6 +26,7 @@ import 'global-agent/bootstrap';
|
||||
|
||||
```sh
|
||||
export GLOBAL_AGENT_HTTP_PROXY=$HTTP_PROXY
|
||||
export GLOBAL_AGENT_NO_PROXY=$NO_PROXY
|
||||
yarn start
|
||||
```
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 303 KiB After Width: | Height: | Size: 303 KiB |
@@ -59,16 +59,17 @@ Once the host build is complete, we are ready to build our image. The following
|
||||
FROM node:14-buster-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy repo skeleton first, to avoid unnecessary docker cache invalidation.
|
||||
# The skeleton contains the package.json of each package in the monorepo,
|
||||
# and along with yarn.lock and the root package.json, that's enough to run yarn install.
|
||||
ADD yarn.lock package.json packages/backend/dist/skeleton.tar.gz ./
|
||||
COPY yarn.lock package.json packages/backend/dist/skeleton.tar.gz ./
|
||||
RUN tar xzf skeleton.tar.gz && rm skeleton.tar.gz
|
||||
|
||||
RUN yarn install --frozen-lockfile --production --network-timeout 300000 && rm -rf "$(yarn cache dir)"
|
||||
|
||||
# Then copy the rest of the backend bundle, along with any other files we might want.
|
||||
ADD packages/backend/dist/bundle.tar.gz app-config.yaml ./
|
||||
COPY packages/backend/dist/bundle.tar.gz app-config.yaml ./
|
||||
RUN tar xzf bundle.tar.gz && rm bundle.tar.gz
|
||||
|
||||
CMD ["node", "packages/backend", "--config", "app-config.yaml"]
|
||||
```
|
||||
|
||||
@@ -68,7 +68,7 @@ The base URL to the Kubernetes control plane. Can be found by using the
|
||||
##### `clusters.\*.name`
|
||||
|
||||
A name to represent this cluster, this must be unique within the `clusters`
|
||||
array. Users will see this value in the Service Catalog Kubernetes plugin.
|
||||
array. Users will see this value in the Software Catalog Kubernetes plugin.
|
||||
|
||||
##### `clusters.\*.authProvider`
|
||||
|
||||
@@ -195,7 +195,7 @@ annotations:
|
||||
|
||||
#### Labeling Kubernetes components
|
||||
|
||||
In order for Kubernetes components to show up in the service catalog as a part
|
||||
In order for Kubernetes components to show up in the software catalog as a part
|
||||
of an entity, Kubernetes components themselves can have the following label:
|
||||
|
||||
```yaml
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
id: overview
|
||||
title: Kubernetes
|
||||
sidebar_label: Overview
|
||||
description: Monitoring Kubernetes based services with the service catalog
|
||||
description: Monitoring Kubernetes based services with the software catalog
|
||||
---
|
||||
|
||||
Kubernetes in Backstage is a tool that's designed around the needs of service
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
---
|
||||
id: software-catalog-overview
|
||||
title: Backstage Service Catalog (alpha)
|
||||
title: Backstage Software Catalog (alpha)
|
||||
sidebar_label: Overview
|
||||
# prettier-ignore
|
||||
description: The Backstage Service Catalog — actually, a software catalog, since it includes more than just services
|
||||
description: The Backstage Software Catalog
|
||||
---
|
||||
|
||||
## What is a Service Catalog?
|
||||
## What is a Software Catalog?
|
||||
|
||||
The Backstage Service Catalog — actually, a software catalog, since it includes
|
||||
The Backstage Software Catalog — actually, a software catalog, since it includes
|
||||
more than just services — is a centralized system that keeps track of ownership
|
||||
and metadata for all the software in your ecosystem (services, websites,
|
||||
libraries, data pipelines, etc). The catalog is built around the concept of
|
||||
[metadata YAML files](descriptor-format.md) stored together with the code, which
|
||||
are then harvested and visualized in Backstage.
|
||||
|
||||

|
||||

|
||||
|
||||
## How it works
|
||||
|
||||
Backstage and the Backstage Service Catalog make it easy for one team to manage
|
||||
Backstage and the Backstage Software Catalog make it easy for one team to manage
|
||||
10 services — and makes it possible for your company to manage thousands of
|
||||
them.
|
||||
|
||||
More specifically, the Service Catalog enables two main use-cases:
|
||||
More specifically, the Software Catalog enables two main use-cases:
|
||||
|
||||
1. Helping teams manage and maintain the software they own. Teams get a uniform
|
||||
view of all their software; services, libraries, websites, ML models — you
|
||||
@@ -37,11 +37,11 @@ The Software Catalog is available to browse at `/catalog`. If you've followed
|
||||
[Getting Started with Backstage](../../getting-started), you should be able to
|
||||
browse the catalog at `http://localhost:3000`.
|
||||
|
||||

|
||||

|
||||
|
||||
## Adding components to the catalog
|
||||
|
||||
The source of truth for the components in your service catalog are
|
||||
The source of truth for the components in your software catalog are
|
||||
[metadata YAML files](descriptor-format.md) stored in source control (GitHub,
|
||||
GitHub Enterprise, GitLab, ...).
|
||||
|
||||
@@ -104,11 +104,11 @@ them, and do so using their normal Git workflow.
|
||||

|
||||
|
||||
Once the change has been merged, Backstage will automatically show the updated
|
||||
metadata in the service catalog after a short while.
|
||||
metadata in the software catalog after a short while.
|
||||
|
||||
## Finding software in the catalog
|
||||
|
||||
By default the service catalog shows components owned by the team of the logged
|
||||
By default the software catalog shows components owned by the team of the logged
|
||||
in user. But you can also switch to _All_ to see all the components across your
|
||||
company's software ecosystem. Basic inline _search_ and _column filtering_ makes
|
||||
it easy to browse a big set of components.
|
||||
@@ -124,7 +124,7 @@ _starring_ of components:
|
||||
|
||||
## Integrated tooling through plugins
|
||||
|
||||
The service catalog is a great way to organize the infrastructure tools you use
|
||||
The software catalog is a great way to organize the infrastructure tools you use
|
||||
to manage the software. This is how Backstage creates one developer portal for
|
||||
all your tools. Rather than asking teams to jump between different
|
||||
infrastructure UIs (and incurring additional cognitive overhead each time they
|
||||
|
||||
@@ -83,7 +83,7 @@ spec:
|
||||
[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
|
||||
Once we have a `template.yaml` ready, we can then add it to the software catalog
|
||||
for use by the scaffolder.
|
||||
|
||||
You can add the template files to the catalog through
|
||||
|
||||
@@ -4,8 +4,8 @@ title: Writing Templates
|
||||
description: Details around creating your own custom Software Templates
|
||||
---
|
||||
|
||||
Templates are stored in the **Service Catalog** under a kind `Template`. You can
|
||||
create your own templates with a small `yaml` definition which describes the
|
||||
Templates are stored in the **Software Catalog** under a kind `Template`. You
|
||||
can create your own templates with a small `yaml` definition which describes the
|
||||
template and it's metadata, along with some input variables that your template
|
||||
will need, and then a list of actions which are then executed by the scaffolding
|
||||
service.
|
||||
|
||||
@@ -78,11 +78,6 @@ the repository. The archive does not have any git history attached to it. Also
|
||||
it is a compressed file. Hence the file size is significantly smaller than how
|
||||
much data git clone has to transfer.
|
||||
|
||||
Caveat: Currently TechDocs sites built using URL Reader will be cached for 30
|
||||
minutes which means they will not be re-built if new changes are made within 30
|
||||
minutes. This cache invalidation will be replaced by commit timestamp based
|
||||
implementation very soon.
|
||||
|
||||
## How to use a custom TechDocs home page?
|
||||
|
||||
### 1st way: TechDocsCustomHome with a custom configuration
|
||||
|
||||
@@ -14,19 +14,25 @@ entities that mirror your org setup.
|
||||
|
||||
## Installation
|
||||
|
||||
The processor that performs the import, `LdapOrgReaderProcessor`, comes
|
||||
installed with the default setup of Backstage.
|
||||
1. The processor is not installed by default, therefore you have to add a
|
||||
dependency to `@backstage/plugin-catalog-backend-module-ldap` to your backend
|
||||
package.
|
||||
|
||||
If you replace the set of processors in your installation using that facility of
|
||||
the catalog builder class, you can import and add it as follows.
|
||||
```bash
|
||||
# From your Backstage root directory
|
||||
cd packages/backend
|
||||
yarn add @backstage/plugin-catalog-backend-module-ldap
|
||||
```
|
||||
|
||||
```ts
|
||||
// Typically in packages/backend/src/plugins/catalog.ts
|
||||
import { LdapOrgReaderProcessor } from '@backstage/plugin-catalog-backend';
|
||||
2. The `LdapOrgReaderProcessor` is not registered by default, so you have to
|
||||
register it in the catalog plugin:
|
||||
|
||||
builder.replaceProcessors(
|
||||
LdapOrgReaderProcessor.fromConfig(config, { logger }),
|
||||
// ...
|
||||
```typescript
|
||||
// packages/backend/src/plugins/catalog.ts
|
||||
builder.addProcessor(
|
||||
LdapOrgReaderProcessor.fromConfig(config, {
|
||||
logger,
|
||||
}),
|
||||
);
|
||||
```
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ different ways.
|
||||
|
||||
The following diagram shows how Backstage might look when deployed inside a
|
||||
company which uses the Tech Radar plugin, the Lighthouse plugin, the CircleCI
|
||||
plugin and the service catalog.
|
||||
plugin and the software catalog.
|
||||
|
||||
There are 3 main components in this architecture:
|
||||
|
||||
@@ -142,7 +142,7 @@ Its architecture looks like this:
|
||||
|
||||

|
||||
|
||||
The service catalog in Backstage is another example of a service backed plugin.
|
||||
The software catalog in Backstage is another example of a service backed plugin.
|
||||
It retrieves a list of services, or "entities", from the Backstage Backend
|
||||
service and renders them in a table for the user.
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@ Our idea was to centralize and simplify end-to-end software development with an
|
||||
abstraction layer that sits on top of all of our infrastructure and developer
|
||||
tooling. That’s Backstage.
|
||||
|
||||
It’s a developer portal powered by a centralized service catalog — with a plugin
|
||||
architecture that makes it endlessly extensible and customizable.
|
||||
It’s a developer portal powered by a centralized software catalog — with a
|
||||
plugin architecture that makes it endlessly extensible and customizable.
|
||||
|
||||
Manage all your services, software, tooling, and testing in Backstage. Start
|
||||
building a new microservice using an automated template in Backstage. Create,
|
||||
|
||||
@@ -22,7 +22,7 @@ We have divided the project into three high-level _phases_:
|
||||
[UX patterns and components](https://backstage.io/storybook) help ensure a
|
||||
consistent experience between tools.
|
||||
|
||||
- 🐢 **Phase 2:** Service Catalog
|
||||
- 🐢 **Phase 2:** Software Catalog
|
||||
([alpha released](https://backstage.io/blog/2020/06/22/backstage-service-catalog-alpha)) -
|
||||
With a single catalog, Backstage makes it easy for a team to manage ten
|
||||
services — and makes it possible for your company to manage thousands of them.
|
||||
@@ -120,13 +120,13 @@ Chances are that someone will jump in and help build it.
|
||||
- [TechDocs v1](https://backstage.io/blog/2020/09/08/announcing-tech-docs)
|
||||
- [Plugin marketplace](https://backstage.io/plugins)
|
||||
- [Improved and move documentation to backstage.io](https://backstage.io/docs/overview/what-is-backstage)
|
||||
- [Backstage Service Catalog (alpha)](https://backstage.io/blog/2020/06/22/backstage-service-catalog-alpha)
|
||||
- [Backstage Software Catalog (alpha)](https://backstage.io/blog/2020/06/22/backstage-service-catalog-alpha)
|
||||
- [Backstage Software Templates (alpha)](https://backstage.io/blog/2020/08/05/announcing-backstage-software-templates)
|
||||
- [Make it possible to add custom auth providers](https://backstage.io/blog/2020/07/01/how-to-enable-authentication-in-backstage-using-passport)
|
||||
- [TechDocs v0](https://github.com/backstage/backstage/milestone/15)
|
||||
- CI plugins: CircleCI, Jenkins, GitHub Actions and TravisCI
|
||||
- [Service API documentation](https://github.com/backstage/backstage/pull/1737)
|
||||
- Backstage Service Catalog can read from: GitHub, GitLab,
|
||||
- Backstage Software Catalog can read from: GitHub, GitLab,
|
||||
[Bitbucket](https://github.com/backstage/backstage/pull/1938)
|
||||
- Support auth providers: Google, Okta, GitHub, GitLab,
|
||||
[auth0](https://github.com/backstage/backstage/pull/1611),
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
id: what-is-backstage
|
||||
title: What is Backstage?
|
||||
# prettier-ignore
|
||||
description: Backstage is an open platform for building developer portals. Powered by a centralized service catalog, Backstage restores order to your microservices and infrastructure
|
||||
description: Backstage is an open platform for building developer portals. Powered by a centralized software catalog, Backstage restores order to your microservices and infrastructure
|
||||
---
|
||||
|
||||

|
||||

|
||||
|
||||
[Backstage](https://backstage.io/) is an open platform for building developer
|
||||
portals. Powered by a centralized service catalog, Backstage restores order to
|
||||
portals. Powered by a centralized software catalog, Backstage restores order to
|
||||
your microservices and infrastructure and enables your product teams to ship
|
||||
high-quality code quickly — without compromising autonomy.
|
||||
|
||||
@@ -17,7 +17,7 @@ to create a streamlined development environment from end to end.
|
||||
|
||||
Out of the box, Backstage includes:
|
||||
|
||||
- [Backstage Service Catalog](../features/software-catalog/index.md) for
|
||||
- [Backstage Software Catalog](../features/software-catalog/index.md) for
|
||||
managing all your software (microservices, libraries, data pipelines,
|
||||
websites, ML models, etc.)
|
||||
|
||||
|
||||
@@ -28,9 +28,9 @@ This helps the community know what plugins are in development.
|
||||
You can also use this process if you have an idea for a good plugin but you hope
|
||||
that someone else will pick up the work.
|
||||
|
||||
## Integrate into the Service Catalog
|
||||
## Integrate into the Software Catalog
|
||||
|
||||
If your plugin isn't supposed to live as a standalone page, but rather needs to
|
||||
be presented as a part of a Service Catalog (e.g. a separate tab or a card on an
|
||||
"Overview" tab), then check out
|
||||
[the instruction](integrating-plugin-into-service-catalog.md) on how to do it.
|
||||
be presented as a part of a Software Catalog (e.g. a separate tab or a card on
|
||||
an "Overview" tab), then check out
|
||||
[the instruction](integrating-plugin-into-software-catalog.md) on how to do it.
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
---
|
||||
id: integrating-plugin-into-service-catalog
|
||||
title: Integrate into the Service Catalog
|
||||
description: How to integrate a plugin into service catalog
|
||||
id: integrating-plugin-into-software-catalog
|
||||
title: Integrate into the Software Catalog
|
||||
description: How to integrate a plugin into software catalog
|
||||
---
|
||||
|
||||
> This is an advanced use case and currently is an experimental feature. Expect
|
||||
@@ -33,7 +33,7 @@ class Footer extends React.Component {
|
||||
<a
|
||||
href={`/docs/features/software-catalog/software-catalog-overview`}
|
||||
>
|
||||
Service Catalog
|
||||
Software Catalog
|
||||
</a>
|
||||
<a href={`/docs/plugins/create-a-plugin`}>Create a Plugin</a>
|
||||
<a href={`/docs/dls/design`}>Designing for Backstage</a>
|
||||
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
---
|
||||
title: Backstage Service Catalog
|
||||
title: Backstage Software Catalog
|
||||
author: Spotify
|
||||
authorUrl: https://github.com/spotify
|
||||
category: Core Feature
|
||||
description: Manage all your services and software components, all in one place.
|
||||
documentation: https://backstage.io/docs/features/software-catalog/software-catalog-overview
|
||||
iconUrl: img/backstage-service-catalog.svg
|
||||
iconUrl: img/backstage-software-catalog.svg
|
||||
npmPackageName: '@backstage/plugin-catalog'
|
||||
order: 1
|
||||
@@ -19,7 +19,7 @@
|
||||
"@spotify/prettier-config": "^10.0.0",
|
||||
"docusaurus": "^2.0.0-alpha.70",
|
||||
"js-yaml": "^4.1.0",
|
||||
"prettier": "^2.3.1",
|
||||
"prettier": "^2.3.2",
|
||||
"yarn-lock-check": "^1.0.5"
|
||||
},
|
||||
"prettier": "@spotify/prettier-config"
|
||||
|
||||
@@ -42,7 +42,7 @@ const Background = props => {
|
||||
To explore the UI and basic features of Backstage firsthand, go
|
||||
to: <a href="https://demo.backstage.io">demo.backstage.io</a>.
|
||||
(Tip: click “All” to view all the example components in the
|
||||
service catalog.)
|
||||
software catalog.)
|
||||
</Block.Paragraph>
|
||||
</Block.TextBox>
|
||||
<Block.Graphics>
|
||||
|
||||
@@ -27,7 +27,7 @@ class Index extends React.Component {
|
||||
An open platform for building developer portals
|
||||
</Block.Title>
|
||||
<Block.Paragraph>
|
||||
Powered by a centralized service catalog, Backstage restores
|
||||
Powered by a centralized software catalog, Backstage restores
|
||||
order to your infrastructure and enables your product teams to
|
||||
ship high-quality code quickly — without compromising autonomy.
|
||||
</Block.Paragraph>
|
||||
@@ -102,10 +102,10 @@ class Index extends React.Component {
|
||||
{' '}
|
||||
<img
|
||||
className="Block__GIF"
|
||||
src={`${baseUrl}animations/backstage-service-catalog-icon-1.gif`}
|
||||
src={`${baseUrl}animations/backstage-software-catalog-icon-1.gif`}
|
||||
/>
|
||||
<Block.Subtitle>
|
||||
Backstage Service Catalog{' '}
|
||||
Backstage Software Catalog{' '}
|
||||
<a
|
||||
title="Submit feedback for this feature. Click to learn more about this release."
|
||||
href="https://backstage.io/blog/2020/06/22/backstage-service-catalog-alpha"
|
||||
@@ -192,7 +192,7 @@ class Index extends React.Component {
|
||||
|
||||
<ActionBlock className="stripe bg-teal">
|
||||
<ActionBlock.Title>
|
||||
Learn more about the service catalog
|
||||
Learn more about the software catalog
|
||||
</ActionBlock.Title>
|
||||
<ActionBlock.Link
|
||||
href={`https://backstage.io/blog/2020/06/22/backstage-service-catalog-alpha`}
|
||||
|
||||
@@ -157,7 +157,7 @@
|
||||
"plugins/create-a-plugin",
|
||||
"plugins/plugin-development",
|
||||
"plugins/structure-of-a-plugin",
|
||||
"plugins/integrating-plugin-into-service-catalog",
|
||||
"plugins/integrating-plugin-into-software-catalog",
|
||||
"plugins/composability",
|
||||
{
|
||||
"type": "subcategory",
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
// site configuration options.
|
||||
|
||||
const siteConfig = {
|
||||
title: 'Backstage Service Catalog and Developer Platform', // Title for your website.
|
||||
title: 'Backstage Software Catalog and Developer Platform', // Title for your website.
|
||||
tagline: 'An open platform for building developer portals',
|
||||
url: 'https://backstage.io', // Your website URL
|
||||
cname: 'backstage.io',
|
||||
|
||||
|
Before Width: | Height: | Size: 474 KiB After Width: | Height: | Size: 474 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
+4
-4
@@ -5207,10 +5207,10 @@ prepend-http@^2.0.0:
|
||||
resolved "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
|
||||
integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=
|
||||
|
||||
prettier@^2.3.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.npmjs.org/prettier/-/prettier-2.3.1.tgz#76903c3f8c4449bc9ac597acefa24dc5ad4cbea6"
|
||||
integrity sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA==
|
||||
prettier@^2.3.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz#ef280a05ec253712e486233db5c6f23441e7342d"
|
||||
integrity sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==
|
||||
|
||||
prismjs@^1.22.0:
|
||||
version "1.23.0"
|
||||
|
||||
+1
-1
@@ -105,7 +105,7 @@ nav:
|
||||
- Plugin Development: 'plugins/plugin-development.md'
|
||||
- Structure of a plugin: 'plugins/structure-of-a-plugin.md'
|
||||
- Plugin Development: 'plugins/plugin-development.md'
|
||||
- Integrate into the Service Catalog: 'plugins/integrating-plugin-into-service-catalog.md'
|
||||
- Integrate into the Software Catalog: 'plugins/integrating-plugin-into-software-catalog.md'
|
||||
- Composability System Migration: 'plugins/composability.md'
|
||||
- Backends and APIs:
|
||||
- Proxying: 'plugins/proxying.md'
|
||||
|
||||
@@ -43,10 +43,10 @@
|
||||
"@material-ui/core": "^4.11.0",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@octokit/rest": "^18.5.3",
|
||||
"@roadiehq/backstage-plugin-buildkite": "^1.0.3",
|
||||
"@roadiehq/backstage-plugin-github-insights": "^1.1.11",
|
||||
"@roadiehq/backstage-plugin-github-pull-requests": "^1.0.5",
|
||||
"@roadiehq/backstage-plugin-travis-ci": "^1.0.0",
|
||||
"@roadiehq/backstage-plugin-buildkite": "^1.0.4",
|
||||
"@roadiehq/backstage-plugin-github-insights": "^1.1.15",
|
||||
"@roadiehq/backstage-plugin-github-pull-requests": "^1.0.8",
|
||||
"@roadiehq/backstage-plugin-travis-ci": "^1.0.4",
|
||||
"history": "^5.0.0",
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "^16.12.0",
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
# @backstage/backend-common
|
||||
|
||||
## 0.8.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 88d742eb8: Download archives as compressed tar files for GitLab to fix the `readTree` bug in TODO Plugin.
|
||||
- ab5cc376f: Add new `isChildPath` and `resolveSafeChildPath` exports
|
||||
- Updated dependencies
|
||||
- @backstage/cli-common@0.1.2
|
||||
- @backstage/integration@0.5.7
|
||||
|
||||
## 0.8.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -16,6 +16,7 @@ import { GithubCredentialsProvider } from '@backstage/integration';
|
||||
import { GitHubIntegration } from '@backstage/integration';
|
||||
import { GitLabIntegration } from '@backstage/integration';
|
||||
import * as http from 'http';
|
||||
import { isChildPath } from '@backstage/cli-common';
|
||||
import { JsonValue } from '@backstage/config';
|
||||
import { Knex } from 'knex';
|
||||
import { Logger } from 'winston';
|
||||
@@ -252,6 +253,8 @@ export class GitlabUrlReader implements UrlReader {
|
||||
toString(): string;
|
||||
}
|
||||
|
||||
export { isChildPath }
|
||||
|
||||
// @public
|
||||
export function loadBackendConfig(options: Options): Promise<Config>;
|
||||
|
||||
@@ -294,6 +297,9 @@ export function requestLoggingHandler(logger?: Logger): RequestHandler;
|
||||
// @public
|
||||
export function resolvePackagePath(name: string, ...paths: string[]): string;
|
||||
|
||||
// @public
|
||||
export function resolveSafeChildPath(base: string, path: string): string;
|
||||
|
||||
// @public (undocumented)
|
||||
export type RunContainerOptions = {
|
||||
imageName: string;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/backend-common",
|
||||
"description": "Common functionality library for Backstage backends",
|
||||
"version": "0.8.3",
|
||||
"version": "0.8.4",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"private": false,
|
||||
@@ -29,11 +29,11 @@
|
||||
"clean": "backstage-cli clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/cli-common": "^0.1.1",
|
||||
"@backstage/cli-common": "^0.1.2",
|
||||
"@backstage/config": "^0.1.5",
|
||||
"@backstage/config-loader": "^0.6.4",
|
||||
"@backstage/errors": "^0.1.1",
|
||||
"@backstage/integration": "^0.5.6",
|
||||
"@backstage/integration": "^0.5.7",
|
||||
"@google-cloud/storage": "^5.8.0",
|
||||
"@octokit/rest": "^18.5.3",
|
||||
"@types/cors": "^2.8.6",
|
||||
@@ -76,7 +76,7 @@
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.7.1",
|
||||
"@backstage/cli": "^0.7.3",
|
||||
"@backstage/test-utils": "^0.1.12",
|
||||
"@types/archiver": "^5.1.0",
|
||||
"@types/compression": "^1.7.0",
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { isChildPath } from '@backstage/cli-common';
|
||||
import { NotAllowedError } from '@backstage/errors';
|
||||
import { resolve as resolvePath } from 'path';
|
||||
|
||||
/**
|
||||
@@ -32,3 +34,27 @@ export function resolvePackagePath(name: string, ...paths: string[]) {
|
||||
|
||||
return resolvePath(req.resolve(`${name}/package.json`), '..', ...paths);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a target path from a base path while guaranteeing that the result is
|
||||
* a path that point to or within the base path. This is useful for resolving
|
||||
* paths from user input, as it otherwise opens up for vulnerabilities.
|
||||
*
|
||||
* @param base The base directory to resolve the path from.
|
||||
* @param path The target path, relative or absolute
|
||||
* @returns A path that is guaranteed to point to or within the base path.
|
||||
*/
|
||||
export function resolveSafeChildPath(base: string, path: string): string {
|
||||
const targetPath = resolvePath(base, path);
|
||||
|
||||
if (!isChildPath(base, targetPath)) {
|
||||
throw new NotAllowedError(
|
||||
'Relative path is not allowed to refer to a directory outside its parent',
|
||||
);
|
||||
}
|
||||
|
||||
return targetPath;
|
||||
}
|
||||
|
||||
// Re-export isChildPath so that backend packages don't need to depend on cli-common
|
||||
export { isChildPath };
|
||||
|
||||
@@ -142,7 +142,7 @@ describe('BitbucketUrlReader', () => {
|
||||
),
|
||||
),
|
||||
rest.get(
|
||||
'https://api.bitbucket.mycompany.net/rest/api/1.0/projects/backstage/repos/mock/archive?format=tgz&prefix=mock&path=docs',
|
||||
'https://api.bitbucket.mycompany.net/rest/api/1.0/projects/backstage/repos/mock/archive',
|
||||
(_, res, ctx) =>
|
||||
res(
|
||||
ctx.status(200),
|
||||
@@ -366,7 +366,7 @@ describe('BitbucketUrlReader', () => {
|
||||
beforeEach(() => {
|
||||
worker.use(
|
||||
rest.get(
|
||||
'https://api.bitbucket.mycompany.net/rest/api/1.0/projects/backstage/repos/mock/archive?format=tgz&prefix=mock&path=docs',
|
||||
'https://api.bitbucket.mycompany.net/rest/api/1.0/projects/backstage/repos/mock/archive',
|
||||
(_, res, ctx) =>
|
||||
res(
|
||||
ctx.status(200),
|
||||
|
||||
@@ -118,7 +118,7 @@ describe('GithubUrlReader', () => {
|
||||
|
||||
worker.use(
|
||||
rest.get(
|
||||
'https://ghe.github.com/api/v3/repos/backstage/mock/tree/contents/?ref=main',
|
||||
'https://ghe.github.com/api/v3/repos/backstage/mock/tree/contents/',
|
||||
(req, res, ctx) => {
|
||||
expect(req.headers.get('authorization')).toBe(
|
||||
mockHeaders.Authorization,
|
||||
|
||||
@@ -182,7 +182,7 @@ describe('GitlabUrlReader', () => {
|
||||
|
||||
describe('readTree', () => {
|
||||
const archiveBuffer = fs.readFileSync(
|
||||
path.resolve('src', 'reading', '__fixtures__', 'gitlab-archive.zip'),
|
||||
path.resolve('src', 'reading', '__fixtures__', 'gitlab-archive.tar.gz'),
|
||||
);
|
||||
|
||||
const projectGitlabApiResponse = {
|
||||
@@ -205,7 +205,7 @@ describe('GitlabUrlReader', () => {
|
||||
beforeEach(() => {
|
||||
worker.use(
|
||||
rest.get(
|
||||
'https://gitlab.com/api/v4/projects/backstage%2Fmock/repository/archive.zip?sha=main',
|
||||
'https://gitlab.com/api/v4/projects/backstage%2Fmock/repository/archive',
|
||||
(_, res, ctx) =>
|
||||
res(
|
||||
ctx.status(200),
|
||||
@@ -283,7 +283,7 @@ describe('GitlabUrlReader', () => {
|
||||
},
|
||||
),
|
||||
rest.get(
|
||||
'https://gitlab.mycompany.com/api/v4/projects/backstage%2Fmock/repository/archive.zip?sha=main',
|
||||
'https://gitlab.mycompany.com/api/v4/projects/backstage%2Fmock/repository/archive',
|
||||
(_, res, ctx) =>
|
||||
res(
|
||||
ctx.status(200),
|
||||
@@ -306,8 +306,8 @@ describe('GitlabUrlReader', () => {
|
||||
const files = await response.files();
|
||||
expect(files.length).toBe(2);
|
||||
|
||||
const mkDocsFile = await files[0].content();
|
||||
const indexMarkdownFile = await files[1].content();
|
||||
const indexMarkdownFile = await files[0].content();
|
||||
const mkDocsFile = await files[1].content();
|
||||
|
||||
expect(mkDocsFile.toString()).toBe('site_name: Test\n');
|
||||
expect(indexMarkdownFile.toString()).toBe('# Test\n');
|
||||
@@ -318,7 +318,7 @@ describe('GitlabUrlReader', () => {
|
||||
'https://gitlab.com/backstage/mock',
|
||||
);
|
||||
|
||||
const dir = await response.dir({ targetDir: '/tmp' });
|
||||
const dir = await response.dir({ targetDir: tmpDir });
|
||||
|
||||
await expect(
|
||||
fs.readFile(path.join(dir, 'mkdocs.yml'), 'utf8'),
|
||||
@@ -331,7 +331,7 @@ describe('GitlabUrlReader', () => {
|
||||
it('returns the wanted files from hosted gitlab', async () => {
|
||||
worker.use(
|
||||
rest.get(
|
||||
'https://gitlab.mycompany.com/backstage/mock/-/archive/main.zip',
|
||||
'https://gitlab.mycompany.com/backstage/mock/-/archive/main.tar.gz',
|
||||
(_, res, ctx) =>
|
||||
res(
|
||||
ctx.status(200),
|
||||
@@ -375,7 +375,7 @@ describe('GitlabUrlReader', () => {
|
||||
'https://gitlab.com/backstage/mock/tree/main/docs',
|
||||
);
|
||||
|
||||
const dir = await response.dir({ targetDir: '/tmp' });
|
||||
const dir = await response.dir({ targetDir: tmpDir });
|
||||
|
||||
await expect(
|
||||
fs.readFile(path.join(dir, 'index.md'), 'utf8'),
|
||||
@@ -454,7 +454,7 @@ describe('GitlabUrlReader', () => {
|
||||
|
||||
describe('search', () => {
|
||||
const archiveBuffer = fs.readFileSync(
|
||||
path.resolve('src', 'reading', '__fixtures__', 'gitlab-archive.zip'),
|
||||
path.resolve('src', 'reading', '__fixtures__', 'gitlab-archive.tar.gz'),
|
||||
);
|
||||
|
||||
const projectGitlabApiResponse = {
|
||||
@@ -471,7 +471,7 @@ describe('GitlabUrlReader', () => {
|
||||
beforeEach(() => {
|
||||
worker.use(
|
||||
rest.get(
|
||||
'https://gitlab.com/api/v4/projects/backstage%2Fmock/repository/archive.zip?sha=main',
|
||||
'https://gitlab.com/api/v4/projects/backstage%2Fmock/repository/archive',
|
||||
(_, res, ctx) =>
|
||||
res(
|
||||
ctx.status(200),
|
||||
|
||||
@@ -139,7 +139,7 @@ export class GitlabUrlReader implements UrlReader {
|
||||
const archiveGitLabResponse = await fetch(
|
||||
`${this.integration.config.apiBaseUrl}/projects/${encodeURIComponent(
|
||||
full_name,
|
||||
)}/repository/archive.zip?sha=${branch}`,
|
||||
)}/repository/archive?sha=${branch}`,
|
||||
getGitLabRequestOptions(this.integration.config),
|
||||
);
|
||||
if (!archiveGitLabResponse.ok) {
|
||||
@@ -150,7 +150,7 @@ export class GitlabUrlReader implements UrlReader {
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
return await this.deps.treeResponseFactory.fromZipArchive({
|
||||
return await this.deps.treeResponseFactory.fromTarArchive({
|
||||
stream: (archiveGitLabResponse.body as unknown) as Readable,
|
||||
subpath: filepath,
|
||||
etag: commitSha,
|
||||
|
||||
Binary file not shown.
@@ -1,5 +1,18 @@
|
||||
# example-backend
|
||||
|
||||
## 0.2.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/plugin-scaffolder-backend@0.12.4
|
||||
- @backstage/backend-common@0.8.4
|
||||
- @backstage/plugin-auth-backend@0.3.15
|
||||
- @backstage/plugin-catalog-backend@0.11.0
|
||||
- @backstage/plugin-techdocs-backend@0.8.5
|
||||
- @backstage/catalog-client@0.3.15
|
||||
- @backstage/plugin-kafka-backend@0.2.7
|
||||
|
||||
## 0.2.32
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "example-backend",
|
||||
"version": "0.2.32",
|
||||
"version": "0.2.35",
|
||||
"main": "dist/index.cjs.js",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
@@ -27,24 +27,24 @@
|
||||
"migrate:create": "knex migrate:make -x ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-common": "^0.8.2",
|
||||
"@backstage/catalog-client": "^0.3.13",
|
||||
"@backstage/backend-common": "^0.8.4",
|
||||
"@backstage/catalog-client": "^0.3.15",
|
||||
"@backstage/catalog-model": "^0.8.2",
|
||||
"@backstage/config": "^0.1.5",
|
||||
"@backstage/plugin-app-backend": "^0.3.13",
|
||||
"@backstage/plugin-auth-backend": "^0.3.12",
|
||||
"@backstage/plugin-auth-backend": "^0.3.15",
|
||||
"@backstage/plugin-badges-backend": "^0.1.6",
|
||||
"@backstage/plugin-catalog-backend": "^0.10.2",
|
||||
"@backstage/plugin-catalog-backend": "^0.11.0",
|
||||
"@backstage/plugin-code-coverage-backend": "^0.1.6",
|
||||
"@backstage/plugin-graphql-backend": "^0.1.8",
|
||||
"@backstage/plugin-kubernetes-backend": "^0.3.8",
|
||||
"@backstage/plugin-kafka-backend": "^0.2.6",
|
||||
"@backstage/plugin-kafka-backend": "^0.2.7",
|
||||
"@backstage/plugin-proxy-backend": "^0.2.9",
|
||||
"@backstage/plugin-rollbar-backend": "^0.1.11",
|
||||
"@backstage/plugin-scaffolder-backend": "^0.12.0",
|
||||
"@backstage/plugin-scaffolder-backend": "^0.12.4",
|
||||
"@backstage/plugin-search-backend": "^0.2.0",
|
||||
"@backstage/plugin-search-backend-node": "^0.2.0",
|
||||
"@backstage/plugin-techdocs-backend": "^0.8.2",
|
||||
"@backstage/plugin-techdocs-backend": "^0.8.5",
|
||||
"@backstage/plugin-todo-backend": "^0.1.6",
|
||||
"@gitbeaker/node": "^30.2.0",
|
||||
"@octokit/rest": "^18.5.3",
|
||||
@@ -60,7 +60,7 @@
|
||||
"winston": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.7.0",
|
||||
"@backstage/cli": "^0.7.3",
|
||||
"@types/dockerode": "^3.2.1",
|
||||
"@types/express": "^4.17.6",
|
||||
"@types/express-serve-static-core": "^4.17.5"
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @backstage/catalog-client
|
||||
|
||||
## 0.3.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- ca080cab8: Don't crash if the entities response doesn't include the entities name and kind
|
||||
|
||||
## 0.3.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@backstage/catalog-client",
|
||||
"version": "0.3.14",
|
||||
"version": "0.3.15",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
@@ -35,7 +35,7 @@
|
||||
"cross-fetch": "^3.0.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.7.2",
|
||||
"@backstage/cli": "^0.7.3",
|
||||
"@types/jest": "^26.0.7",
|
||||
"msw": "^0.29.0"
|
||||
},
|
||||
|
||||
@@ -151,6 +151,26 @@ describe('CatalogClient', () => {
|
||||
|
||||
expect(response.items).toEqual([]);
|
||||
});
|
||||
|
||||
it('handles field filtered entities', async () => {
|
||||
server.use(
|
||||
rest.get(`${mockBaseUrl}/entities`, (_req, res, ctx) => {
|
||||
return res(ctx.json([{ apiVersion: '1' }, { apiVersion: '2' }]));
|
||||
}),
|
||||
);
|
||||
|
||||
const response = await client.getEntities(
|
||||
{
|
||||
fields: ['apiVersion'],
|
||||
},
|
||||
{ token },
|
||||
);
|
||||
|
||||
expect(response.items).toEqual([
|
||||
{ apiVersion: '1' },
|
||||
{ apiVersion: '2' },
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getLocationById', () => {
|
||||
|
||||
@@ -92,6 +92,16 @@ export class CatalogClient implements CatalogApi {
|
||||
);
|
||||
|
||||
const refCompare = (a: Entity, b: Entity) => {
|
||||
// in case field filtering is used, these fields might not be part of the response
|
||||
if (
|
||||
a.metadata?.name === undefined ||
|
||||
a.kind === undefined ||
|
||||
b.metadata?.name === undefined ||
|
||||
b.kind === undefined
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const aRef = stringifyEntityRef(a);
|
||||
const bRef = stringifyEntityRef(b);
|
||||
if (aRef < bRef) {
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
# @backstage/cli-common
|
||||
|
||||
## 0.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- ab5cc376f: Add new `isChildPath` export
|
||||
@@ -7,6 +7,9 @@
|
||||
// @public
|
||||
export function findPaths(searchDir: string): Paths;
|
||||
|
||||
// @public
|
||||
export function isChildPath(base: string, path: string): boolean;
|
||||
|
||||
// @public (undocumented)
|
||||
export type Paths = {
|
||||
ownDir: string;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/cli-common",
|
||||
"description": "Common functionality used by cli, backend, and create-app",
|
||||
"version": "0.1.1",
|
||||
"version": "0.1.2",
|
||||
"private": false,
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
|
||||
@@ -15,4 +15,5 @@
|
||||
*/
|
||||
|
||||
export { findPaths } from './paths';
|
||||
export { isChildPath } from './isChildPath';
|
||||
export type { Paths } from './paths';
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2021 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { posix, win32 } from 'path';
|
||||
|
||||
describe('isChildPath', () => {
|
||||
it('should check child posix paths', () => {
|
||||
jest.isolateModules(() => {
|
||||
jest.setMock('path', posix);
|
||||
const { isChildPath } = require('./isChildPath');
|
||||
|
||||
expect(isChildPath('/', '/')).toBe(true);
|
||||
expect(isChildPath('/x', '/x')).toBe(true);
|
||||
expect(isChildPath('/x', '/x/y')).toBe(true);
|
||||
expect(isChildPath('/x', '/x/x')).toBe(true);
|
||||
expect(isChildPath('/x', '/x/y/z')).toBe(true);
|
||||
expect(isChildPath('/x/y', '/x/y/z')).toBe(true);
|
||||
expect(isChildPath('/x/y/z', '/x/y/z')).toBe(true);
|
||||
expect(isChildPath('/x/a b c/z', '/x/a b c/z')).toBe(true);
|
||||
expect(isChildPath('/', '/ yz')).toBe(true);
|
||||
|
||||
expect(isChildPath('/x', '/y')).toBe(false);
|
||||
expect(isChildPath('/x', '/')).toBe(false);
|
||||
expect(isChildPath('/x', '/x y')).toBe(false);
|
||||
expect(isChildPath('/x y', '/x yz')).toBe(false);
|
||||
expect(isChildPath('/ yz', '/')).toBe(false);
|
||||
expect(isChildPath('/x', '/')).toBe(false);
|
||||
|
||||
jest.dontMock('path');
|
||||
});
|
||||
});
|
||||
|
||||
it('should check child win32 paths', () => {
|
||||
jest.isolateModules(() => {
|
||||
jest.setMock('path', win32);
|
||||
const { isChildPath } = require('./isChildPath');
|
||||
|
||||
expect(isChildPath('/x', '/x')).toBe(true);
|
||||
expect(isChildPath('/x', '/x/y')).toBe(true);
|
||||
expect(isChildPath('/x', '/x/x')).toBe(true);
|
||||
expect(isChildPath('/x', '/x/y/z')).toBe(true);
|
||||
expect(isChildPath('/x/y', '/x/y/z')).toBe(true);
|
||||
expect(isChildPath('/x/y/z', '/x/y/z')).toBe(true);
|
||||
expect(isChildPath('Z:', 'Z:')).toBe(true);
|
||||
expect(isChildPath('C:/', 'c:/')).toBe(true);
|
||||
expect(isChildPath('C:/x', 'C:/x')).toBe(true);
|
||||
expect(isChildPath('C:/x', 'c:/x')).toBe(true);
|
||||
expect(isChildPath('C:/x', 'C:/x/y')).toBe(true);
|
||||
expect(isChildPath('d:/x', 'D:/x/y')).toBe(true);
|
||||
|
||||
expect(isChildPath('/x', '/y')).toBe(false);
|
||||
expect(isChildPath('/x', '/')).toBe(false);
|
||||
expect(isChildPath('C:/', 'D:/')).toBe(false);
|
||||
expect(isChildPath('C:/x', 'D:/x')).toBe(false);
|
||||
expect(isChildPath('D:/x', 'CD:/x')).toBe(false);
|
||||
expect(isChildPath('D:/x', 'D:/y')).toBe(false);
|
||||
|
||||
jest.dontMock('path');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2021 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { relative, isAbsolute } from 'path';
|
||||
|
||||
/**
|
||||
* Checks if path is the same as or a child path of base.
|
||||
*/
|
||||
export function isChildPath(base: string, path: string): boolean {
|
||||
const relativePath = relative(base, path);
|
||||
if (relativePath === '') {
|
||||
// The same directory
|
||||
return true;
|
||||
}
|
||||
|
||||
const outsideBase = relativePath.startsWith('..'); // not outside base
|
||||
const differentDrive = isAbsolute(relativePath); // on Windows, this means dir is on a different drive from base.
|
||||
|
||||
return !outsideBase && !differentDrive;
|
||||
}
|
||||
@@ -1,5 +1,15 @@
|
||||
# @backstage/cli
|
||||
|
||||
## 0.7.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- a93e60fdc: Updated dependencies
|
||||
- 55f49fcc7: Update dependencies
|
||||
- ab5cc376f: Use new `isChildPath` export from `@backstage/cli-common`
|
||||
- Updated dependencies
|
||||
- @backstage/cli-common@0.1.2
|
||||
|
||||
## 0.7.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/cli",
|
||||
"description": "CLI for developing Backstage plugins and apps",
|
||||
"version": "0.7.2",
|
||||
"version": "0.7.3",
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
@@ -30,7 +30,7 @@
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.4.4",
|
||||
"@babel/plugin-transform-modules-commonjs": "^7.4.4",
|
||||
"@backstage/cli-common": "^0.1.1",
|
||||
"@backstage/cli-common": "^0.1.2",
|
||||
"@backstage/config": "^0.1.5",
|
||||
"@backstage/config-loader": "^0.6.4",
|
||||
"@hot-loader/react-dom": "^16.13.0",
|
||||
@@ -40,7 +40,7 @@
|
||||
"@rollup/plugin-commonjs": "^17.1.0",
|
||||
"@rollup/plugin-json": "^4.0.2",
|
||||
"@rollup/plugin-node-resolve": "^13.0.0",
|
||||
"@rollup/plugin-yaml": "^2.1.1",
|
||||
"@rollup/plugin-yaml": "^3.0.0",
|
||||
"@spotify/eslint-config-base": "^9.0.0",
|
||||
"@spotify/eslint-config-react": "^10.0.0",
|
||||
"@spotify/eslint-config-typescript": "^10.0.0",
|
||||
@@ -61,7 +61,7 @@
|
||||
"chalk": "^4.0.0",
|
||||
"chokidar": "^3.3.1",
|
||||
"commander": "^6.1.0",
|
||||
"css-loader": "^3.5.3",
|
||||
"css-loader": "^5.2.6",
|
||||
"dashify": "^2.0.0",
|
||||
"diff": "^5.0.0",
|
||||
"esbuild": "^0.8.56",
|
||||
@@ -118,11 +118,11 @@
|
||||
"yn": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/backend-common": "^0.8.3",
|
||||
"@backstage/backend-common": "^0.8.4",
|
||||
"@backstage/config": "^0.1.5",
|
||||
"@backstage/core-components": "^0.1.3",
|
||||
"@backstage/core-components": "^0.1.4",
|
||||
"@backstage/core-plugin-api": "^0.1.3",
|
||||
"@backstage/core-app-api": "^0.1.3",
|
||||
"@backstage/core-app-api": "^0.1.4",
|
||||
"@backstage/dev-utils": "^0.2.0",
|
||||
"@backstage/test-utils": "^0.1.14",
|
||||
"@backstage/theme": "^0.2.8",
|
||||
@@ -146,7 +146,7 @@
|
||||
"del": "^6.0.0",
|
||||
"mock-fs": "^4.13.0",
|
||||
"nodemon": "^2.0.2",
|
||||
"ts-node": "^9.1.1"
|
||||
"ts-node": "^10.0.0"
|
||||
},
|
||||
"files": [
|
||||
"asset-types",
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
import { resolve as resolvePath } from 'path';
|
||||
import { ResolvePlugin } from 'webpack';
|
||||
import { isChildPath } from './paths';
|
||||
import { isChildPath } from '@backstage/cli-common';
|
||||
import { LernaPackage } from './types';
|
||||
|
||||
// Enables proper resolution of packages when linking in external packages.
|
||||
|
||||
@@ -22,9 +22,10 @@ import ModuleScopePlugin from 'react-dev-utils/ModuleScopePlugin';
|
||||
import StartServerPlugin from 'start-server-webpack-plugin';
|
||||
import webpack from 'webpack';
|
||||
import nodeExternals from 'webpack-node-externals';
|
||||
import { isChildPath } from '@backstage/cli-common';
|
||||
import { optimization } from './optimization';
|
||||
import { Config } from '@backstage/config';
|
||||
import { BundlingPaths, isChildPath } from './paths';
|
||||
import { BundlingPaths } from './paths';
|
||||
import { transforms } from './transforms';
|
||||
import { LinkedPackageResolvePlugin } from './LinkedPackageResolvePlugin';
|
||||
import { BundlingOptions, BackendBundlingOptions, LernaPackage } from './types';
|
||||
|
||||
@@ -15,25 +15,8 @@
|
||||
*/
|
||||
|
||||
import fs from 'fs-extra';
|
||||
import path from 'path';
|
||||
import { paths } from '../paths';
|
||||
|
||||
/**
|
||||
* Checks if dir is the same as or a child of base.
|
||||
*/
|
||||
export function isChildPath(base: string, dir: string): boolean {
|
||||
const relativePath = path.relative(base, dir);
|
||||
if (relativePath === '') {
|
||||
// The same directory
|
||||
return true;
|
||||
}
|
||||
|
||||
const outsideBase = relativePath.startsWith('..'); // not outside base
|
||||
const differentDrive = path.isAbsolute(relativePath); // on Windows, this means dir is on a different drive from base.
|
||||
|
||||
return !outsideBase && !differentDrive;
|
||||
}
|
||||
|
||||
export type BundlingPathsOptions = {
|
||||
// bundle entrypoint, e.g. 'src/index'
|
||||
entry: string;
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# @backstage/codemods
|
||||
|
||||
## 0.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/core-app-api@0.1.4
|
||||
- @backstage/core-components@0.1.4
|
||||
- @backstage/cli-common@0.1.2
|
||||
|
||||
## 0.1.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/codemods",
|
||||
"description": "A collection of codemods for Backstage projects",
|
||||
"version": "0.1.3",
|
||||
"version": "0.1.4",
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
@@ -31,7 +31,7 @@
|
||||
"backstage-codemods": "bin/backstage-codemods"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/cli-common": "0.1.1",
|
||||
"@backstage/cli-common": "0.1.2",
|
||||
"@backstage/core-app-api": "*",
|
||||
"@backstage/core-components": "*",
|
||||
"@backstage/core-plugin-api": "*",
|
||||
@@ -43,7 +43,7 @@
|
||||
"@types/jscodeshift": "^0.11.0",
|
||||
"@types/node": "^14.14.32",
|
||||
"commander": "^6.1.0",
|
||||
"ts-node": "^9.1.1"
|
||||
"ts-node": "^10.0.0"
|
||||
},
|
||||
"nodemonConfig": {
|
||||
"watch": "./src",
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# @backstage/core-app-api
|
||||
|
||||
## 0.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 62abffee4: Reintroduce export of `defaultConfigLoader`.
|
||||
- Updated dependencies
|
||||
- @backstage/core-components@0.1.4
|
||||
|
||||
## 0.1.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/core-app-api",
|
||||
"description": "Core app API used by Backstage apps",
|
||||
"version": "0.1.3",
|
||||
"version": "0.1.4",
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
@@ -29,7 +29,7 @@
|
||||
"clean": "backstage-cli clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/core-components": "^0.1.2",
|
||||
"@backstage/core-components": "^0.1.4",
|
||||
"@backstage/config": "^0.1.3",
|
||||
"@backstage/core-plugin-api": "^0.1.3",
|
||||
"@backstage/theme": "^0.2.8",
|
||||
@@ -44,7 +44,7 @@
|
||||
"zen-observable": "^0.8.15"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.7.2",
|
||||
"@backstage/cli": "^0.7.3",
|
||||
"@backstage/test-utils": "^0.1.14",
|
||||
"@backstage/test-utils-core": "^0.1.1",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
|
||||
@@ -1,5 +1,41 @@
|
||||
# @backstage/core-components
|
||||
|
||||
## 0.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f423891ee: Fixed sizing of the System diagram when the rendered graph was wider than the container.
|
||||
- 3db266fe4: Make `ErrorBoundary` display more helpful information about the error that
|
||||
occurred.
|
||||
|
||||
The `slackChannel` (optional) prop can now be passed as an object on the form
|
||||
`{ name: string; href?: string; }` in addition to the old string form. If you
|
||||
are using the error boundary like
|
||||
|
||||
```tsx
|
||||
<ErrorBoundary slackChannel="#support">
|
||||
<InnerComponent>
|
||||
</ErrorBoundary>
|
||||
```
|
||||
|
||||
you may like to migrate it to
|
||||
|
||||
```tsx
|
||||
const support = {
|
||||
name: '#support',
|
||||
href: 'https://slack.com/channels/your-channel',
|
||||
};
|
||||
|
||||
<ErrorBoundary slackChannel={support}>
|
||||
<InnerComponent>
|
||||
</ErrorBoundary>
|
||||
```
|
||||
|
||||
Also deprecated the prop `slackChannel` on `TabbedCard` and `InfoCard`, while
|
||||
adding the prop `errorBoundaryProps` to replace it.
|
||||
|
||||
- e8c65b068: Clear the previously selected sign-in provider on failure
|
||||
|
||||
## 0.1.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/core-components",
|
||||
"description": "Core components used by Backstage plugins and apps",
|
||||
"version": "0.1.3",
|
||||
"version": "0.1.4",
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
@@ -70,8 +70,8 @@
|
||||
"zen-observable": "^0.8.15"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/core-app-api": "^0.1.2",
|
||||
"@backstage/cli": "^0.7.1",
|
||||
"@backstage/core-app-api": "^0.1.4",
|
||||
"@backstage/cli": "^0.7.3",
|
||||
"@backstage/test-utils": "^0.1.13",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
"@testing-library/react": "^11.2.5",
|
||||
|
||||
@@ -262,7 +262,7 @@ export function DependencyGraph({
|
||||
<svg
|
||||
ref={containerRef}
|
||||
{...svgProps}
|
||||
width={maxWidth}
|
||||
width="100%"
|
||||
height={maxHeight}
|
||||
viewBox={`0 0 ${maxWidth} ${maxHeight}`}
|
||||
>
|
||||
|
||||
@@ -107,6 +107,7 @@ export const WarningPanel = (props: Props) => {
|
||||
<Accordion
|
||||
defaultExpanded={defaultExpanded ?? false}
|
||||
className={classes.panel}
|
||||
role="alert"
|
||||
>
|
||||
<AccordionSummary
|
||||
expandIcon={<ExpandMoreIconStyled />}
|
||||
|
||||
@@ -17,7 +17,13 @@
|
||||
|
||||
import React from 'react';
|
||||
import { ErrorBoundary } from './ErrorBoundary';
|
||||
import { renderInTestApp, withLogCollector } from '@backstage/test-utils';
|
||||
import {
|
||||
MockErrorApi,
|
||||
renderInTestApp,
|
||||
withLogCollector,
|
||||
} from '@backstage/test-utils';
|
||||
import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
|
||||
import { errorApiRef } from '@backstage/core-plugin-api';
|
||||
|
||||
type BombProps = {
|
||||
shouldThrow?: boolean;
|
||||
@@ -35,28 +41,33 @@ const Bomb = ({ shouldThrow }: BombProps) => {
|
||||
describe('<ErrorBoundary/>', () => {
|
||||
it('should render error boundary with and without error', async () => {
|
||||
const { error } = await withLogCollector(['error'], async () => {
|
||||
const apis = ApiRegistry.with(errorApiRef, new MockErrorApi());
|
||||
const {
|
||||
rerender,
|
||||
queryByRole,
|
||||
getByRole,
|
||||
getByText,
|
||||
} = await renderInTestApp(
|
||||
<ErrorBoundary>
|
||||
<Bomb />
|
||||
</ErrorBoundary>,
|
||||
<ApiProvider apis={apis}>
|
||||
<ErrorBoundary>
|
||||
<Bomb />
|
||||
</ErrorBoundary>
|
||||
</ApiProvider>,
|
||||
);
|
||||
|
||||
expect(queryByRole('alert')).not.toBeInTheDocument();
|
||||
expect(getByText(/working component/i)).toBeInTheDocument();
|
||||
|
||||
rerender(
|
||||
<ErrorBoundary>
|
||||
<Bomb shouldThrow />
|
||||
</ErrorBoundary>,
|
||||
<ApiProvider apis={apis}>
|
||||
<ErrorBoundary>
|
||||
<Bomb shouldThrow />
|
||||
</ErrorBoundary>
|
||||
</ApiProvider>,
|
||||
);
|
||||
|
||||
expect(getByRole('alert')).toBeInTheDocument();
|
||||
expect(getByText(/something went wrong here/i)).toBeInTheDocument();
|
||||
expect(getByText(/something went wrong/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
expect(error).toEqual([
|
||||
|
||||
@@ -15,9 +15,16 @@
|
||||
*/
|
||||
|
||||
import React, { ComponentClass, Component, ErrorInfo } from 'react';
|
||||
import { Button } from '../../components/Button';
|
||||
import { ErrorPanel } from '../../components/ErrorPanel';
|
||||
|
||||
type Props = {
|
||||
slackChannel?: string;
|
||||
type SlackChannel = {
|
||||
name: string;
|
||||
href?: string;
|
||||
};
|
||||
|
||||
export type ErrorBoundaryProps = {
|
||||
slackChannel?: string | SlackChannel;
|
||||
onError?: (error: Error, errorInfo: string) => null;
|
||||
};
|
||||
|
||||
@@ -26,28 +33,30 @@ type State = {
|
||||
errorInfo?: ErrorInfo;
|
||||
};
|
||||
|
||||
type EProps = {
|
||||
error?: Error;
|
||||
slackChannel?: string;
|
||||
children?: React.ReactNode;
|
||||
};
|
||||
const SlackLink = (props: { slackChannel?: string | SlackChannel }) => {
|
||||
const { slackChannel } = props;
|
||||
|
||||
if (!slackChannel) {
|
||||
return null;
|
||||
} else if (typeof slackChannel === 'string') {
|
||||
return <>Please contact {slackChannel} for help.</>;
|
||||
} else if (!slackChannel.href) {
|
||||
return <>Please contact {slackChannel.name} for help.</>;
|
||||
}
|
||||
|
||||
const Error = ({ slackChannel }: EProps) => {
|
||||
return (
|
||||
<div role="alert">
|
||||
Something went wrong here.{' '}
|
||||
{slackChannel && <>Please contact {slackChannel} for help.</>}
|
||||
</div>
|
||||
<Button to={slackChannel.href} variant="contained">
|
||||
{slackChannel.name}
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
export const ErrorBoundary: ComponentClass<
|
||||
Props,
|
||||
ErrorBoundaryProps,
|
||||
State
|
||||
> = class ErrorBoundary extends Component<Props, State> {
|
||||
constructor(props: Props) {
|
||||
> = class ErrorBoundary extends Component<ErrorBoundaryProps, State> {
|
||||
constructor(props: ErrorBoundaryProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
error: undefined,
|
||||
errorInfo: undefined,
|
||||
@@ -61,13 +70,17 @@ export const ErrorBoundary: ComponentClass<
|
||||
}
|
||||
|
||||
render() {
|
||||
const { slackChannel } = this.props;
|
||||
const { error, errorInfo } = this.state;
|
||||
const { slackChannel, children } = this.props;
|
||||
const { error } = this.state;
|
||||
|
||||
if (!errorInfo) {
|
||||
return this.props.children;
|
||||
if (!error) {
|
||||
return children;
|
||||
}
|
||||
|
||||
return <Error error={error} slackChannel={slackChannel} />;
|
||||
return (
|
||||
<ErrorPanel title="Something Went Wrong" error={error}>
|
||||
<SlackLink slackChannel={slackChannel} />
|
||||
</ErrorPanel>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -14,4 +14,5 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export type { ErrorBoundaryProps } from './ErrorBoundary';
|
||||
export { ErrorBoundary } from './ErrorBoundary';
|
||||
|
||||
@@ -26,7 +26,7 @@ import {
|
||||
makeStyles,
|
||||
} from '@material-ui/core';
|
||||
import classNames from 'classnames';
|
||||
import { ErrorBoundary } from '../ErrorBoundary';
|
||||
import { ErrorBoundary, ErrorBoundaryProps } from '../ErrorBoundary';
|
||||
import { BottomLink, BottomLinkProps } from '../BottomLink';
|
||||
|
||||
const useStyles = makeStyles(theme => ({
|
||||
@@ -95,8 +95,8 @@ export type InfoCardVariants = 'flex' | 'fullHeight' | 'gridItem';
|
||||
* You can custom style an InfoCard with the 'style' (outer container) and 'cardStyle' (inner container)
|
||||
* styles.
|
||||
*
|
||||
* The InfoCard serves as an error boundary. As a result, if you provide a 'slackChannel' property this
|
||||
* specifies the channel to display in the error component that is displayed if an error occurs
|
||||
* The InfoCard serves as an error boundary. As a result, if you provide an 'errorBoundaryProps' property this
|
||||
* specifies the extra information to display in the error component that is displayed if an error occurs
|
||||
* in any descendent components.
|
||||
*
|
||||
* By default the InfoCard has no custom layout of its children, but is treated as a block element. A
|
||||
@@ -112,7 +112,9 @@ type Props = {
|
||||
subheader?: ReactNode;
|
||||
divider?: boolean;
|
||||
deepLink?: BottomLinkProps;
|
||||
/** @deprecated Use errorBoundaryProps instead */
|
||||
slackChannel?: string;
|
||||
errorBoundaryProps?: ErrorBoundaryProps;
|
||||
variant?: InfoCardVariants;
|
||||
style?: object;
|
||||
cardStyle?: object;
|
||||
@@ -133,7 +135,8 @@ export const InfoCard = ({
|
||||
subheader,
|
||||
divider = true,
|
||||
deepLink,
|
||||
slackChannel = '#backstage',
|
||||
slackChannel,
|
||||
errorBoundaryProps,
|
||||
variant,
|
||||
children,
|
||||
headerStyle,
|
||||
@@ -169,9 +172,12 @@ export const InfoCard = ({
|
||||
});
|
||||
}
|
||||
|
||||
const errProps: ErrorBoundaryProps =
|
||||
errorBoundaryProps || (slackChannel ? { slackChannel } : {});
|
||||
|
||||
return (
|
||||
<Card style={calculatedStyle} className={className}>
|
||||
<ErrorBoundary slackChannel={slackChannel}>
|
||||
<ErrorBoundary {...errProps}>
|
||||
{title && (
|
||||
<CardHeader
|
||||
classes={{
|
||||
|
||||
@@ -143,6 +143,7 @@ export const useSignInProviders = (
|
||||
if (didCancel) {
|
||||
return;
|
||||
}
|
||||
localStorage.removeItem(PROVIDER_STORAGE_KEY);
|
||||
errorApi.post(error);
|
||||
setLoading(false);
|
||||
});
|
||||
|
||||
@@ -32,7 +32,7 @@ import {
|
||||
TabProps,
|
||||
} from '@material-ui/core';
|
||||
import { BottomLink, BottomLinkProps } from '../BottomLink';
|
||||
import { ErrorBoundary } from '../ErrorBoundary';
|
||||
import { ErrorBoundary, ErrorBoundaryProps } from '../ErrorBoundary';
|
||||
|
||||
const useTabsStyles = makeStyles(theme => ({
|
||||
root: {
|
||||
@@ -52,7 +52,9 @@ const BoldHeader = withStyles(theme => ({
|
||||
}))(CardHeader);
|
||||
|
||||
type Props = {
|
||||
/** @deprecated Use errorBoundaryProps instead */
|
||||
slackChannel?: string;
|
||||
errorBoundaryProps?: ErrorBoundaryProps;
|
||||
children?: ReactElement<TabProps>[];
|
||||
onChange?: (event: React.ChangeEvent<{}>, value: number | string) => void;
|
||||
title?: string;
|
||||
@@ -61,7 +63,8 @@ type Props = {
|
||||
};
|
||||
|
||||
const TabbedCard = ({
|
||||
slackChannel = '#backstage',
|
||||
slackChannel,
|
||||
errorBoundaryProps,
|
||||
children,
|
||||
title,
|
||||
deepLink,
|
||||
@@ -87,9 +90,12 @@ const TabbedCard = ({
|
||||
});
|
||||
}
|
||||
|
||||
const errProps: ErrorBoundaryProps =
|
||||
errorBoundaryProps || (slackChannel ? { slackChannel } : {});
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<ErrorBoundary slackChannel={slackChannel}>
|
||||
<ErrorBoundary {...errProps}>
|
||||
{title && <BoldHeader title={title} />}
|
||||
<Tabs
|
||||
classes={tabsClasses}
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# @backstage/create-app
|
||||
|
||||
## 0.3.29
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/cli-common@0.1.2
|
||||
|
||||
## 0.3.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/create-app",
|
||||
"description": "Create app package for Backstage",
|
||||
"version": "0.3.28",
|
||||
"version": "0.3.29",
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
@@ -27,7 +27,7 @@
|
||||
"start": "nodemon --"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/cli-common": "^0.1.1",
|
||||
"@backstage/cli-common": "^0.1.2",
|
||||
"chalk": "^4.0.0",
|
||||
"commander": "^6.1.0",
|
||||
"fs-extra": "^9.0.0",
|
||||
@@ -41,7 +41,7 @@
|
||||
"@types/inquirer": "^7.3.1",
|
||||
"@types/react-dev-utils": "^9.0.4",
|
||||
"@types/recursive-readdir": "^2.2.0",
|
||||
"ts-node": "^9.1.1"
|
||||
"ts-node": "^10.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@backstage/backend-common": "*",
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
"commander": "^6.1.0",
|
||||
"fs-extra": "^9.0.0",
|
||||
"github-slugger": "^1.3.0",
|
||||
"ts-node": "^9.1.1",
|
||||
"ts-node": "^10.0.0",
|
||||
"typescript": "^4.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
"handlebars": "^4.7.3",
|
||||
"pgtools": "^0.3.0",
|
||||
"tree-kill": "^1.2.2",
|
||||
"ts-node": "^9.1.1",
|
||||
"ts-node": "^10.0.0",
|
||||
"zombie": "^6.1.4"
|
||||
},
|
||||
"nodemonConfig": {
|
||||
|
||||
@@ -1,5 +1,51 @@
|
||||
# @backstage/integration
|
||||
|
||||
## 0.5.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 22a60518c: Support ingesting multiple GitHub organizations via a new `GithubMultiOrgReaderProcessor`.
|
||||
|
||||
This new processor handles namespacing created groups according to the org of the associated GitHub team to prevent potential name clashes between organizations. Be aware that this processor is considered alpha and may not be compatible with future org structures in the catalog.
|
||||
|
||||
NOTE: This processor only fully supports auth via GitHub Apps
|
||||
|
||||
To install this processor, import and add it as follows:
|
||||
|
||||
```typescript
|
||||
// Typically in packages/backend/src/plugins/catalog.ts
|
||||
import { GithubMultiOrgReaderProcessor } from '@backstage/plugin-catalog-backend';
|
||||
// ...
|
||||
export default async function createPlugin(env: PluginEnvironment) {
|
||||
const builder = new CatalogBuilder(env);
|
||||
builder.addProcessor(
|
||||
GithubMultiOrgReaderProcessor.fromConfig(env.config, {
|
||||
logger: env.logger,
|
||||
}),
|
||||
);
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
Configure in your `app-config.yaml` by pointing to your GitHub instance and optionally list which GitHub organizations you wish to import. You can also configure what namespace you want to set for teams from each org. If unspecified, the org name will be used as the namespace. If no organizations are listed, by default this processor will import from all organizations accessible by all configured GitHub Apps:
|
||||
|
||||
```yaml
|
||||
catalog:
|
||||
locations:
|
||||
- type: github-multi-org
|
||||
target: https://github.myorg.com
|
||||
|
||||
processors:
|
||||
githubMultiOrg:
|
||||
orgs:
|
||||
- name: fooOrg
|
||||
groupNamespace: foo
|
||||
- name: barOrg
|
||||
groupNamespace: bar
|
||||
- name: awesomeOrg
|
||||
- name: anotherOrg
|
||||
```
|
||||
|
||||
## 0.5.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
```ts
|
||||
|
||||
import { Config } from '@backstage/config';
|
||||
import { RestEndpointMethodTypes } from '@octokit/rest';
|
||||
|
||||
// @public (undocumented)
|
||||
export class AzureIntegration implements ScmIntegration {
|
||||
@@ -106,6 +107,15 @@ export function getGitLabFileFetchUrl(url: string, config: GitLabIntegrationConf
|
||||
// @public
|
||||
export function getGitLabRequestOptions(config: GitLabIntegrationConfig): RequestInit;
|
||||
|
||||
// @public (undocumented)
|
||||
export class GithubAppCredentialsMux {
|
||||
constructor(config: GitHubIntegrationConfig);
|
||||
// (undocumented)
|
||||
getAllInstallations(): Promise<RestEndpointMethodTypes['apps']['listInstallations']['response']['data']>;
|
||||
// (undocumented)
|
||||
getAppToken(owner: string, repo?: string): Promise<string | undefined>;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export class GithubCredentialsProvider {
|
||||
// (undocumented)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@backstage/integration",
|
||||
"version": "0.5.6",
|
||||
"version": "0.5.7",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
@@ -37,7 +37,7 @@
|
||||
"luxon": "^1.25.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.7.0",
|
||||
"@backstage/cli": "^0.7.3",
|
||||
"@backstage/config-loader": "^0.6.3",
|
||||
"@backstage/test-utils": "^0.1.13",
|
||||
"@types/jest": "^26.0.7",
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
const octokit = {
|
||||
paginate: async (fn: any) => (await fn()).data,
|
||||
apps: {
|
||||
listInstallations: jest.fn(),
|
||||
createInstallationAccessToken: jest.fn(),
|
||||
@@ -53,7 +54,7 @@ describe('GithubCredentialsProvider tests', () => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
it('create repository specific tokens', async () => {
|
||||
octokit.apps.listInstallations.mockResolvedValueOnce({
|
||||
octokit.apps.listInstallations.mockResolvedValue({
|
||||
headers: {
|
||||
etag: '123',
|
||||
},
|
||||
@@ -72,7 +73,6 @@ describe('GithubCredentialsProvider tests', () => {
|
||||
},
|
||||
],
|
||||
} as RestEndpointMethodTypes['apps']['listInstallations']['response']);
|
||||
octokit.apps.listInstallations.mockRejectedValue({ status: 304 });
|
||||
|
||||
octokit.apps.createInstallationAccessToken.mockResolvedValueOnce({
|
||||
data: {
|
||||
@@ -84,12 +84,8 @@ describe('GithubCredentialsProvider tests', () => {
|
||||
const { token, headers, type } = await github.getCredentials({
|
||||
url: 'https://github.com/backstage/foobar',
|
||||
});
|
||||
const { token: accessToken2 } = await github.getCredentials({
|
||||
url: 'https://github.com/backstage/foobar',
|
||||
});
|
||||
expect(type).toEqual('app');
|
||||
expect(token).toEqual('secret_token');
|
||||
expect(token).toEqual(accessToken2);
|
||||
expect(headers).toEqual({ Authorization: 'Bearer secret_token' });
|
||||
|
||||
// fallback to the configured token if no application is matching
|
||||
@@ -107,7 +103,7 @@ describe('GithubCredentialsProvider tests', () => {
|
||||
});
|
||||
|
||||
it('creates tokens for an organization', async () => {
|
||||
octokit.apps.listInstallations.mockResolvedValueOnce({
|
||||
octokit.apps.listInstallations.mockResolvedValue({
|
||||
headers: {
|
||||
etag: '123',
|
||||
},
|
||||
@@ -121,7 +117,6 @@ describe('GithubCredentialsProvider tests', () => {
|
||||
},
|
||||
],
|
||||
} as RestEndpointMethodTypes['apps']['listInstallations']['response']);
|
||||
octokit.apps.listInstallations.mockRejectedValue({ status: 304 });
|
||||
|
||||
octokit.apps.createInstallationAccessToken.mockResolvedValueOnce({
|
||||
data: {
|
||||
@@ -133,17 +128,13 @@ describe('GithubCredentialsProvider tests', () => {
|
||||
const { token, headers } = await github.getCredentials({
|
||||
url: 'https://github.com/backstage',
|
||||
});
|
||||
const { token: accessToken2 } = await github.getCredentials({
|
||||
url: 'https://github.com/backstage',
|
||||
});
|
||||
|
||||
expect(headers).toEqual({ Authorization: 'Bearer secret_token' });
|
||||
expect(token).toEqual('secret_token');
|
||||
expect(token).toEqual(accessToken2);
|
||||
});
|
||||
|
||||
it('should fail to issue tokens for an organization when the app is installed for a single repo', async () => {
|
||||
octokit.apps.listInstallations.mockResolvedValueOnce({
|
||||
octokit.apps.listInstallations.mockResolvedValue({
|
||||
headers: {
|
||||
etag: '123',
|
||||
},
|
||||
@@ -157,7 +148,6 @@ describe('GithubCredentialsProvider tests', () => {
|
||||
},
|
||||
],
|
||||
} as RestEndpointMethodTypes['apps']['listInstallations']['response']);
|
||||
octokit.apps.listInstallations.mockRejectedValue({ status: 304 });
|
||||
|
||||
octokit.apps.createInstallationAccessToken.mockResolvedValueOnce({
|
||||
data: {
|
||||
@@ -176,7 +166,7 @@ describe('GithubCredentialsProvider tests', () => {
|
||||
});
|
||||
|
||||
it('should throw if the app is suspended', async () => {
|
||||
octokit.apps.listInstallations.mockResolvedValueOnce({
|
||||
octokit.apps.listInstallations.mockResolvedValue({
|
||||
headers: {
|
||||
etag: '123',
|
||||
},
|
||||
@@ -193,7 +183,6 @@ describe('GithubCredentialsProvider tests', () => {
|
||||
},
|
||||
],
|
||||
} as RestEndpointMethodTypes['apps']['listInstallations']['response']);
|
||||
octokit.apps.listInstallations.mockRejectedValue({ status: 304 });
|
||||
|
||||
await expect(
|
||||
github.getCredentials({
|
||||
@@ -229,7 +218,7 @@ describe('GithubCredentialsProvider tests', () => {
|
||||
).resolves.toEqual(expect.objectContaining({ token: 'fallback_token' }));
|
||||
});
|
||||
|
||||
it('should return the configured token if listing installations throws', async () => {
|
||||
it('should return the configured token if there are no installations', async () => {
|
||||
const githubProvider = GithubCredentialsProvider.create({
|
||||
host: 'github.com',
|
||||
apps: [
|
||||
@@ -243,7 +232,9 @@ describe('GithubCredentialsProvider tests', () => {
|
||||
],
|
||||
token: 'hardcoded_token',
|
||||
});
|
||||
octokit.apps.listInstallations.mockRejectedValue({ status: 304 });
|
||||
octokit.apps.listInstallations.mockResolvedValue(({
|
||||
data: [],
|
||||
} as unknown) as RestEndpointMethodTypes['apps']['listInstallations']['response']);
|
||||
|
||||
await expect(
|
||||
githubProvider.getCredentials({
|
||||
|
||||
@@ -66,7 +66,6 @@ const HEADERS = {
|
||||
class GithubAppManager {
|
||||
private readonly appClient: Octokit;
|
||||
private readonly baseAuthConfig: { appId: number; privateKey: string };
|
||||
private installations?: RestEndpointMethodTypes['apps']['listInstallations']['response'];
|
||||
private readonly cache = new Cache();
|
||||
|
||||
constructor(config: GithubAppConfig, baseUrl?: string) {
|
||||
@@ -121,22 +120,15 @@ class GithubAppManager {
|
||||
});
|
||||
}
|
||||
|
||||
getInstallations(): Promise<
|
||||
RestEndpointMethodTypes['apps']['listInstallations']['response']['data']
|
||||
> {
|
||||
return this.appClient.paginate(this.appClient.apps.listInstallations);
|
||||
}
|
||||
|
||||
private async getInstallationData(owner: string): Promise<InstallationData> {
|
||||
// List all installations using the last used etag.
|
||||
// Return cached InstallationData if error with status 304 is thrown.
|
||||
try {
|
||||
this.installations = await this.appClient.apps.listInstallations({
|
||||
headers: {
|
||||
'If-None-Match': this.installations?.headers.etag,
|
||||
Accept: HEADERS.Accept,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.status !== 304) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
const installation = this.installations?.data.find(
|
||||
const allInstallations = await this.getInstallations();
|
||||
const installation = allInstallations.find(
|
||||
inst => inst.account?.login === owner,
|
||||
);
|
||||
if (installation) {
|
||||
@@ -163,6 +155,20 @@ export class GithubAppCredentialsMux {
|
||||
config.apps?.map(ac => new GithubAppManager(ac, config.apiBaseUrl)) ?? [];
|
||||
}
|
||||
|
||||
async getAllInstallations(): Promise<
|
||||
RestEndpointMethodTypes['apps']['listInstallations']['response']['data']
|
||||
> {
|
||||
if (!this.apps.length) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const installs = await Promise.all(
|
||||
this.apps.map(app => app.getInstallations()),
|
||||
);
|
||||
|
||||
return installs.flat();
|
||||
}
|
||||
|
||||
async getAppToken(owner: string, repo?: string): Promise<string | undefined> {
|
||||
if (this.apps.length === 0) {
|
||||
return undefined;
|
||||
|
||||
@@ -20,6 +20,9 @@ export {
|
||||
} from './config';
|
||||
export type { GitHubIntegrationConfig } from './config';
|
||||
export { getGitHubFileFetchUrl, getGitHubRequestOptions } from './core';
|
||||
export { GithubCredentialsProvider } from './GithubCredentialsProvider';
|
||||
export {
|
||||
GithubAppCredentialsMux,
|
||||
GithubCredentialsProvider,
|
||||
} from './GithubCredentialsProvider';
|
||||
export type { GithubCredentialType } from './GithubCredentialsProvider';
|
||||
export { GitHubIntegration } from './GitHubIntegration';
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
# @backstage/techdocs-common
|
||||
|
||||
## 0.6.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- ab5cc376f: Use new utilities from `@backstage/backend-common` for safely resolving child paths
|
||||
- b47fc34bc: Update "service catalog" references to "software catalog"
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.8.4
|
||||
- @backstage/integration@0.5.7
|
||||
|
||||
## 0.6.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/techdocs-common",
|
||||
"description": "Common functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli",
|
||||
"version": "0.6.5",
|
||||
"version": "0.6.6",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"private": false,
|
||||
@@ -38,11 +38,11 @@
|
||||
"dependencies": {
|
||||
"@azure/identity": "^1.2.2",
|
||||
"@azure/storage-blob": "^12.4.0",
|
||||
"@backstage/backend-common": "^0.8.2",
|
||||
"@backstage/backend-common": "^0.8.4",
|
||||
"@backstage/catalog-model": "^0.8.4",
|
||||
"@backstage/config": "^0.1.5",
|
||||
"@backstage/errors": "^0.1.1",
|
||||
"@backstage/integration": "^0.5.6",
|
||||
"@backstage/integration": "^0.5.7",
|
||||
"@google-cloud/storage": "^5.6.0",
|
||||
"@types/express": "^4.17.6",
|
||||
"aws-sdk": "^2.840.0",
|
||||
@@ -60,7 +60,7 @@
|
||||
"winston": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.7.2",
|
||||
"@backstage/cli": "^0.7.3",
|
||||
"@types/fs-extra": "^9.0.5",
|
||||
"@types/git-url-parse": "^9.0.0",
|
||||
"@types/js-yaml": "^4.0.0",
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { isChildPath } from '@backstage/backend-common';
|
||||
import { spawn } from 'child_process';
|
||||
import fs from 'fs-extra';
|
||||
import yaml, { DEFAULT_SCHEMA, Type } from 'js-yaml';
|
||||
@@ -23,7 +24,6 @@ import { Logger } from 'winston';
|
||||
import { ParsedLocationAnnotation } from '../../helpers';
|
||||
import { RemoteProtocol } from '../prepare/types';
|
||||
import { SupportedGeneratorKey } from './types';
|
||||
import { resolve as resolvePath } from 'path';
|
||||
|
||||
// TODO: Implement proper support for more generators.
|
||||
export function getGeneratorKey(entity: Entity): SupportedGeneratorKey {
|
||||
@@ -178,10 +178,7 @@ export const validateMkdocsYaml = async (
|
||||
schema: MKDOCS_SCHEMA,
|
||||
});
|
||||
|
||||
if (
|
||||
mkdocsYml.docs_dir &&
|
||||
!resolvePath(inputDir, mkdocsYml.docs_dir).startsWith(inputDir)
|
||||
) {
|
||||
if (mkdocsYml.docs_dir && !isChildPath(inputDir, mkdocsYml.docs_dir)) {
|
||||
throw new Error(
|
||||
`docs_dir configuration value in mkdocs can't be an absolute directory or start with ../ for security reasons.
|
||||
Use relative paths instead which are resolved relative to your mkdocs.yml file location.`,
|
||||
|
||||
@@ -29,10 +29,10 @@ export type PreparerResponse = {
|
||||
|
||||
export type PreparerBase = {
|
||||
/**
|
||||
* Given an Entity definition from the Service Catalog, go and prepare a directory
|
||||
* Given an Entity definition from the Software Catalog, go and prepare a directory
|
||||
* with contents from the location in temporary storage and return the path.
|
||||
*
|
||||
* @param entity The entity from the Service Catalog
|
||||
* @param entity The entity from the Software Catalog
|
||||
* @param options.etag (Optional) If etag is provider, it will be used to check if the target has
|
||||
* updated since the last build.
|
||||
* @throws {NotModifiedError} when the prepared directory has not been changed since the last build.
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
"dependencies": {
|
||||
"@asyncapi/react-component": "^0.23.0",
|
||||
"@backstage/catalog-model": "^0.8.4",
|
||||
"@backstage/core-components": "^0.1.3",
|
||||
"@backstage/core-components": "^0.1.4",
|
||||
"@backstage/core-plugin-api": "^0.1.3",
|
||||
"@backstage/plugin-catalog": "^0.6.4",
|
||||
"@backstage/plugin-catalog-react": "^0.2.4",
|
||||
@@ -51,8 +51,8 @@
|
||||
"swagger-ui-react": "^3.37.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.7.2",
|
||||
"@backstage/core-app-api": "^0.1.3",
|
||||
"@backstage/cli": "^0.7.3",
|
||||
"@backstage/core-app-api": "^0.1.4",
|
||||
"@backstage/dev-utils": "^0.2.0",
|
||||
"@backstage/test-utils": "^0.1.14",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
# @backstage/plugin-auth-backend
|
||||
|
||||
## 0.3.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 6ca29b66c: Unbreak `.well-known` OIDC routes
|
||||
- 72574ac4d: Show better error message when configs defined under auth.providers.<provider> are undefined.
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.8.4
|
||||
- @backstage/catalog-client@0.3.15
|
||||
|
||||
## 0.3.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@backstage/plugin-auth-backend",
|
||||
"version": "0.3.14",
|
||||
"version": "0.3.15",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
@@ -29,8 +29,8 @@
|
||||
"clean": "backstage-cli clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-common": "^0.8.3",
|
||||
"@backstage/catalog-client": "^0.3.14",
|
||||
"@backstage/backend-common": "^0.8.4",
|
||||
"@backstage/catalog-client": "^0.3.15",
|
||||
"@backstage/catalog-model": "^0.8.4",
|
||||
"@backstage/config": "^0.1.5",
|
||||
"@backstage/errors": "^0.1.1",
|
||||
@@ -68,7 +68,7 @@
|
||||
"yn": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.7.2",
|
||||
"@backstage/cli": "^0.7.3",
|
||||
"@types/body-parser": "^1.19.0",
|
||||
"@types/cookie-parser": "^1.4.2",
|
||||
"@types/express-session": "^1.17.2",
|
||||
|
||||
@@ -144,11 +144,6 @@ export async function createRouter({
|
||||
}
|
||||
}
|
||||
|
||||
router.use('/:provider/', req => {
|
||||
const { provider } = req.params;
|
||||
throw new NotFoundError(`Unknown auth provider '${provider}'`);
|
||||
});
|
||||
|
||||
router.use(
|
||||
createOidcRouter({
|
||||
tokenIssuer,
|
||||
@@ -156,5 +151,10 @@ export async function createRouter({
|
||||
}),
|
||||
);
|
||||
|
||||
router.use('/:provider/', req => {
|
||||
const { provider } = req.params;
|
||||
throw new NotFoundError(`Unknown auth provider '${provider}'`);
|
||||
});
|
||||
|
||||
return router;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/catalog-model": "^0.8.4",
|
||||
"@backstage/core-components": "^0.1.3",
|
||||
"@backstage/core-components": "^0.1.4",
|
||||
"@backstage/core-plugin-api": "^0.1.3",
|
||||
"@backstage/errors": "^0.1.1",
|
||||
"@backstage/plugin-catalog-react": "^0.2.4",
|
||||
@@ -35,8 +35,8 @@
|
||||
"react-use": "^17.2.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.7.2",
|
||||
"@backstage/core-app-api": "^0.1.3",
|
||||
"@backstage/cli": "^0.7.3",
|
||||
"@backstage/core-app-api": "^0.1.4",
|
||||
"@backstage/dev-utils": "^0.2.0",
|
||||
"@backstage/test-utils": "^0.1.14",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/catalog-model": "^0.8.4",
|
||||
"@backstage/core-components": "^0.1.3",
|
||||
"@backstage/core-components": "^0.1.4",
|
||||
"@backstage/core-plugin-api": "^0.1.3",
|
||||
"@backstage/plugin-catalog-react": "^0.2.4",
|
||||
"@backstage/theme": "^0.2.8",
|
||||
@@ -38,8 +38,8 @@
|
||||
"recharts": "^1.8.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.7.2",
|
||||
"@backstage/core-app-api": "^0.1.3",
|
||||
"@backstage/cli": "^0.7.3",
|
||||
"@backstage/core-app-api": "^0.1.4",
|
||||
"@backstage/dev-utils": "^0.2.0",
|
||||
"@backstage/test-utils": "^0.1.14",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
extends: [require.resolve('@backstage/cli/config/eslint.backend')],
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
# @backstage/plugin-catalog-backend-module-ldap
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/plugin-catalog-backend@0.11.0
|
||||
@@ -0,0 +1,10 @@
|
||||
# Catalog Backend Module for LDAP
|
||||
|
||||
This is an extension module to the plugin-catalog-backend plugin, providing an LdapOrgReaderProcessor that can be
|
||||
used to ingest organization data from an LDAP server. This processor is useful if you want to import users and
|
||||
groups from your Active Directory or another LDAP compatible server.
|
||||
|
||||
## Getting started
|
||||
|
||||
See [Backstage documentation](https://backstage.io/docs/integrations/ldap/org) for details on how to install
|
||||
and configure the plugin.
|
||||
@@ -0,0 +1,72 @@
|
||||
## API Report File for "@backstage/plugin-catalog-backend-module-ldap"
|
||||
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
|
||||
import { CatalogProcessor } from '@backstage/plugin-catalog-backend';
|
||||
import { CatalogProcessorEmit } from '@backstage/plugin-catalog-backend';
|
||||
import { Client } from 'ldapjs';
|
||||
import { Config } from '@backstage/config';
|
||||
import { GroupEntity } from '@backstage/catalog-model';
|
||||
import { JsonValue } from '@backstage/config';
|
||||
import { LocationSpec } from '@backstage/catalog-model';
|
||||
import { Logger } from 'winston';
|
||||
import { SearchEntry } from 'ldapjs';
|
||||
import { SearchOptions } from 'ldapjs';
|
||||
import { UserEntity } from '@backstage/catalog-model';
|
||||
|
||||
// @public
|
||||
export const LDAP_DN_ANNOTATION = "backstage.io/ldap-dn";
|
||||
|
||||
// @public
|
||||
export const LDAP_RDN_ANNOTATION = "backstage.io/ldap-rdn";
|
||||
|
||||
// @public
|
||||
export const LDAP_UUID_ANNOTATION = "backstage.io/ldap-uuid";
|
||||
|
||||
// @public
|
||||
export class LdapClient {
|
||||
constructor(client: Client);
|
||||
// (undocumented)
|
||||
static create(logger: Logger, target: string, bind?: BindConfig): Promise<LdapClient>;
|
||||
getRootDSE(): Promise<SearchEntry | undefined>;
|
||||
getVendor(): Promise<LdapVendor>;
|
||||
search(dn: string, options: SearchOptions): Promise<SearchEntry[]>;
|
||||
}
|
||||
|
||||
// @public
|
||||
export class LdapOrgReaderProcessor implements CatalogProcessor {
|
||||
constructor(options: {
|
||||
providers: LdapProviderConfig[];
|
||||
logger: Logger;
|
||||
});
|
||||
// (undocumented)
|
||||
static fromConfig(config: Config, options: {
|
||||
logger: Logger;
|
||||
}): LdapOrgReaderProcessor;
|
||||
// (undocumented)
|
||||
readLocation(location: LocationSpec, _optional: boolean, emit: CatalogProcessorEmit): Promise<boolean>;
|
||||
}
|
||||
|
||||
// @public
|
||||
export type LdapProviderConfig = {
|
||||
target: string;
|
||||
bind?: BindConfig;
|
||||
users: UserConfig;
|
||||
groups: GroupConfig;
|
||||
};
|
||||
|
||||
// @public
|
||||
export function readLdapConfig(config: Config): LdapProviderConfig[];
|
||||
|
||||
// @public
|
||||
export function readLdapOrg(client: LdapClient, userConfig: UserConfig, groupConfig: GroupConfig): Promise<{
|
||||
users: UserEntity[];
|
||||
groups: GroupEntity[];
|
||||
}>;
|
||||
|
||||
|
||||
// (No @packageDocumentation comment for this package)
|
||||
|
||||
```
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user