Merge pull request #2 from backstage/master

megre from upstream
This commit is contained in:
Brett Wright
2021-06-22 07:47:29 +02:00
committed by GitHub
3648 changed files with 17577 additions and 7738 deletions
+38
View File
@@ -0,0 +1,38 @@
/*
* 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.
*/
const {
default: defaultChangelogFunctions,
} = require('@changesets/cli/changelog');
// Custom CHANGELOG generation for changesets, stolen from here with one minor change:
// https://github.com/atlassian/changesets/blob/main/packages/cli/src/changelog/index.ts
async function getDependencyReleaseLine(changesets, dependenciesUpdated) {
if (dependenciesUpdated.length === 0) return '';
const updatedDepenenciesList = dependenciesUpdated.map(
dependency => ` - ${dependency.name}@${dependency.newVersion}`,
);
// Return one `Updated dependencies` bullet instead of repeating for each changeset; this
// sacrifices the commit shas for brevity.
return ['- Updated dependencies', ...updatedDepenenciesList].join('\n');
}
module.exports = {
getReleaseLine: defaultChangelogFunctions.getReleaseLine,
getDependencyReleaseLine,
};
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-catalog': patch
---
Exports `CatalogLayout` and `CreateComponentButton` for catalog customization.
+1 -1
View File
@@ -1,6 +1,6 @@
{
"$schema": "https://unpkg.com/@changesets/config@1.3.0/schema.json",
"changelog": "@changesets/cli/changelog",
"changelog": "./backstage-changelog.js",
"commit": false,
"linked": [["*"]],
"access": "public",
+54
View File
@@ -0,0 +1,54 @@
---
'@backstage/plugin-explore': patch
---
Refactors the explore plugin to be more customizable. This includes the following non-breaking changes:
- Introduce new `ExploreLayout` page which can be used to create a custom `ExplorePage`
- Refactor `ExplorePage` to use a new `ExploreLayout` component
- Exports existing `DomainExplorerContent`, `GroupsExplorerContent`, & `ToolExplorerContent` components
- Allows `title` props to be customized
Create a custom explore page in `packages/app/src/components/explore/ExplorePage.tsx`.
```tsx
import {
DomainExplorerContent,
ExploreLayout,
} from '@backstage/plugin-explore';
import React from 'react';
import { InnserSourceExplorerContent } from './InnserSourceExplorerContent';
export const ExplorePage = () => {
return (
<ExploreLayout
title="Explore the ACME corp ecosystem"
subtitle="Browse our ecosystem"
>
<ExploreLayout.Route path="domains" title="Domains">
<DomainExplorerContent />
</ExploreLayout.Route>
<ExploreLayout.Route path="inner-source" title="InnerSource">
<AcmeInnserSourceExplorerContent />
</ExploreLayout.Route>
</ExploreLayout>
);
};
export const explorePage = <ExplorePage />;
```
Now register the new explore page in `packages/app/src/App.tsx`.
```diff
+ import { explorePage } from './components/explore/ExplorePage';
const routes = (
<FlatRoutes>
- <Route path="/explore" element={<ExplorePage />} />
+ <Route path="/explore" element={<ExplorePage />}>
+ {explorePage}
+ </Route>
</FlatRoutes>
);
```
+8
View File
@@ -0,0 +1,8 @@
---
'@backstage/core-app-api': patch
'@backstage/core-plugin-api': patch
'@backstage/plugin-catalog': patch
'@backstage/plugin-scaffolder': patch
---
Adding `FeatureFlag` component and treating `FeatureFlags` as first class citizens to composability API
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/dev-utils': minor
---
Removed support for deprecated registered plugin routes. All routes now need to be added using `addPage` instead.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/catalog-client': patch
---
Return entities sorted alphabetically by ref
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/cli': patch
---
updated plugin template to generate path equals plugin id for the root page
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/codemods': patch
---
Fix execution of `jscodeshift` on windows.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-search': patch
---
Use the `identityApi` to forward authorization headers to the `search-backend`
+10
View File
@@ -0,0 +1,10 @@
---
'@backstage/plugin-api-docs': minor
'@backstage/plugin-cost-insights': minor
'@backstage/plugin-gcp-projects': minor
'@backstage/plugin-gitops-profiles': minor
'@backstage/plugin-newrelic': minor
'@backstage/plugin-welcome': minor
---
**BREAKING CHANGE** Remove deprecated route registrations, meaning that it is no longer enough to only import the plugin in the app and the exported page extension must be used instead.
+25
View File
@@ -0,0 +1,25 @@
---
'@backstage/plugin-catalog-backend': patch
'@backstage/plugin-catalog-backend-module-msgraph': patch
---
Move `MicrosoftGraphOrgReaderProcessor` from `@backstage/plugin-catalog-backend`
to `@backstage/plugin-catalog-backend-module-msgraph`.
The `MicrosoftGraphOrgReaderProcessor` isn't registered by default anymore, if
you want to continue using it you have to register it manually at the catalog
builder:
1. Add dependency to `@backstage/plugin-catalog-backend-module-msgraph` to the `package.json` of your backend.
2. Add the processor to the catalog builder:
```typescript
// packages/backend/src/plugins/catalog.ts
builder.addProcessor(
MicrosoftGraphOrgReaderProcessor.fromConfig(config, {
logger,
}),
);
```
For more configuration details, see the [README of the `@backstage/plugin-catalog-backend-module-msgraph` package](https://github.com/backstage/backstage/blob/master/plugins/catalog-backend-module-msgraph/README.md).
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-techdocs': patch
---
Fix the overlapping between the sidebar and the tabs navigation when enabled in mkdocs (features: navigation.tabs)
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/cli': patch
---
Make the `create-github-app` command disable webhooks by default.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-auth-backend': patch
---
Don't export the `defaultGoogleAuthProvider`
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/cli': patch
---
chore: bump `@typescript-eslint/eslint-plugin` from 4.26.0 to 4.27.0
+8
View File
@@ -0,0 +1,8 @@
---
'@backstage/plugin-catalog': patch
'@backstage/plugin-catalog-backend': patch
'@backstage/plugin-scaffolder': patch
'@backstage/plugin-scaffolder-backend': patch
---
Moved installation instructions from the main [backstage.io](https://backstage.io) documentation to the package README file. These instructions are not generally needed, since the plugin comes installed by default with `npx @backstage/create-app`.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-user-settings': patch
---
Fix a bug that prevented changing themes on the user settings page when the theme `id` didn't match exactly the theme `variant`.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/cli': patch
---
chore: bump `@spotify/eslint-config-typescript` from 9.0.0 to 10.0.0
+25
View File
@@ -0,0 +1,25 @@
---
'@backstage/plugin-auth-backend': patch
---
Adds support for custom sign-in resolvers and profile transformations for the
Google auth provider.
Adds an `ent` claim in Backstage tokens, with a list of
[entity references](https://backstage.io/docs/features/software-catalog/references)
related to your signed-in user's identities and groups across multiple systems.
Adds an optional `providerFactories` argument to the `createRouter` exported by
the `auth-backend` plugin.
Updates `BackstageIdentity` so that
- `idToken` is deprecated in favor of `token`
- An optional `entity` field is added which represents the entity that the user is represented by within Backstage.
More information:
- [The identity resolver documentation](https://backstage.io/docs/auth/identity-resolver)
explains the concepts and shows how to implement your own.
- The [From Identity to Ownership](https://github.com/backstage/backstage/issues/4089)
RFC contains details about how this affects ownership in the catalog
+6
View File
@@ -0,0 +1,6 @@
---
'@backstage/plugin-catalog-backend-module-msgraph': patch
---
Allow customizations of `MicrosoftGraphOrgReaderProcessor` by passing an
optional `groupTransformer`, `userTransformer`, and `organizationTransformer`.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog': patch
---
Disambiguated titles of `EntityDependencyOfComponentsCard` and `EntityDependsOnComponentsCard`.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/core-components': patch
---
Add title prop in SupportButton component
@@ -0,0 +1,5 @@
---
'@backstage/plugin-techdocs': patch
---
Refactor the implicit logic from `<Reader />` into an explicit state machine. This resolves some state synchronization issues when content is refreshed or rebuilt in the backend.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-techdocs': patch
---
Adding support for user owned document filter for TechDocs custom Homepage
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-techdocs-backend': patch
---
Return a `304 Not Modified` from the `/sync/:namespace/:kind/:name` endpoint if nothing was built. This enables the caller to know whether a refresh of the docs page will return updated content (-> `201 Created`) or not (-> `304 Not Modified`).
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-proxy-backend': patch
---
Bump http-proxy-middleware from 0.19.2 to 2.0.0
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder-backend': patch
---
Correctly recognize whether the cookiecutter command exists
+7 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2021 Spotify AB
* 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.
@@ -25,6 +25,12 @@ module.exports = {
{
// eslint-disable-next-line no-restricted-syntax
templateFile: path.resolve(__dirname, './scripts/copyright-header.txt'),
templateVars: {
NAME: 'The Backstage Authors',
},
varRegexps: {
NAME: /(The Backstage Authors)|(Spotify AB)/,
},
onNonMatchingHeader: 'replace',
},
],
+1 -1
View File
@@ -4,7 +4,7 @@
# The last matching pattern takes precedence.
# https://help.github.com/articles/about-codeowners/
* @backstage/maintainers
* @backstage/reviewers
/docs/features/techdocs @backstage/techdocs-core
/docs/features/search @backstage/techdocs-core
/docs/assets/search @backstage/techdocs-core
+1
View File
@@ -149,6 +149,7 @@ Mkdocs
monorepo
Monorepo
monorepos
msgraph
msw
mysql
namespace
+35 -32
View File
@@ -1,32 +1,35 @@
| 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. |
| [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. |
| [SDA SE](https://sda.se) | [@Fox32](https://github.com/Fox32) | Central place for developing and sharing services in our insurance ecosystem. |
| [H-E-B](https://www.heb.com) | [@german-j-rodriguez](https://github.com/german-j-rodriguez) | Initial work on Engineering Portal service platform. |
| [American Airlines](https://www.aa.com) | [@paulpach](https://github.com/paulpach) | Central place for developers to develop and maintain applications |
| [Kiwi.com](https://kiwi.com) | [@aexvir](https://github.com/aexvir) | Replacing the frontend of [The Zoo](https://github.com/kiwicom/the-zoo), their service registry. |
| [Voi](https://www.voiscooters.com/) | [@K-Phoen](https://github.com/K-Phoen) | Developer portal, main gateway to our infrastructure, documentation and internal tooling. |
| [Talkdesk](https://www.talkdesk.com) | [@jaime-talkdesk](https://github.com/jaime-talkdesk) | Initial work for Engineering Portal and Self Provisioning to R&D |
| [Wealthsimple](https://www.wealthsimple.com) | [@andrewthauer](https://github.com/andrewthauer) | Developer portal, service catalog, documentation and tooling |
| [Grab](https://www.grab.com) | [@althafh](https://github.com/althafh) | Initial work as a unified interface for all of Grab's internal tooling |
| [Telenor Sweden](https://www.telenor.se) | [@O5ten](https://github.com/O5ten) | Building a developer portal for scaffolding projects towards our unified build environment and microservice stacks |
| [Fiverr](https://www.fiverr.com) | [@nirga](https://github.com/nirga) | Unifying separate tools that developers are using today (i.e. monitoring, dead letter queues management, etc.) into a single platform. |
| [Zalando SE](https://www.zalando.de) | [@leviferreira](https://github.com/leviferreira) | Building V2 of the Internal Development Portal. |
| [LegalZoom](https://legalzoom.com) | [@backjo](https://github.com/backjo) | Developer portal - hub for all engineering projects and metadata. |
| [Expedia Group](https://www.expediagroup.com) | [Mike Turner](mailto:miturner@expediagroup.com), [Sneha Kumar](mailto:snkumar@expediagroup.com), [@guillermomanzo](https://github.com/guillermomanzo), [Erik Lindgren](https://github.com/lindgren) | EG Common Developer Toolkit |
| [Paddle.com](https://paddle.com) | [Ioannis Georgoulas](https://github.com/geototti21) | Developer portal (Tech Docs, Service Catalog, Internal Tooling), we use vanilla Backstage FE and custom BE implementation in Go |
| [Acast.com](https://acast.com) | [Olle Lundberg](https://github.com/lndbrg) | Developer portal with tech docs, service catalog and a bunch of other internal tooling |
| [Lunar](https://lunar.app) | [Jacob Valdemar](https://github.com/JacobValdemar) | Internal developer portal for service overview and insights, API documentation, technical guides, onboarding guides and RFC's. |
| [Trendyol](https://trendyol.com) | [Erdogan Oksuz](https://github.com/erdoganoksuz) | The Developer Portal has been called `Pandora`. Provides an overview of Trendyol tech ecosystem. TechDocs, Catalog, Custom Plugins and Theme. |
| [Peloton](https://www.onepeloton.com/) | [Jim Haughwout](https://github.com/JimHaughwout) | Creating our first developer portal and tech-docs. Exploring Service Catalog, Tech Insights and Cost Insights as well. |
| [TELUS](https://telus.com) | [Seb Barre](https://github.com/sbarre) | The Go-to place to find answers about development and delivery at TELUS. |
| [Brex](https://www.brex.com/) | [Vamsi Chitters](https://github.com/vamsikc) | A centralized UI to understand how a service fits in the whole Brex architecture and manage a teams engineering dependencies. |
| [Oriflame](https://www.oriflame.com/) | [Oriflame](https://github.com/oriflame) | Internal developer portal for services, single page apps and packages overview, API documentation, technical guides, tech-radar and more. |
| [Booz Allen Hamilton](https://www.boozallen.com/) | [Jason Miller](https://github.com/JasonMiller-BAH) | Developer portal for a full-stack software development ecosystem that accelerates consistent and repeatable Modern Software Development practices for internal innovation and investments. |
| [Netflix](https://www.netflix.com/) | [bleathem](https://github.com/bleathem) | Our Backstage implementation will be the front door to a unified experience connecting our internal platform products across important workflows with integrated knowledge and support. |
| [b.well](https://www.icanbwell.com/) | [Jacob Rosales](https://github.com/jrosales) | Foundation for our engineering portal and cloud insights. |
| [PagerDuty](https://www.pagerduty.com/) | [Mark Shaw](https://github.com/markshawtoronto) | Developer portal, initially focused on software templates and tech-docs. |
| 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. |
| [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. |
| [SDA SE](https://sda.se) | [@Fox32](https://github.com/Fox32) | Central place for developing and sharing services in our insurance ecosystem. |
| [H-E-B](https://www.heb.com) | [@german-j-rodriguez](https://github.com/german-j-rodriguez) | Initial work on Engineering Portal service platform. |
| [American Airlines](https://www.aa.com) | [@paulpach](https://github.com/paulpach) | Central place for developers to develop and maintain applications |
| [Kiwi.com](https://kiwi.com) | [@aexvir](https://github.com/aexvir) | Replacing the frontend of [The Zoo](https://github.com/kiwicom/the-zoo), their service registry. |
| [Voi](https://www.voiscooters.com/) | [@K-Phoen](https://github.com/K-Phoen) | Developer portal, main gateway to our infrastructure, documentation and internal tooling. |
| [Talkdesk](https://www.talkdesk.com) | [@jaime-talkdesk](https://github.com/jaime-talkdesk) | Initial work for Engineering Portal and Self Provisioning to R&D |
| [Wealthsimple](https://www.wealthsimple.com) | [@andrewthauer](https://github.com/andrewthauer) | Developer portal, service catalog, documentation and tooling |
| [Grab](https://www.grab.com) | [@althafh](https://github.com/althafh) | Initial work as a unified interface for all of Grab's internal tooling |
| [Telenor Sweden](https://www.telenor.se) | [@O5ten](https://github.com/O5ten) | Building a developer portal for scaffolding projects towards our unified build environment and microservice stacks |
| [Fiverr](https://www.fiverr.com) | [@nirga](https://github.com/nirga) | Unifying separate tools that developers are using today (i.e. monitoring, dead letter queues management, etc.) into a single platform. |
| [Zalando SE](https://www.zalando.de) | [@leviferreira](https://github.com/leviferreira) | Building V2 of the Internal Development Portal. |
| [LegalZoom](https://legalzoom.com) | [@backjo](https://github.com/backjo) | Developer portal - hub for all engineering projects and metadata. |
| [Expedia Group](https://www.expediagroup.com) | [Mike Turner](mailto:miturner@expediagroup.com), [Sneha Kumar](mailto:snkumar@expediagroup.com), [@guillermomanzo](https://github.com/guillermomanzo), [Erik Lindgren](https://github.com/lindgren) | EG Common Developer Toolkit |
| [Paddle.com](https://paddle.com) | [Ioannis Georgoulas](https://github.com/geototti21) | Developer portal (Tech Docs, Service Catalog, Internal Tooling), we use vanilla Backstage FE and custom BE implementation in Go |
| [Acast.com](https://acast.com) | [Olle Lundberg](https://github.com/lndbrg) | Developer portal with tech docs, service catalog and a bunch of other internal tooling |
| [Lunar](https://lunar.app) | [Jacob Valdemar](https://github.com/JacobValdemar) | Internal developer portal for service overview and insights, API documentation, technical guides, onboarding guides and RFC's. |
| [Trendyol](https://trendyol.com) | [Erdogan Oksuz](https://github.com/erdoganoksuz) | The Developer Portal has been called `Pandora`. Provides an overview of Trendyol tech ecosystem. TechDocs, Catalog, Custom Plugins and Theme. |
| [Peloton](https://www.onepeloton.com/) | [Jim Haughwout](https://github.com/JimHaughwout) | Creating our first developer portal and tech-docs. Exploring Service Catalog, Tech Insights and Cost Insights as well. |
| [TELUS](https://telus.com) | [Seb Barre](https://github.com/sbarre) | The Go-to place to find answers about development and delivery at TELUS. |
| [Brex](https://www.brex.com/) | [Vamsi Chitters](https://github.com/vamsikc) | A centralized UI to understand how a service fits in the whole Brex architecture and manage a teams engineering dependencies. |
| [Oriflame](https://www.oriflame.com/) | [Oriflame](https://github.com/oriflame) | Internal developer portal for services, single page apps and packages overview, API documentation, technical guides, tech-radar and more. |
| [Booz Allen Hamilton](https://www.boozallen.com/) | [Jason Miller](https://github.com/JasonMiller-BAH) | Developer portal for a full-stack software development ecosystem that accelerates consistent and repeatable Modern Software Development practices for internal innovation and investments. |
| [Netflix](https://www.netflix.com/) | [bleathem](https://github.com/bleathem) | Our Backstage implementation will be the front door to a unified experience connecting our internal platform products across important workflows with integrated knowledge and support. |
| [b.well](https://www.icanbwell.com/) | [Jacob Rosales](https://github.com/jrosales) | Foundation for our engineering portal and cloud insights. |
| [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). |
+25 -1
View File
@@ -36,9 +36,33 @@ To become a maintainer you need to demonstrate the following:
If a maintainer is no longer interested or cannot perform the maintainer duties listed above, they should volunteer to be moved to emeritus status. In extreme cases this can also occur by a vote of the sponsors and maintainers per the voting process below.
# Reviewers
The project also contains a team called [@backstage/reviewers](https://github.com/orgs/backstage/teams/reviewers). This is the team of people who are the fallback in [`CODEOWNERS`](./.github/CODEOWNERS). This team will typically contain the maintainers, and a small number of additional people who are permitted to approve and merge pull requests. The purpose of this group is to offload some of the review work from the maintainers, simplifying and speeding up the review process for contributors.
This responsibility is distinct from the maintainer role. A reviewer must not approve and merge changes that have a level of impact that a maintainer should oversee; see below for clarification. For that class of changes, a reviewer can still review the pull request thoroughly without approving it (e.g. with a comment on the pull request), and is expected to notify `@backstage/maintainers` for final approval. Note that it is best to not use the GitHub review approve functionality for this, since that would let Hall of Fame members self-merge the pull request before maintainers get the chance to look at it.
The following is a non-exhaustive list of types of change, for which a reviewer should defer final decision and merge to a maintainer:
- A larger refactoring that significantly affects the structure of/between packages
- Changes that settle or alter the trajectory of contested ongoing topics in issues or elsewhere
- Changes that affect the [Architecture Decision Records](./docs/architecture-decisions)
- Changes to APIs that have large customer impact, such as the core APIs in `@backstage/core-*` packages, or significant `@backstage/cli` changes.
- Pull requests whose build checks are not passing fully
- Additions and removals of entire packages
- Releases (e.g. pull requests titled `Version Packages`)
A maintainer may suggest an addition to the reviewers team by opening a pull request that modifies [`OWNERS.md`](./OWNERS.md) accordingly. Prospective reviewers are not expected to do this themselves, but should rather ask a maintainer to sponsor their addition. All of the maintainers and sponsors are called to vote on the addition (see the section below about voting). If the vote passes, the pull request can be approved and merged, and the corresponding addition to the GitHub team can be made.
A reviewer can elect to remove themselves from the reviewers group by opening, or asking a maintainer to open, a pull request that modifies [`OWNERS.md`](./OWNERS.md) accordingly. A maintainer will approve and merge the pull request, and the corresponding removal from the GitHub team can be made.
A maintainer can call on the other maintainers and sponsors for a vote to remove a reviewer (see the section below about conflict resolution and voting). If the vote passes, a maintainer creates a pull request that modifies [`OWNERS.md`](./OWNERS.md) accordingly. After approval by another maintainer, the pull request can be merged, and the corresponding removal from the GitHub team can be made.
# Conflict resolution and voting
In general, we prefer that technical issues and maintainer membership are amicably worked out between the persons involved. If a dispute cannot be decided independently, the sponsors and maintainers can be called in to decide an issue. If the sponsors and maintainers themselves cannot decide an issue, the issue will be resolved by voting. The voting process is a simple majority in which each sponsor receives two votes and each maintainer receives one vote.
In general, we prefer that technical issues and membership are amicably worked out between the persons involved. If a dispute cannot be decided independently, the sponsors and maintainers can be called in to decide an issue. If the sponsors and maintainers themselves cannot decide an issue, the issue will be resolved by voting.
In all cases in this document where voting is mentioned, the voting process is a simple majority in which each sponsor receives two votes and each maintainer receives one vote. If such a majority is reached, the vote is said to have _passed_.
# Adding new projects to the Backstage GitHub organization
+1 -1
View File
@@ -186,7 +186,7 @@ APPENDIX: How to apply the Apache License to your work.
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2020 Spotify AB
Copyright 2020 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.
+1 -1
View File
@@ -1,5 +1,5 @@
Backstage
Copyright 2020 Spotify AB
Copyright 2020 The Backstage Authors
Portions of this software were developed by third-party software vendors:
- Tech Radar Plugin (https://opensource.zalando.com/tech-radar/), Copyright (c) 2017 Zalando SE
+12
View File
@@ -16,6 +16,18 @@ This page lists all active sponsors and maintainers.
- Ben Lambert ([benjdlambert](https://github.com/benjdlambert)) (Discord: @blam)
- Johan Haals ([jhaals](https://github.com/jhaals)) (Discord: @jhaals)
# Reviewers
See [`GOVERNANCE.md`](./GOVERNANCE.md) for details about how the reviewers team
works.
- Patrik Oldsberg ([rugvip](https://github.com/rugvip)) (Discord: @Rugvip)
- Fredrik Adelöw ([freben](https://github.com/freben)) (Discord: @freben)
- Ben Lambert ([benjdlambert](https://github.com/benjdlambert)) (Discord: @blam)
- Johan Haals ([jhaals](https://github.com/jhaals)) (Discord: @jhaals)
- Himanshu Mishra ([OrkoHunter](https://github.com/OrkoHunter)) (Discord: @OrkoHunter)
- Tim Hansen ([timbonicus](https://github.com/timbonicus)) (Discord: @timbonicus)
# Emeritus maintainers
- Stefan Ålund ([stefanalund](https://github.com/stefanalund)) (Discord: @stalund)
+1 -1
View File
@@ -72,7 +72,7 @@ proxy:
'/pagerduty':
target: https://api.pagerduty.com
headers:
Authorization: ${PAGERDUTY_TOKEN}
Authorization: Token token=${PAGERDUTY_TOKEN}
'/buildkite/api':
target: https://api.buildkite.com/v2/
@@ -16,9 +16,9 @@ import {
identityApiRef,
useApi,
} from '@backstage/core';
import ExampleFetchComponent from '../ExampleFetchComponent';
import { ExampleFetchComponent } from '../ExampleFetchComponent';
const ExampleComponent = () => {
export const ExampleComponent = () => {
const identityApi = useApi(identityApiRef);
const userId = identityApi.getUserId();
const profile = identityApi.getProfile();
@@ -52,6 +52,4 @@ const ExampleComponent = () => {
</Page>
);
};
export default ExampleComponent;
```
@@ -76,7 +76,7 @@ export const DenseTable = ({ viewer }: DenseTableProps) => {
);
};
const ExampleFetchComponent = () => {
export const ExampleFetchComponent = () => {
const auth = useApi(githubAuthApiRef);
const { value, loading, error } = useAsync(async (): Promise<any> => {
@@ -106,6 +106,4 @@ const ExampleFetchComponent = () => {
/>
);
};
export default ExampleFetchComponent;
```
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2021 Spotify AB
* 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.
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2021 Spotify AB
* 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.
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2021 Spotify AB
* 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.
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2021 Spotify AB
* 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.
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2021 Spotify AB
* 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.
+150
View File
@@ -0,0 +1,150 @@
---
id: identity-resolver
title: Identity resolver
description: Identity resolvers of Backstage users after they sign-in
---
This guide explains how the identity of a Backstage user is stored inside their
Backstage Identity Token and how you can customize the Sign-In resolvers to
include identity and group membership information of the user from other
external systems. This ultimately helps with determining the ownership of a
Backstage entity by a user. The ideas here were originally proposed in the RFC
[#4089](https://github.com/backstage/backstage/issues/4089).
When a user signs in to Backstage, inside the `claims` field of their Backstage
Token (which are standard JWT tokens) a special `ent` claim is set. `ent`
contains a list of
[entity references](../features/software-catalog/references.md), each of which
denotes an identity or a membership that is relevant to the user. There is no
guarantee that these correspond to actual existing catalog entities.
Let's take an example sign-in resolver for the Google auth provider and explore
how the `ent` field inside `claims` can be set.
Inside your `packages/backend/src/plugins/auth.ts` file, you can provide custom
sign-in resolvers and set them for any of the Authentication providers inside
`providerFactories` of the `createRouter` imported from the
`@backstage/plugin-auth-backend` plugin.
```ts
export default async function createPlugin({
...
}: PluginEnvironment): Promise<Router> {
return await createRouter({
...
providerFactories: {
google: createGoogleProvider({
signIn: {
resolver: async ({ profile: { email } }, ctx) => {
// Call a custom validator function that checks that the email is
// valid and on our own company's domain, and throws an Error if it
// isn't
validateEmail(email);
// List of entity references that denote the identity and
// membership of the user
const ent = [];
// Let's use the username in the email ID as the user's default
// unique identifier inside Backstage.
const [id] = email.split('@');
ent.push(`User:default/${id}`)
// Let's call the internal LDAP provider to get a list of groups
// that the user belongs to, and add those to the list as well
const ldapGroups = await getLdapGroups(email);
ldapGroups.forEach(group => ent.push(`Group:default/${group}`))
// Issue the token containing the entity claims
const token = await ctx.tokenIssuer.issueToken({
claims: { sub: id, ent },
});
return { id, token };
},
},
}),
},
});
}
```
As you can see, the generated Backstage Token now contains all the claims about
the identity and membership of the user. Once the sign-in process is complete,
and we need to find out if a user owns an Entity in the Software Catalog, these
`ent` claims can be used to determine the ownership.
According to the RFC, the definition of the ownership of an entity E, for a user
U, is as follows:
- Get all the `ownedBy` relations of E, and call them O
- Get all the claims of the user U and call them C
- If any C matches any O, return `true`
- Get all Group entities that U is a member of, using the regular
`memberOf`/`hasMember` relation mechanism, and call them G
- If any G matches any O, return `true`
- Otherwise, return `false`
## Default sign-in resolvers
Of course you don't have to customize the sign-in resolver if you don't need to.
The Auth backend plugin comes with a set of default sign-in resolvers which you
can use. For example - the Google provider has a default email-based sign-in
resolver, which will search the catalog for a single user entity that has a
matching `google.com/email` annotation.
It can be enabled like this
```tsx
// File: packages/backend/src/plugins/auth.ts
import { googleEmailSignInResolver } from '@backstage/plugin-auth-backend';
export default async function createPlugin({
...
}: PluginEnvironment): Promise<Router> {
return await createRouter({
...
providerFactories: {
google: createGoogleProvider({
signIn: {
resolver: googleEmailSignInResolver
}
...
```
## AuthHandler
Similar to a custom sign-in resolver, you can also write a custom auth handler
function which is used to verify and convert the auth response into the profile
that will be presented to the user. This is where you can customize things like
display name and profile picture.
This is also the place where you can do authorization and validation of the user
and throw errors if the user should not be allowed access in Backstage.
```tsx
// File: packages/backend/src/plugins/auth.ts
export default async function createPlugin({
...
}: PluginEnvironment): Promise<Router> {
return await createRouter({
...
providerFactories: {
google: createGoogleProvider({
authHandler: async ({
fullProfile // Type: passport.Profile,
idToken // Type: (Optional) string,
}) => {
// Custom validation code goes here
return {
profile: {
email,
picture,
displayName,
}
};
}
})
}
})
}
```
+15
View File
@@ -93,6 +93,21 @@ declare the visibility of a leaf node of `type: "string"`.
| `backend` | (Default) Only in backend |
| `secret` | Only in backend and may be excluded from logs for security reasons |
You can set visibility with an `@visibility` comment in the `Config` Typescript
interface.
```ts
export interface Config {
app: {
/**
* Frontend root URL
* @visibility frontend
*/
baseUrl: string;
};
}
```
## Validation
Schemas can be validated using the `backstage-cli config:check` command. If you
+2 -3
View File
@@ -34,9 +34,8 @@ More specifically, the Service Catalog enables two main use-cases:
## Getting Started
The Software Catalog is available to browse at `/catalog`. If you've followed
[Installing in your Backstage App](./installation.md) in your separate App or
[Getting Started with Backstage](../../getting-started) for this repo, you
should be able to browse the catalog at `http://localhost:3000`.
[Getting Started with Backstage](../../getting-started), you should be able to
browse the catalog at `http://localhost:3000`.
![](../../assets/software-catalog/service-catalog-home.png)
@@ -1,177 +0,0 @@
---
id: installation
title: Installing in your Backstage App
description: Documentation on How to install Backstage Plugin
---
The catalog plugin comes in two packages, `@backstage/plugin-catalog` and
`@backstage/plugin-catalog-backend`. Each has their own installation steps,
outlined below.
## Installing @backstage/plugin-catalog
> **Note that if you used `npx @backstage/create-app`, the plugin is already
> installed and you can skip to
> [adding entries to the catalog](#adding-entries-to-the-catalog)**
The catalog frontend plugin should be installed in your `app` package, which is
created as a part of `@backstage/create-app`. To install the package, run:
```bash
# From your Backstage root directory
cd packages/app
yarn add @backstage/plugin-catalog
```
### Adding the Plugin to your `packages/app`
Add the two pages that the catalog plugin provides to your app. You can choose
any name for these routes, but we recommend the following:
```tsx
// packages/app/src/App.tsx
import {
catalogPlugin,
CatalogIndexPage,
CatalogEntityPage,
} from '@backstage/plugin-catalog';
// Add to the top-level routes, directly within <FlatRoutes>
<Route path="/catalog" element={<CatalogIndexPage />} />
<Route path="/catalog/:namespace/:kind/:name" element={<CatalogEntityPage />}>
{/*
This is the root of the custom entity pages for your app, refer to the example app
in the main repo or the output of @backstage/create-app for an example
*/}
<EntityPage />
</Route>
```
The catalog plugin also has one external route that needs to be bound for it to
function: the `createComponent` route which should link to the page where the
user can create components. In a typical setup the create component route will
be linked to the Scaffolder plugin's template index page:
```ts
// packages/app/src/App.tsx
import { catalogPlugin } from '@backstage/plugin-catalog';
import { scaffolderPlugin } from '@backstage/plugin-scaffolder';
const app = createApp({
// ...
bindRoutes({ bind }) {
bind(catalogPlugin.externalRoutes, {
createComponent: scaffolderPlugin.routes.root,
});
},
});
```
You may also want to add a link to the catalog index page to your sidebar:
```tsx
// packages/app/src/components/Root.tsx
import HomeIcon from '@material-ui/icons/Home';
// Somewhere within the <Sidebar>
<SidebarItem icon={HomeIcon} to="/catalog" text="Home" />;
```
This is all that is needed for the frontend part of the Catalog plugin to work!
## Gotchas that we will fix
Since the catalog plugin currently ships with a sentry plugin `InfoCard`
installed by default, you'll need to set `sentry.organization` in your
`app-config.yaml`. For example:
```yaml
sentry:
organization: Acme Corporation
```
If you've created an app with an older version of `@backstage/create-app` or
`@backstage/cli create-app`, be sure to remove the Welcome plugin from the app,
as that will conflict with the catalog routes.
## Installing @backstage/plugin-catalog-backend
> **Note that if you used `npx @backstage/create-app`, the plugin is already
> installed and you can skip to
> [adding entries to the catalog](#adding-entries-to-the-catalog)**
The catalog backend should be installed in your `backend` package, which is
created as a part of `@backstage/create-app`. To install the package, run:
```bash
# From your Backstage root directory
cd packages/backend
yarn add @backstage/plugin-catalog-backend
```
### Adding the Plugin to your `packages/backend`
You'll need to add the plugin to the `backend`'s router. You can do this by
creating a file called `packages/backend/src/plugins/catalog.ts` with contents
matching
[catalog.ts in the create-app template](https://github.com/backstage/backstage/blob/master/packages/create-app/templates/default-app/packages/backend/src/plugins/catalog.ts).
Once the `catalog.ts` router setup file is in place, add the router to
`packages/backend/src/index.ts`:
```ts
import catalog from './plugins/catalog';
const catalogEnv = useHotMemoize(module, () => createEnv('catalog'));
const apiRouter = Router();
/** several different routers */
apiRouter.use('/catalog', await catalog(catalogEnv));
```
### Adding Entries to the Catalog
At this point the catalog backend is installed in your backend package, but you
will not have any entities loaded.
To get up and running and try out some templates quickly, you can add some of
our example templates through static configuration. Add the following to the
`catalog.locations` section in your `app-config.yaml`:
```yaml
catalog:
locations:
# Backstage Example Components
- type: url
target: https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/components/artist-lookup-component.yaml
- type: url
target: https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/components/playback-order-component.yaml
- type: url
target: https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/components/podcast-api-component.yaml
- type: url
target: https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/components/queue-proxy-component.yaml
- type: url
target: https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/components/searcher-component.yaml
- type: url
target: https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/components/playback-lib-component.yaml
- type: url
target: https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/components/www-artist-component.yaml
- type: url
target: https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/components/shuffle-api-component.yaml
```
### Running the Backend
Finally, start up Backstage with the new configuration:
```bash
# Run from the root to start both backend and frontend
yarn dev
# Alternatively, run only the backend from its own package
cd packages/backend
yarn start
```
If you've also set up the frontend plugin, you should be ready to go browse the
catalog at [localhost:3000](http://localhost:3000) now!
@@ -0,0 +1,52 @@
---
id: configuration
title: Software Template Configuration
sidebar_label: Configuration
description: Configuration options for Backstage Software Templates
---
Backstage software templates create source code, so your Backstage application
needs to be set up to allow repository creation.
This is done in your `app-config.yaml` by adding
[Backstage integrations](https://backstage.io/docs/integrations/) for the
appropriate source code repository for your organization.
> Note: Integrations may already be set up as part of your `app-config.yaml`.
The next step is to add
[add templates](http://backstage.io/docs/features/software-templates/adding-templates)
to your Backstage app.
### GitHub
For GitHub, you can configure who can see the new repositories that are created
by specifying `visibility` option. Valid options are `public`, `private` and
`internal`. The `internal` option is for GitHub Enterprise clients, which means
public within the enterprise.
```yaml
scaffolder:
github:
visibility: public # or 'internal' or 'private'
```
### Disabling Docker in Docker situation (Optional)
Software Templates use
[Cookiecutter](https://github.com/cookiecutter/cookiecutter) as a templating
library. By default it will use the
[scaffolder-backend/Cookiecutter](https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend/scripts/Cookiecutter.dockerfile)
docker image.
If you are running Backstage from a Docker container and you want to avoid
calling a container inside a container, you can set up Cookiecutter in your own
image, this will use the local installation instead.
You can do so by including the following lines in the last step of your
`Dockerfile`:
```Dockerfile
RUN apt-get update && apt-get install -y python3 python3-pip
RUN pip3 install cookiecutter
```
+2 -4
View File
@@ -17,10 +17,8 @@ locations like GitHub or GitLab.
### Getting Started
> Be sure to have covered [Installing in your Backstage App](./installation.md)
> for your separate App or
> [Getting Started with Backstage](../../getting-started) for this repo before
> proceeding.
> Be sure to have covered
> [Getting Started with Backstage](../../getting-started) before proceeding.
The Software Templates are available under `/create`. For local development you
should be able to reach them at `http://localhost:3000/create`.
@@ -1,280 +0,0 @@
---
id: installation
title: Installing in your Backstage App
description: Documentation on How to install Backstage App
---
The scaffolder plugin comes in two packages, `@backstage/plugin-scaffolder` and
`@backstage/plugin-scaffolder-backend`. Each has their own installation steps,
outlined below.
The Scaffolder plugin also depends on the Software Catalog. Instructions for how
to set that up can be found [here](../software-catalog/installation.md).
## Installing @backstage/plugin-scaffolder
> **Note that if you used `npx @backstage/create-app`, the plugin may already be
> present**
The scaffolder frontend plugin should be installed in your `app` package, which
is created as a part of `@backstage/create-app`. To install the package, run:
```bash
# From your Backstage root directory
cd packages/app
yarn add @backstage/plugin-scaffolder
```
### Adding the Plugin to your `packages/app`
Add the root page that the Scaffolder plugin provides to your app. You can
choose any path for the route, but we recommend the following:
```tsx
import { ScaffolderPage } from '@backstage/plugin-scaffolder';
// Add to the top-level routes, directly within <FlatRoutes>
<Route path="/create" element={<ScaffolderPage />} />;
```
You may also want to add a link to the template index page to your sidebar:
```tsx
import CreateComponentIcon from '@material-ui/icons/AddCircleOutline';
// Somewhere within the <Sidebar>
<SidebarItem icon={CreateComponentIcon} to="create" text="Create..." />;
```
This is all that is needed for the frontend part of the Scaffolder plugin to
work!
## Installing @backstage/plugin-scaffolder-backend
> **Note that if you used `npx @backstage/create-app`, the plugin may already be
> present**
The scaffolder backend should be installed in your `backend` package, which is
created as a part of `@backstage/create-app`. To install the package, run:
```bash
# From your Backstage root directory
cd packages/backend
yarn add @backstage/plugin-scaffolder-backend
```
### Adding the Plugin to your `packages/backend`
You'll need to add the plugin to the `backend`'s router. You can do this by
creating a file called `packages/backend/src/plugins/scaffolder.ts` with the
following contents to get you up and running quickly.
```ts
import {
DockerContainerRunner,
SingleHostDiscovery,
} from '@backstage/backend-common';
import {
CookieCutter,
createRouter,
Preparers,
Publishers,
CreateReactAppTemplater,
Templaters,
} from '@backstage/plugin-scaffolder-backend';
import type { PluginEnvironment } from '../types';
import Docker from 'dockerode';
import { CatalogClient } from '@backstage/catalog-client';
export default async function createPlugin({
logger,
config,
database,
reader,
}: PluginEnvironment) {
const dockerClient = new Docker();
const containerRunner = new DockerContainerRunner({ dockerClient });
const cookiecutterTemplater = new CookieCutter({ containerRunner });
const craTemplater = new CreateReactAppTemplater({ containerRunner });
const templaters = new Templaters();
templaters.register('cookiecutter', cookiecutterTemplater);
templaters.register('cra', craTemplater);
const preparers = await Preparers.fromConfig(config, { logger });
const publishers = await Publishers.fromConfig(config, { logger });
const discovery = SingleHostDiscovery.fromConfig(config);
const catalogClient = new CatalogClient({ discoveryApi: discovery });
return await createRouter({
preparers,
templaters,
publishers,
logger,
config,
database,
catalogClient,
reader,
});
}
```
Once the `scaffolder.ts` router setup file is in place, add the router to
`packages/backend/src/index.ts`:
```ts
import scaffolder from './plugins/scaffolder';
const scaffolderEnv = useHotMemoize(module, () => createEnv('scaffolder'));
const apiRouter = Router();
/* several router .use calls */
/* add this line */
apiRouter.use('/scaffolder', await scaffolder(scaffolderEnv));
```
### Adding Templates
At this point the scaffolder backend is installed in your backend package, but
you will not have any templates available to use. These need to be added to the
software catalog, as they are represented as entities of kind
[Template](../software-catalog/descriptor-format.md#kind-template). You can find
out more about adding templates [here](./adding-templates.md).
To get up and running and try out some templates quickly, you can add some of
our example templates through static configuration. Add the following to the
`catalog.locations` section in your `app-config.yaml`:
```yaml
catalog:
locations:
# Backstage Example Templates
- type: url
target: https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend/sample-templates/react-ssr-template/template.yaml
- type: url
target: https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/template.yaml
- type: url
target: https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend/sample-templates/create-react-app/template.yaml
- type: url
target: https://github.com/spotify/cookiecutter-golang/blob/master/template.yaml
```
### Runtime Dependencies / Configuration
For the scaffolder backend plugin to function, you'll need to setup the
integrations config in your `app-config.yaml`.
You can find help for different providers below.
> Note: Some of this configuration may already be set up as part of your
> `app-config.yaml`. We're moving away from the duplicated config for
> authentication in the `scaffolder` section and using `integrations` instead.
#### GitHub
The GitHub access token is retrieved from environment variables via the config.
The config file needs to specify what environment variable the token is
retrieved from. Your config should have the following objects.
You can configure who can see the new repositories that the scaffolder creates
by specifying `visibility` option. Valid options are `public`, `private` and
`internal`. The `internal` option is for GitHub Enterprise clients, which means
public within the enterprise.
```yaml
integrations:
github:
- host: github.com
token: ${GITHUB_TOKEN}
scaffolder:
github:
visibility: public # or 'internal' or 'private'
```
#### GitLab
For GitLab, we currently support the configuration of the GitLab publisher and
allows to configure the private access token and the base URL of a GitLab
instance:
```yaml
integrations:
gitlab:
- host: gitlab.com
token: ${GITLAB_TOKEN}
```
#### Bitbucket
For Bitbucket there are two authentication methods supported. Either `token` or
a combination of `appPassword` and `username`. It looks like either of the
following:
```yaml
integrations:
bitbucket:
- host: bitbucket.org
token: ${BITBUCKET_TOKEN}
```
or
```yaml
integrations:
bitbucket:
- host: bitbucket.org
appPassword: ${BITBUCKET_APP_PASSWORD}
username: ${BITBUCKET_USERNAME}
```
#### Azure DevOps
For Azure DevOps we support both the preparer and publisher stage with the
configuration of a private access token (PAT). For the publisher it's also
required to define the base URL for the client to connect to the service. This
will hopefully support on-prem installations as well but that has not been
verified.
```yaml
integrations:
azure:
- host: dev.azure.com
token: ${AZURE_TOKEN}
```
### Running the Backend
Finally, make sure you have a local Docker daemon running, and start up the
backend with the new configuration:
```bash
cd packages/backend
GITHUB_TOKEN=<token> yarn start
```
If you've also set up the frontend plugin, so you should be ready to go browse
the templates at [localhost:3000/create](http://localhost:3000/create) now!
### Disabling Docker in Docker situation (Optional)
Software Templates use
[Cookiecutter](https://github.com/cookiecutter/cookiecutter) as templating
library. By default it will use the
[spotify/backstage-cookiecutter](https://github.com/backstage/backstage/blob/37e35b910afc7d1270855aed0ec4718aba366c91/plugins/scaffolder-backend/scripts/Cookiecutter.dockerfile)
docker image.
If you are running Backstage from a Docker container and you want to avoid
calling a container inside a container, you can set up Cookiecutter in your own
image, this will use the local installation instead.
You can do so by including the following lines in the last step of your
`Dockerfile`:
```Dockerfile
RUN apt-get update && apt-get install -y python3 python3-pip
RUN pip3 install cookiecutter
```
@@ -28,10 +28,10 @@ scratch.
### Use the documentation template
Your working Backstage instance should by default have a documentation template
added. If not, follow these
[instructions](../software-templates/installation.md#adding-templates) to add
the documentation template. The template creates a component with only TechDocs
configuration and default markdown files as below mentioned in manual
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.
![Documentation Template](../../assets/techdocs/documentation-template.png)
@@ -370,7 +370,7 @@ techdocs:
openStackSwift:
containerName: 'name-of-techdocs-storage-bucket'
credentials:
userName: ${OPENSTACK_SWIFT_STORAGE_USERNAME}
username: ${OPENSTACK_SWIFT_STORAGE_USERNAME}
password: ${OPENSTACK_SWIFT_STORAGE_PASSWORD}
authUrl: ${OPENSTACK_SWIFT_STORAGE_AUTH_URL}
keystoneAuthVersion: ${OPENSTACK_SWIFT_STORAGE_AUTH_VERSION}
+2 -2
View File
@@ -6,8 +6,8 @@ sidebar_label: Locations
description: Integrating source code stored in Azure DevOps into the Backstage catalog
---
The Azure integration supports loading catalog entities from Azure DevOps.
Entities can be added to
The Azure DevOps integration supports loading catalog entities from Azure
DevOps. Entities can be added to
[static catalog configuration](../../features/software-catalog/configuration.md),
or registered with the
[catalog-import](https://github.com/backstage/backstage/tree/master/plugins/catalog-import)
+14
View File
@@ -0,0 +1,14 @@
---
id: org
title: Microsoft Azure Active Directory Organizational Data
sidebar_label: Org Data
# prettier-ignore
description: Importing users and groups from a Microsoft Azure Active Directory into Backstage
---
The Backstage catalog can be set up to ingest organizational data - users and
teams - directly from an tenant in Microsoft Azure Active Directory via the
Microsoft Graph API.
More details on this are available in the
[README of the `@backstage/plugin-catalog-backend-module-msgraph` package](https://github.com/backstage/backstage/blob/master/plugins/catalog-backend-module-msgraph/README.md).
@@ -11,7 +11,7 @@ terminology below for clarity and consistency when discussing Backstage.
### Authentication Glossary
This [page](./auth/glossary.md) directs to the terms and phrases related to
This [page](../auth/glossary.md) directs to the terms and phrases related to
authentication and identity section of Backstage.
### Backstage User Profiles
+1 -1
View File
@@ -99,7 +99,7 @@ import carmen from './plugins/carmen';
async function main() {
// ...
const carmenEnv = useHotMemoize(module, () => createEnv('carmen'));
apiRouter.use('/carmen', await carmen(badgesEnv));
apiRouter.use('/carmen', await carmen(carmenEnv));
```
After you start the backend (e.g. using `yarn start-backend` from the repo
+4 -4
View File
@@ -22,9 +22,9 @@ yarn create-plugin
This will create a new Backstage Plugin based on the ID that was provided. It
will be built and added to the Backstage App automatically.
> If `yarn start` is already running you should be able to see the default page
> for your new plugin directly by navigating to
> `http://localhost:3000/my-plugin`.
> If the Backstage App is already running (with `yarn start` or `yarn dev`) you
> should be able to see the default page for your new plugin directly by
> navigating to `http://localhost:3000/my-plugin`.
![](../assets/my-plugin_screenshot.png)
@@ -32,7 +32,7 @@ You can also serve the plugin in isolation by running `yarn start` in the plugin
directory. Or by using the yarn workspace command, for example:
```bash
yarn workspace @backstage/plugin-welcome start # Also supports --check
yarn workspace @backstage/my-plugin start # Also supports --check
```
This method of serving the plugin provides quicker iteration speed and a faster
+13
View File
@@ -43,6 +43,10 @@ root of the project which you can then use as an `include` in your
`app-config.yaml`. You can go ahead and
[skip ahead](#including-in-integrations-config) if you've already got an app.
Note that the created app will have a webhook that is disabled by default and
points to `smee.io`, which is intended for local development. There's also
currently no part of Backstage that makes use of the webhook.
### GitHub Enterprise
You have to create the GitHub Application manually using these
@@ -84,3 +88,12 @@ integrations:
apps:
- $include: example-backstage-app-credentials.yaml
```
### Permissions for pull requests
These are the minimum permissions required for creating a pull request with
Backstage software templates:
- Read and Write permissions for `Contents`.
- Read and write permissions for `Pull Requests` and `Issues`.
- Read permissions on `Metadata`.
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2020 Spotify AB
* Copyright 2020 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.
@@ -0,0 +1,204 @@
---
id: configuring-plugin-databases
title: Configuring Plugin Databases
# prettier-ignore
description: Guide on how to configure Backstage databases.
---
This guide covers a variety of production persistence use cases which are
supported out of the box by Backstage. The database manager allows the developer
to set the client and database connection details on a per plugin basis in
addition to the base client and connection configuration. This means that you
can use a SQLite 3 in-memory database for a specific plugin whilst using
PostgreSQL for everything else and so on.
By default, Backstage uses automatically created databases for each plugin whose
names follow the `backstage_plugin_<pluginId>` pattern, e.g.
`backstage_plugin_auth`. You can configure a different database name prefix for
use cases where you have multiple deployments running on a shared database
instance or cluster.
With infrastructure defined as code or data (Terraform, AWS CloudFormation,
etc.), you may have database credentials which lack permissions to create new
databases or you do not have control over the database names. In these
instances, you can set the database name and connection information on a per
plugin basis as mentioned earlier.
Backstage supports all of these use cases with the `DatabaseManager` provided by
`@backstage/backend-common`. We will now cover how to use and configure
Backstage's databases.
## Prerequisites
### Dependencies
Please ensure the appropriate database drivers are installed in your `backend`
package. If you intend to use both `postgres` and `sqlite3`, you can install
both of them.
```sh
cd packages/backend
# install pg if you need postgres
yarn add pg
# install sqlite3 if you intend to set it as the client
yarn add sqlite3
```
From an operational perspective, you only need to install drivers for clients
that are actively used.
### Database Manager
Existing Backstage instances should be updated to use `DatabaseManager` from
`@backstage/backend-common` in your `packages/backend/src/index.ts` file, the
`SingleConnectionDatabaseManager` has been deprecated. Import the manager and
update the references as shown below if this is not the case:
```diff
import {
- SingleConnectionDatabaseManager,
+ DatabaseManager,
} from '@backstage/backend-common';
// ...
function makeCreateEnv(config: Config) {
// ...
- const databaseManager = SingleConnectionDatabaseManager.fromConfig(config);
+ const databaseManager = DatabaseManager.fromConfig(config);
// ...
}
```
## Configuration
You should set the base database client and connection information in your
`app-config.yaml` (or equivalent) file. The base client and configuration is
used as the default which is extended for each plugin with the same or unset
client type. If a client type is specified for a specific plugin which does not
match the base client, the configuration set for the plugin will be used as is
without extending the base configuration.
Client type and configuration for plugins need to be defined under
**`backend.database.plugin.<pluginId>`**. As an example, `catalog` is the
`pluginId` for the catalog plugin and any configuration defined under that block
is specific to that plugin. We will now explore more detailed example
configurations below.
### Minimal In-Memory Configuration
In the example below, we are using `sqlite3` in-memory databases for all
plugins. You may want to use this configuration for testing or other non-durable
use cases.
```yaml
backend:
database:
client: sqlite3
connection: ':memory:'
```
### PostgreSQL
The example below uses PostgreSQL (`pg`) as the database client for all plugins.
The `auth` plugin uses a user defined database name instead of the automatically
generated one which would have been `backstage_plugin_auth`.
```yaml
backend:
database:
client: pg
connection:
host: some.example-pg-instance.tld
user: postgres
password: password
port: 5432
plugin:
auth:
connection:
database: pg_auth_set_by_user
```
### Custom Database Name Prefix
The configuration below uses `example_prefix_` as the database name prefix
instead of `backstage_plugin_`. Plugins such as `auth` and `catalog` will use
databases named `example_prefix_auth` and `example_prefix_catalog` respectively.
```yaml
backend:
database:
client: pg
connection:
host: some.example-pg-instance.tld
user: postgres
password: password
port: 5432
prefix: 'example_prefix_'
```
### Connection Configuration Per Plugin
Both `auth` and `catalog` use connection configuration with different
credentials and database names. This type of configuration can be useful for
environments with infrastructure as code or data which may provide randomly
generated credentials and/or database names.
```yaml
backend:
database:
client: pg
connection: 'postgresql://some.example-pg-instance.tld:5432'
plugin:
auth:
connection: 'postgresql://fort:knox@some.example-pg-instance.tld:5432/unwitting_fox_jumps'
catalog:
connection: 'postgresql://bank:reserve@some.example-pg-instance.tld:5432/shuffle_ransack_playback'
```
### PostgreSQL and SQLite 3
The example below uses PostgreSQL (`pg`) as the database client for all plugins
except the `auth` plugin which uses `sqlite3`. As the `auth` plugin's client
type is different from the base client type, the connection configuration for
`auth` is used verbatim without extending the base configuration for PostgreSQL.
```yaml
backend:
database:
client: pg
connection: 'postgresql://foo:bar@some.example-pg-instance.tld:5432'
plugin:
auth:
client: sqlite3
connection: ':memory:'
```
## Check Your Databases
The `DatabaseManager` will attempt to create the databases if they do not exist.
If you have set credentials per plugin because the credentials in the base
configuration do not have permissions to create databases, you must ensure they
exist before starting the service. The service will not be able to create them,
it can only use them.
### Privileges
As Backstage attempts to check if the database exists, you may need to grant
privileges to list or show databases for a given user. For PostgreSQL, you would
grant the following:
```postgres
GRANT SELECT ON pg_database TO some_user;
```
MySQL:
```mysql
GRANT SHOW DATABASES ON *.* TO some_user;
```
The mechanisms in this guide should help you tackle different database
deployment situations. Good luck!
+1 -3
View File
@@ -146,11 +146,9 @@ import {
} from '@backstage/core';
import { graphql } from '@octokit/graphql';
const ExampleFetchComponent = () => {
export const ExampleFetchComponent = () => {
return <div>Nothing to see yet</div>;
};
export default ExampleFetchComponent;
```
3. Save that and ensure you see no errors. Comment out the unused imports if
+1 -1
View File
@@ -20,7 +20,7 @@
"docusaurus": "^2.0.0-alpha.70",
"js-yaml": "^4.1.0",
"prettier": "^2.3.1",
"yarn-lock-check": "^1.0.4"
"yarn-lock-check": "^1.0.5"
},
"prettier": "@spotify/prettier-config"
}
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2020 Spotify AB
* Copyright 2020 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.
+9 -7
View File
@@ -8,6 +8,8 @@
"overview/background",
"overview/adopting",
"overview/stability-index",
"overview/support",
"overview/glossary",
"overview/logos"
],
"Getting Started": [
@@ -24,7 +26,8 @@
},
"getting-started/keeping-backstage-updated",
"getting-started/concepts",
"getting-started/contributors"
"getting-started/contributors",
"getting-started/project-structure"
],
"CLI": ["cli/index", "cli/commands"],
"Core Features": [
@@ -33,7 +36,6 @@
"label": "Software Catalog",
"ids": [
"features/software-catalog/software-catalog-overview",
"features/software-catalog/installation",
"features/software-catalog/configuration",
"features/software-catalog/system-model",
"features/software-catalog/descriptor-format",
@@ -62,7 +64,7 @@
"label": "Software Templates",
"ids": [
"features/software-templates/software-templates-index",
"features/software-templates/installation",
"features/software-templates/configuration",
"features/software-templates/adding-templates",
"features/software-templates/writing-templates",
"features/software-templates/builtin-actions",
@@ -103,8 +105,8 @@
"integrations/index",
{
"type": "subcategory",
"label": "Azure DevOps",
"ids": ["integrations/azure/locations"]
"label": "Azure",
"ids": ["integrations/azure/locations", "integrations/azure/org"]
},
{
"type": "subcategory",
@@ -206,6 +208,7 @@
},
"auth/add-auth-provider",
"auth/using-auth",
"auth/identity-resolver",
"auth/auth-backend",
"auth/oauth",
"auth/auth-backend-classes",
@@ -243,6 +246,7 @@
"Tutorials": [
"tutorials/journey",
"tutorials/quickstart-app-plugin",
"tutorials/configuring-plugin-databases",
"tutorials/switching-sqlite-postgres"
],
"Architecture Decision Records (ADRs)": [
@@ -259,8 +263,6 @@
"architecture-decisions/adrs-adr010",
"architecture-decisions/adrs-adr011"
],
"Support": ["support/support", "support/project-structure"],
"Glossary": ["glossary"],
"FAQ": ["FAQ"]
}
}
+5
View File
@@ -7,6 +7,11 @@
/* your custom css */
/* makes scroll bars, inputs etc match the dark theme better */
html {
color-scheme: dark;
}
/* override font color for new dark tech docs styling */
table {
color: white;
Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

+9 -120
View File
@@ -9,13 +9,6 @@
dependencies:
"@babel/highlight" "^7.0.0"
"@babel/code-frame@^7.0.0":
version "7.12.13"
resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658"
integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==
dependencies:
"@babel/highlight" "^7.12.13"
"@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.11":
version "7.12.11"
resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f"
@@ -227,11 +220,6 @@
resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed"
integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==
"@babel/helper-validator-identifier@^7.14.0":
version "7.14.0"
resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz#d26cad8a47c65286b15df1547319a5d0bcf27288"
integrity sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==
"@babel/helper-validator-option@^7.12.1", "@babel/helper-validator-option@^7.12.11":
version "7.12.11"
resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.11.tgz#d66cb8b7a3e7fe4c6962b32020a131ecf0847f4f"
@@ -265,15 +253,6 @@
chalk "^2.0.0"
js-tokens "^4.0.0"
"@babel/highlight@^7.12.13":
version "7.14.0"
resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz#3197e375711ef6bf834e67d0daec88e4f46113cf"
integrity sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==
dependencies:
"@babel/helper-validator-identifier" "^7.14.0"
chalk "^2.0.0"
js-tokens "^4.0.0"
"@babel/parser@^7.12.10", "@babel/parser@^7.12.11", "@babel/parser@^7.12.7":
version "7.12.11"
resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz#9ce3595bcd74bc5c466905e86c535b8b25011e79"
@@ -942,29 +921,11 @@
dependencies:
"@types/node" "*"
"@types/glob@^7.1.3":
version "7.1.3"
resolved "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183"
integrity sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==
dependencies:
"@types/minimatch" "*"
"@types/node" "*"
"@types/minimatch@*":
version "3.0.4"
resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz#f0ec25dbf2f0e4b18647313ac031134ca5b24b21"
integrity sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==
"@types/node@*":
version "14.14.20"
resolved "https://registry.npmjs.org/@types/node/-/node-14.14.20.tgz#f7974863edd21d1f8a494a73e8e2b3658615c340"
integrity sha512-Y93R97Ouif9JEOWPIUyU+eyIdyRqQR0I8Ez1dzku4hDx34NWh4HbtIc3WNzwB1Y9ULvNGeu5B8h8bVL5cAk4/A==
"@types/node@^15.6.1":
version "15.9.0"
resolved "https://registry.npmjs.org/@types/node/-/node-15.9.0.tgz#0b7f6c33ca5618fe329a9d832b478b4964d325a8"
integrity sha512-AR1Vq1Ei1GaA5FjKL5PBqblTZsL5M+monvGSZwe6sSIdGiuu7Xr/pNwWJY+0ZQuN8AapD/XMB5IzBAyYRFbocA==
"@types/q@^1.5.1":
version "1.5.4"
resolved "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24"
@@ -1449,11 +1410,6 @@ buffer@^5.2.1:
base64-js "^1.3.1"
ieee754 "^1.1.13"
builtin-modules@^1.1.1:
version "1.1.1"
resolved "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=
bytes@1:
version "1.0.0"
resolved "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz#3569ede8ba34315fab99c3e92cb04c7220de1fa8"
@@ -1567,7 +1523,7 @@ caw@^2.0.0, caw@^2.0.1:
tunnel-agent "^0.6.0"
url-to-options "^1.0.1"
chalk@2.4.2, chalk@^2.0.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2:
chalk@2.4.2, chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2:
version "2.4.2"
resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
@@ -1758,7 +1714,7 @@ combined-stream@^1.0.6, combined-stream@~1.0.6:
dependencies:
delayed-stream "~1.0.0"
commander@^2.12.1, commander@^2.8.1:
commander@^2.8.1:
version "2.20.3"
resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
@@ -2230,11 +2186,6 @@ diacritics-map@^0.1.0:
resolved "https://registry.npmjs.org/diacritics-map/-/diacritics-map-0.1.0.tgz#6dfc0ff9d01000a2edf2865371cac316e94977af"
integrity sha1-bfwP+dAQAKLt8oZTccrDFulJd68=
diff@^4.0.1:
version "4.0.2"
resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
dir-glob@2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034"
@@ -3091,19 +3042,7 @@ glob-to-regexp@^0.3.0:
resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab"
integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=
glob@^7.0.0, glob@^7.0.5, glob@^7.1.2, glob@^7.1.3, glob@^7.1.6, glob@~7.1.1:
version "7.1.6"
resolved "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.0.4"
once "^1.3.0"
path-is-absolute "^1.0.0"
glob@^7.1.1, glob@^7.1.7:
glob@^7.0.0, glob@^7.0.5, glob@^7.1.2, glob@^7.1.3, glob@^7.1.6, glob@^7.1.7, glob@~7.1.1:
version "7.1.7"
resolved "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90"
integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==
@@ -3638,13 +3577,6 @@ is-core-module@^2.1.0:
dependencies:
has "^1.0.3"
is-core-module@^2.2.0:
version "2.4.0"
resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1"
integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==
dependencies:
has "^1.0.3"
is-data-descriptor@^0.1.4:
version "0.1.4"
resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56"
@@ -4457,7 +4389,7 @@ mixin-deep@^1.1.3, mixin-deep@^1.2.0:
for-in "^1.0.2"
is-extendable "^1.0.1"
mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5, mkdirp@~0.5.1:
mkdirp@^0.5.1, mkdirp@^0.5.5, mkdirp@~0.5.1:
version "0.5.5"
resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
@@ -5681,14 +5613,6 @@ resolve@^1.1.6, resolve@^1.10.0:
is-core-module "^2.1.0"
path-parse "^1.0.6"
resolve@^1.3.2:
version "1.20.0"
resolved "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975"
integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
dependencies:
is-core-module "^2.2.0"
path-parse "^1.0.6"
responselike@1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7"
@@ -6437,37 +6361,11 @@ truncate-html@^1.0.3:
"@types/cheerio" "^0.22.8"
cheerio "0.22.0"
tslib@^1.13.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
tslib@^1.9.0, tslib@^1.9.3:
version "1.14.1"
resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
tslint@^6.1.3:
version "6.1.3"
resolved "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz#5c23b2eccc32487d5523bd3a470e9aa31789d904"
integrity sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==
dependencies:
"@babel/code-frame" "^7.0.0"
builtin-modules "^1.1.1"
chalk "^2.3.0"
commander "^2.12.1"
diff "^4.0.1"
glob "^7.1.1"
js-yaml "^3.13.1"
minimatch "^3.0.4"
mkdirp "^0.5.3"
resolve "^1.3.2"
semver "^5.3.0"
tslib "^1.13.0"
tsutils "^2.29.0"
tsutils@^2.29.0:
version "2.29.0"
resolved "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99"
integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==
dependencies:
tslib "^1.8.1"
tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
@@ -6493,11 +6391,6 @@ typedarray@^0.0.6:
resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
typescript@^4.3.2:
version "4.3.2"
resolved "https://registry.npmjs.org/typescript/-/typescript-4.3.2.tgz#399ab18aac45802d6f2498de5054fcbbe716a805"
integrity sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==
unbzip2-stream@^1.0.9:
version "1.4.3"
resolved "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz#b0da04c4371311df771cdc215e87f2130991ace7"
@@ -6767,18 +6660,14 @@ yargs@^2.3.0:
dependencies:
wordwrap "0.0.2"
yarn-lock-check@^1.0.4:
version "1.0.4"
resolved "https://registry.npmjs.org/yarn-lock-check/-/yarn-lock-check-1.0.4.tgz#a0373de051be0c8442d8933070df7a45595263b4"
integrity sha512-Gj0wRN85c4OPZUlE7WsQ0a1COv38uyeWWR0YAvJr2Vxw1f32bwK19xySjUZlxt9o4QopJkd8g6x6CLv81OHwYg==
yarn-lock-check@^1.0.5:
version "1.0.5"
resolved "https://registry.npmjs.org/yarn-lock-check/-/yarn-lock-check-1.0.5.tgz#69d9516385f3ff010d0e2b0e87fbbd9bb1ffecaf"
integrity sha512-dxmV4LpIBrRAPbPg+klyGvqdVo3Y6PgJs6ERJYXf0HSEst7klDmvKKqQUtk+wrIRCoMDIVIzSUTZsuC4zr/tFQ==
dependencies:
"@types/glob" "^7.1.3"
"@types/node" "^15.6.1"
"@yarnpkg/lockfile" "^1.1.0"
glob "^7.1.7"
ini "^2.0.0"
tslint "^6.1.3"
typescript "^4.3.2"
yauzl@^2.4.2:
version "2.10.0"
+7 -4
View File
@@ -13,6 +13,8 @@ nav:
- The Spotify Story: 'overview/background.md'
- Strategies for adopting: 'overview/adopting.md'
- Stability Index: 'overview/stability-index.md'
- Support and community: 'overview/support.md'
- Glossary: 'overview/glossary.md'
- Logo assets: 'overview/logos.md'
- Getting Started:
- Getting Started: 'getting-started/index.md'
@@ -24,13 +26,13 @@ nav:
- Keeping Backstage Updated: 'getting-started/keeping-backstage-updated.md'
- Key Concepts: 'getting-started/concepts.md'
- Contributors: 'getting-started/contributors.md'
- Project Structure: 'getting-started/project-structure.md'
- CLI:
- Overview: 'cli/index.md'
- Commands: 'cli/commands.md'
- Core Features:
- Software Catalog:
- Overview: 'features/software-catalog/index.md'
- Installing in your Backstage App: 'features/software-catalog/installation.md'
- Catalog Configuration: 'features/software-catalog/configuration.md'
- System Model: 'features/software-catalog/system-model.md'
- YAML File Format: 'features/software-catalog/descriptor-format.md'
@@ -49,7 +51,7 @@ nav:
- Troubleshooting: 'features/kubernetes/troubleshooting.md'
- Software Templates:
- Overview: 'features/software-templates/index.md'
- Installing in your Backstage App: 'features/software-templates/installation.md'
- Configuration: 'features/software-templates/configuration.md'
- Adding your own Templates: 'features/software-templates/adding-templates.md'
- Writing Templates: 'features/software-templates/writing-templates.md'
- Builtin Actions: 'features/software-templates/builtin-actions.md'
@@ -76,8 +78,9 @@ nav:
- FAQ: 'features/techdocs/FAQ.md'
- Integrations:
- Overview: 'integrations/index.md'
- Azure DevOps:
- Azure:
- Locations: 'integrations/azure/locations.md'
- Org Data: 'integrations/azure/org.md'
- Bitbucket:
- Locations: 'integrations/bitbucket/locations.md'
- Discovery: 'integrations/bitbucket/discovery.md'
@@ -133,6 +136,7 @@ nav:
- OneLogin: 'auth/onelogin/provider.md'
- Adding authentication providers: 'auth/add-auth-provider.md'
- Using authentication and identity: 'auth/using-auth.md'
- Sign in resolvers: 'auth/identity-resolver.md'
- Auth backend: 'auth/auth-backend.md'
- OAuth and OpenID Connect: 'auth/oauth.md'
- Auth backend classes: 'auth/auth-backend-classes.md'
@@ -173,7 +177,6 @@ nav:
- ADR010 - Luxon Date Library: 'architecture-decisions/adr010-luxon-date-library.md'
- ADR011 - Plugin Package Structure: 'architecture-decisions/adr011-plugin-package-structure.md'
- Support:
- Support and community: 'support/support.md'
- Backstage Project Structure: 'support/project-structure.md'
- Glossary: glossary.md
- FAQ: FAQ.md
+18
View File
@@ -1,5 +1,23 @@
# example-app
## 0.2.33
### Patch Changes
- Updated dependencies
- @backstage/plugin-catalog-react@0.2.3
- @backstage/plugin-catalog@0.6.3
- @backstage/cli@0.7.1
- @backstage/plugin-api-docs@0.5.0
- @backstage/plugin-jenkins@0.4.5
- @backstage/plugin-techdocs@0.9.6
- @backstage/plugin-circleci@0.2.16
- @backstage/plugin-catalog-import@0.5.10
- @backstage/plugin-sentry@0.3.12
- @backstage/plugin-user-settings@0.2.11
- @backstage/catalog-model@0.8.3
- @backstage/core@0.7.13
## 0.2.32
### Patch Changes
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2020 Spotify AB
* Copyright 2020 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.
@@ -1,5 +1,5 @@
/*
* Copyright 2021 Spotify AB
* 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.
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2021 Spotify AB
* 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.
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2020 Spotify AB
* Copyright 2020 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.
+15 -13
View File
@@ -1,19 +1,21 @@
{
"name": "example-app",
"version": "0.2.32",
"version": "0.2.33",
"private": true,
"bundled": true,
"dependencies": {
"@backstage/catalog-model": "^0.8.2",
"@backstage/cli": "^0.7.0",
"@backstage/core": "^0.7.12",
"@backstage/catalog-model": "^0.8.3",
"@backstage/cli": "^0.7.1",
"@backstage/core": "^0.7.13",
"@backstage/integration-react": "^0.1.3",
"@backstage/plugin-api-docs": "^0.4.15",
"@backstage/core-app-api": "^0.1.2",
"@backstage/core-components": "^0.1.1",
"@backstage/plugin-api-docs": "^0.5.0",
"@backstage/plugin-badges": "^0.2.2",
"@backstage/plugin-catalog": "^0.6.2",
"@backstage/plugin-catalog-import": "^0.5.9",
"@backstage/plugin-catalog-react": "^0.2.2",
"@backstage/plugin-circleci": "^0.2.15",
"@backstage/plugin-catalog": "^0.6.3",
"@backstage/plugin-catalog-import": "^0.5.10",
"@backstage/plugin-catalog-react": "^0.2.3",
"@backstage/plugin-circleci": "^0.2.16",
"@backstage/plugin-cloudbuild": "^0.2.16",
"@backstage/plugin-code-coverage": "^0.1.4",
"@backstage/plugin-cost-insights": "^0.10.2",
@@ -21,7 +23,7 @@
"@backstage/plugin-gcp-projects": "^0.2.6",
"@backstage/plugin-github-actions": "^0.4.9",
"@backstage/plugin-graphiql": "^0.2.11",
"@backstage/plugin-jenkins": "^0.4.4",
"@backstage/plugin-jenkins": "^0.4.5",
"@backstage/plugin-kafka": "^0.2.8",
"@backstage/plugin-kubernetes": "^0.4.5",
"@backstage/plugin-lighthouse": "^0.2.17",
@@ -31,12 +33,12 @@
"@backstage/plugin-rollbar": "^0.3.6",
"@backstage/plugin-scaffolder": "^0.9.8",
"@backstage/plugin-search": "^0.4.0",
"@backstage/plugin-sentry": "^0.3.11",
"@backstage/plugin-sentry": "^0.3.12",
"@backstage/plugin-shortcuts": "^0.1.2",
"@backstage/plugin-tech-radar": "^0.4.0",
"@backstage/plugin-techdocs": "^0.9.5",
"@backstage/plugin-techdocs": "^0.9.6",
"@backstage/plugin-todo": "^0.1.2",
"@backstage/plugin-user-settings": "^0.2.10",
"@backstage/plugin-user-settings": "^0.2.11",
"@backstage/theme": "^0.2.8",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2020 Spotify AB
* Copyright 2020 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.
+5 -4
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2020 Spotify AB
* Copyright 2020 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.
@@ -14,13 +14,12 @@
* limitations under the License.
*/
import { createApp, FlatRoutes } from '@backstage/core-app-api';
import {
AlertDisplay,
createApp,
FlatRoutes,
OAuthRequestDialog,
SignInPage,
} from '@backstage/core';
} from '@backstage/core-components';
import { apiDocsPlugin, ApiExplorerPage } from '@backstage/plugin-api-docs';
import {
CatalogEntityPage,
@@ -65,6 +64,7 @@ const app = createApp({
// Custom icon example
alert: AlarmIcon,
},
components: {
SignInPage: props => {
return (
@@ -116,6 +116,7 @@ const routes = (
/>
<Route path="/graphiql" element={<GraphiQLPage />} />
<Route path="/lighthouse" element={<LighthousePage />} />
<Route path="/api-docs" element={<ApiExplorerPage />} />
<Route path="/gcp-projects" element={<GcpProjectsPage />} />
<Route path="/newrelic" element={<NewRelicPage />} />
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2020 Spotify AB
* Copyright 2020 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.
@@ -1,5 +1,5 @@
/*
* Copyright 2020 Spotify AB
* Copyright 2020 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.
@@ -1,5 +1,5 @@
/*
* Copyright 2020 Spotify AB
* Copyright 2020 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.
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2020 Spotify AB
* Copyright 2020 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.
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2020 Spotify AB
* Copyright 2020 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.
@@ -1,5 +1,5 @@
/*
* Copyright 2020 Spotify AB
* Copyright 2020 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.
@@ -1,5 +1,5 @@
/*
* Copyright 2020 Spotify AB
* Copyright 2020 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.
@@ -1,5 +1,5 @@
/*
* Copyright 2021 Spotify AB
* 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.
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2020 Spotify AB
* Copyright 2020 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.
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2020 Spotify AB
* Copyright 2020 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.
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2020 Spotify AB
* Copyright 2020 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.
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2020 Spotify AB
* Copyright 2020 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.
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2020 Spotify AB
* Copyright 2020 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.
+54
View File
@@ -1,5 +1,59 @@
# @backstage/backend-common
## 0.8.3
### Patch Changes
- e5cdf0560: Provide a more clear error message when database connection fails.
- 772dbdb51: Deprecates `SingleConnectionDatabaseManager` and provides an API compatible database
connection manager, `DatabaseManager`, which allows developers to configure database
connections on a per plugin basis.
The `backend.database` config path allows you to set `prefix` to use an
alternate prefix for automatically generated database names, the default is
`backstage_plugin_`. Use `backend.database.plugin.<pluginId>` to set plugin
specific database connection configuration, e.g.
```yaml
backend:
database:
client: 'pg',
prefix: 'custom_prefix_'
connection:
host: 'localhost'
user: 'foo'
password: 'bar'
plugin:
catalog:
connection:
database: 'database_name_overriden'
scaffolder:
client: 'sqlite3'
connection: ':memory:'
```
Migrate existing backstage installations by swapping out the database manager in the
`packages/backend/src/index.ts` file as shown below:
```diff
import {
- SingleConnectionDatabaseManager,
+ DatabaseManager,
} from '@backstage/backend-common';
// ...
function makeCreateEnv(config: Config) {
// ...
- const databaseManager = SingleConnectionDatabaseManager.fromConfig(config);
+ const databaseManager = DatabaseManager.fromConfig(config);
// ...
}
```
- Updated dependencies
- @backstage/config-loader@0.6.4
## 0.8.2
### Patch Changes
+8 -5
View File
@@ -100,6 +100,12 @@ export function createServiceBuilder(_module: NodeModule): ServiceBuilderImpl;
// @public (undocumented)
export function createStatusCheckRouter(options: StatusCheckRouterOptions): Promise<express.Router>;
// @public (undocumented)
export class DatabaseManager {
forPlugin(pluginId: string): PluginDatabaseManager;
static fromConfig(config: Config): DatabaseManager;
}
// @public (undocumented)
export class DockerContainerRunner implements ContainerRunner {
constructor({ dockerClient }: {
@@ -326,11 +332,8 @@ export type ServiceBuilder = {
// @public (undocumented)
export function setRootLogger(newLogger: winston.Logger): void;
// @public
export class SingleConnectionDatabaseManager {
forPlugin(pluginId: string): PluginDatabaseManager;
static fromConfig(config: Config): SingleConnectionDatabaseManager;
}
// @public @deprecated
export const SingleConnectionDatabaseManager: typeof DatabaseManager;
// @public
export class SingleHostDiscovery implements PluginEndpointDiscovery {
+21 -11
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2020 Spotify AB
* Copyright 2020 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.
@@ -53,20 +53,30 @@ export interface Config {
};
};
/** Database connection configuration, select database type using the `client` field */
database:
| {
client: 'sqlite3';
connection: ':memory:' | string | { filename: string };
}
| {
client: 'pg';
/** Database connection configuration, select base database type using the `client` field */
database: {
/** Default database client to use */
client: 'sqlite3' | 'pg';
/**
* Base database connection string or Knex object
* @secret
*/
connection: string | object;
/** Database name prefix override */
prefix?: string;
/** Plugin specific database configuration and client override */
plugin?: {
[pluginId: string]: {
/** Database client override */
client?: 'sqlite3' | 'pg';
/**
* PostgreSQL connection string or knex configuration object.
* Database connection string or Knex object override
* @secret
*/
connection: string | object;
connection?: string | object;
};
};
};
/** Cache connection configuration, select cache type using the `store` field */
cache?:
+3 -3
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/backend-common",
"description": "Common functionality library for Backstage backends",
"version": "0.8.2",
"version": "0.8.3",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
@@ -31,7 +31,7 @@
"dependencies": {
"@backstage/cli-common": "^0.1.1",
"@backstage/config": "^0.1.5",
"@backstage/config-loader": "^0.6.2",
"@backstage/config-loader": "^0.6.4",
"@backstage/errors": "^0.1.1",
"@backstage/integration": "^0.5.6",
"@google-cloud/storage": "^5.8.0",
@@ -76,7 +76,7 @@
}
},
"devDependencies": {
"@backstage/cli": "^0.7.0",
"@backstage/cli": "^0.7.1",
"@backstage/test-utils": "^0.1.12",
"@types/archiver": "^5.1.0",
"@types/compression": "^1.7.0",
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2021 Spotify AB
* 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.
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2021 Spotify AB
* 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.
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2021 Spotify AB
* 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.

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