From dd395335bc252ff02c07e6457b519792fba917f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20MORI?= Date: Mon, 8 Aug 2022 15:06:01 +0200 Subject: [PATCH 001/198] Allow unknown typed location from being registered via the location service by configuration settings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane MORI --- .changeset/flat-plums-shout.md | 5 + plugins/catalog-backend/config.d.ts | 17 +++ .../src/service/CatalogBuilder.ts | 2 +- .../service/DefaultLocationService.test.ts | 116 +++++++++++++++++- .../src/service/DefaultLocationService.ts | 10 +- 5 files changed, 146 insertions(+), 4 deletions(-) create mode 100644 .changeset/flat-plums-shout.md diff --git a/.changeset/flat-plums-shout.md b/.changeset/flat-plums-shout.md new file mode 100644 index 0000000000..578952c9c3 --- /dev/null +++ b/.changeset/flat-plums-shout.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +Allow unknown typed location from being registered via the location service by configuration settings diff --git a/plugins/catalog-backend/config.d.ts b/plugins/catalog-backend/config.d.ts index 950ed2f63c..473db9a35a 100644 --- a/plugins/catalog-backend/config.d.ts +++ b/plugins/catalog-backend/config.d.ts @@ -54,6 +54,23 @@ export interface Config { */ readonly?: boolean; + /** + * Allow unknown type when create location. + * + * Setting 'locationService.create.allowUnknownType=false' forbids to create + * location with unknown type through location service. + * This is the default value. + * + * Setting 'locationService.create.allowUnknownType=true' allows to create + * location with unknown type through location service. + * + */ + locationService?: { + create?: { + allowUnknownType: boolean; + }; + }; + /** * A set of static locations that the catalog shall always keep itself * up-to-date with. This is commonly used for large, permanent integrations diff --git a/plugins/catalog-backend/src/service/CatalogBuilder.ts b/plugins/catalog-backend/src/service/CatalogBuilder.ts index e9e35301c3..57b5160a97 100644 --- a/plugins/catalog-backend/src/service/CatalogBuilder.ts +++ b/plugins/catalog-backend/src/service/CatalogBuilder.ts @@ -465,7 +465,7 @@ export class CatalogBuilder { const locationAnalyzer = this.locationAnalyzer ?? new RepoLocationAnalyzer(logger, integrations); const locationService = new AuthorizedLocationService( - new DefaultLocationService(locationStore, orchestrator), + new DefaultLocationService(locationStore, orchestrator, config), permissionEvaluator, ); const refreshService = new AuthorizedRefreshService( diff --git a/plugins/catalog-backend/src/service/DefaultLocationService.test.ts b/plugins/catalog-backend/src/service/DefaultLocationService.test.ts index 4399d48d69..e936d2de93 100644 --- a/plugins/catalog-backend/src/service/DefaultLocationService.test.ts +++ b/plugins/catalog-backend/src/service/DefaultLocationService.test.ts @@ -18,6 +18,7 @@ import { DefaultLocationService } from './DefaultLocationService'; import { CatalogProcessingOrchestrator } from '../processing/types'; import { LocationStore } from './types'; import { InputError } from '@backstage/errors'; +import { ConfigReader } from '@backstage/config'; describe('DefaultLocationServiceTest', () => { const orchestrator: jest.Mocked = { @@ -29,7 +30,17 @@ describe('DefaultLocationServiceTest', () => { listLocations: jest.fn(), getLocation: jest.fn(), }; - const locationService = new DefaultLocationService(store, orchestrator); + + const mockConfig = (allowUnknownType: boolean) => + new ConfigReader({ + catalog: { + locationService: { + create: { + allowUnknownType, + }, + }, + }, + }); beforeEach(() => { jest.resetAllMocks(); @@ -81,6 +92,11 @@ describe('DefaultLocationServiceTest', () => { errors: [], }); + const locationService = new DefaultLocationService( + store, + orchestrator, + mockConfig(false), + ); await locationService.createLocation( { type: 'url', target: 'https://backstage.io/catalog-info.yaml' }, true, @@ -144,6 +160,12 @@ describe('DefaultLocationServiceTest', () => { store.listLocations.mockResolvedValueOnce([ { id: '137', ...locationSpec }, ]); + + const locationService = new DefaultLocationService( + store, + orchestrator, + mockConfig(false), + ); const result = await locationService.createLocation( { type: 'url', target: 'https://backstage.io/catalog-info.yaml' }, true, @@ -197,6 +219,11 @@ describe('DefaultLocationServiceTest', () => { errors: [], }); + const locationService = new DefaultLocationService( + store, + orchestrator, + mockConfig(false), + ); await expect( locationService.createLocation( { type: 'url', target: 'https://backstage.io/catalog-info.yaml' }, @@ -225,6 +252,12 @@ describe('DefaultLocationServiceTest', () => { store.listLocations.mockResolvedValueOnce([ { id: '987', type: 'url', target: 'https://example.com' }, ]); + + const locationService = new DefaultLocationService( + store, + orchestrator, + mockConfig(false), + ); const result = await locationService.createLocation( { type: 'url', target: 'https://backstage.io/catalog-info.yaml' }, true, @@ -243,6 +276,11 @@ describe('DefaultLocationServiceTest', () => { id: '123', }); + const locationService = new DefaultLocationService( + store, + orchestrator, + mockConfig(false), + ); await expect( locationService.createLocation(locationSpec, false), ).resolves.toEqual({ @@ -259,7 +297,61 @@ describe('DefaultLocationServiceTest', () => { }); }); - it('should not allow locations of unknown types', async () => { + it('should create location with unknown type if configuration allows it', async () => { + const locationSpec = { + type: 'unknown', + target: 'https://backstage.io/catalog-info.yaml', + }; + + store.createLocation.mockResolvedValue({ + ...locationSpec, + id: '123', + }); + + const locationService = new DefaultLocationService( + store, + orchestrator, + mockConfig(true), + ); + await expect( + locationService.createLocation(locationSpec, false), + ).resolves.toEqual({ + entities: [], + location: { + id: '123', + target: 'https://backstage.io/catalog-info.yaml', + type: 'unknown', + }, + }); + expect(store.createLocation).toBeCalledWith({ + target: 'https://backstage.io/catalog-info.yaml', + type: 'unknown', + }); + }); + + it('should not allow locations of unknown types by default', async () => { + const locationService = new DefaultLocationService( + store, + orchestrator, + new ConfigReader({}), + ); + await expect( + locationService.createLocation( + { + type: 'unknown', + target: 'https://backstage.io/catalog-info.yaml', + }, + false, + ), + ).rejects.toThrow(InputError); + }); + + it('should not allow locations of unknown types if configuration forbids it', async () => { + const locationService = new DefaultLocationService( + store, + orchestrator, + mockConfig(false), + ); await expect( locationService.createLocation( { @@ -279,6 +371,11 @@ describe('DefaultLocationServiceTest', () => { errors: [new Error('Error: Unable to read url')], }); + const locationService = new DefaultLocationService( + store, + orchestrator, + mockConfig(false), + ); await expect( locationService.createLocation( { @@ -293,6 +390,11 @@ describe('DefaultLocationServiceTest', () => { describe('listLocations', () => { it('should call locationStore.deleteLocation', async () => { + const locationService = new DefaultLocationService( + store, + orchestrator, + mockConfig(false), + ); await locationService.listLocations(); expect(store.listLocations).toBeCalled(); }); @@ -300,6 +402,11 @@ describe('DefaultLocationServiceTest', () => { describe('deleteLocation', () => { it('should call locationStore.deleteLocation', async () => { + const locationService = new DefaultLocationService( + store, + orchestrator, + mockConfig(false), + ); await locationService.deleteLocation('123'); expect(store.deleteLocation).toBeCalledWith('123'); }); @@ -307,6 +414,11 @@ describe('DefaultLocationServiceTest', () => { describe('getLocation', () => { it('should call locationStore.getLocation', async () => { + const locationService = new DefaultLocationService( + store, + orchestrator, + mockConfig(false), + ); await locationService.getLocation('123'); expect(store.getLocation).toBeCalledWith('123'); }); diff --git a/plugins/catalog-backend/src/service/DefaultLocationService.ts b/plugins/catalog-backend/src/service/DefaultLocationService.ts index 819cead63d..e70d72a9ee 100644 --- a/plugins/catalog-backend/src/service/DefaultLocationService.ts +++ b/plugins/catalog-backend/src/service/DefaultLocationService.ts @@ -26,18 +26,26 @@ import { LocationInput, LocationService, LocationStore } from './types'; import { locationSpecToMetadataName } from '../util/conversion'; import { InputError } from '@backstage/errors'; import { DeferredEntity } from '@backstage/plugin-catalog-node'; +import { Config } from '@backstage/config'; export class DefaultLocationService implements LocationService { constructor( private readonly store: LocationStore, private readonly orchestrator: CatalogProcessingOrchestrator, + private readonly config: Config, ) {} async createLocation( input: LocationInput, dryRun: boolean, ): Promise<{ location: Location; entities: Entity[]; exists?: boolean }> { - if (input.type !== 'url') { + const allowUnknownTypeConfigName = + 'catalog.locationService.create.allowUnknownType'; + const allowUnknownType = + this.config.has(allowUnknownTypeConfigName) && + this.config.getBoolean(allowUnknownTypeConfigName); + + if (!allowUnknownType && input.type !== 'url') { throw new InputError(`Registered locations must be of type 'url'`); } if (dryRun) { From 2ab80d3c2577e3c1d0f5159d6767fa201004f63a Mon Sep 17 00:00:00 2001 From: blam Date: Tue, 16 Aug 2022 09:34:59 +0200 Subject: [PATCH 002/198] chore: starting to work on some stuff Signed-off-by: blam --- microsite/core/Typeform.js | 41 +++++++++++++++++++++---------------- microsite/pages/en/index.js | 1 - 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/microsite/core/Typeform.js b/microsite/core/Typeform.js index c737d907f0..ff0c5da0ee 100644 --- a/microsite/core/Typeform.js +++ b/microsite/core/Typeform.js @@ -1,21 +1,26 @@ import React from 'react'; -export function Typeform() { - return ( - <> -
- +
+ ); + } } diff --git a/microsite/pages/en/index.js b/microsite/pages/en/index.js index 2581fdbf2f..4f2a0ecf3d 100644 --- a/microsite/pages/en/index.js +++ b/microsite/pages/en/index.js @@ -18,7 +18,6 @@ class Index extends React.Component { render() { const { config: siteConfig } = this.props; const { baseUrl } = siteConfig; - return (
From 679f7c5e95be93fc639b3aa9cd3677a29de6a7bb Mon Sep 17 00:00:00 2001 From: "TANGUY Antoine (SIB)" Date: Tue, 16 Aug 2022 16:51:29 +0200 Subject: [PATCH 003/198] fix(catalog-backend): add entity ref within errors Signed-off-by: TANGUY Antoine (SIB) --- .changeset/small-lemons-brake.md | 5 ++ ...faultCatalogProcessingOrchestrator.test.ts | 76 +++++++++++++++---- .../DefaultCatalogProcessingOrchestrator.ts | 11 ++- 3 files changed, 75 insertions(+), 17 deletions(-) create mode 100644 .changeset/small-lemons-brake.md diff --git a/.changeset/small-lemons-brake.md b/.changeset/small-lemons-brake.md new file mode 100644 index 0000000000..ac7906fc28 --- /dev/null +++ b/.changeset/small-lemons-brake.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +Include entity ref into error message when catalog policies fail diff --git a/plugins/catalog-backend/src/processing/DefaultCatalogProcessingOrchestrator.test.ts b/plugins/catalog-backend/src/processing/DefaultCatalogProcessingOrchestrator.test.ts index 30c668bb38..cbb130d138 100644 --- a/plugins/catalog-backend/src/processing/DefaultCatalogProcessingOrchestrator.test.ts +++ b/plugins/catalog-backend/src/processing/DefaultCatalogProcessingOrchestrator.test.ts @@ -20,6 +20,7 @@ import { ANNOTATION_ORIGIN_LOCATION, Entity, EntityPolicies, + EntityPolicy, LocationEntity, } from '@backstage/catalog-model'; import { ScmIntegrations } from '@backstage/integration'; @@ -35,6 +36,7 @@ import { CatalogRulesEnforcer } from '../ingestion/CatalogRules'; import { DefaultCatalogProcessingOrchestrator } from './DefaultCatalogProcessingOrchestrator'; import { defaultEntityDataParser } from '../modules/util/parse'; import { ConfigReader } from '@backstage/config'; +import { InputError } from '@backstage/errors'; class FooBarProcessor implements CatalogProcessor { getProcessorName = () => 'foo-bar'; @@ -191,23 +193,23 @@ describe('DefaultCatalogProcessingOrchestrator', () => { }); describe('rules', () => { - it('enforces catalog rules', async () => { - const entity: LocationEntity = { - apiVersion: 'backstage.io/v1beta1', - kind: 'Location', - metadata: { - name: 'l', - annotations: { - [ANNOTATION_ORIGIN_LOCATION]: 'url:https://example.com/origin.yaml', - [ANNOTATION_LOCATION]: 'url:https://example.com/origin.yaml', - }, + const entity: LocationEntity = { + apiVersion: 'backstage.io/v1beta1', + kind: 'Location', + metadata: { + name: 'l', + annotations: { + [ANNOTATION_ORIGIN_LOCATION]: 'url:https://example.com/origin.yaml', + [ANNOTATION_LOCATION]: 'url:https://example.com/origin.yaml', }, - spec: { - type: 'url', - target: 'http://example.com/entity.yaml', - }, - }; + }, + spec: { + type: 'url', + target: 'http://example.com/entity.yaml', + }, + }; + it('enforces catalog rules', async () => { const integrations = ScmIntegrations.fromConfig(new ConfigReader({})); const processor: jest.Mocked = { getProcessorName: jest.fn(), @@ -241,5 +243,49 @@ describe('DefaultCatalogProcessingOrchestrator', () => { orchestrator.process({ entity, state: {} }), ).resolves.toEqual(expect.objectContaining({ ok: false })); }); + + it('includes entity ref within error', async () => { + const integrations = ScmIntegrations.fromConfig(new ConfigReader({})); + const processor: jest.Mocked = { + getProcessorName: jest.fn(), + validateEntityKind: jest.fn(async () => true), + readLocation: jest.fn(async (_l, _o, emit) => { + emit(processingResult.entity({ type: 't', target: 't' }, entity)); + return true; + }), + }; + const parser: CatalogProcessorParser = jest.fn(); + const rulesEnforcer: jest.Mocked = { + isAllowed: jest.fn(), + }; + + class FailingEntityPolicy implements EntityPolicy { + async enforce(_entity: Entity): Promise { + // eslint-disable-next-line no-throw-literal + throw 'boom'; + } + } + const orchestrator = new DefaultCatalogProcessingOrchestrator({ + processors: [processor], + integrations, + logger: getVoidLogger(), + parser, + policy: EntityPolicies.allOf([new FailingEntityPolicy()]), + rulesEnforcer, + }); + + await expect( + orchestrator.process({ entity, state: {} }), + ).resolves.toEqual( + expect.objectContaining({ + ok: false, + errors: [ + new InputError( + "Policy check failed for location:default/l; caused by unknown error 'boom'", + ), + ], + }), + ); + }); }); }); diff --git a/plugins/catalog-backend/src/processing/DefaultCatalogProcessingOrchestrator.ts b/plugins/catalog-backend/src/processing/DefaultCatalogProcessingOrchestrator.ts index 9effaeb3d9..79876f70d8 100644 --- a/plugins/catalog-backend/src/processing/DefaultCatalogProcessingOrchestrator.ts +++ b/plugins/catalog-backend/src/processing/DefaultCatalogProcessingOrchestrator.ts @@ -211,11 +211,18 @@ export class DefaultCatalogProcessingOrchestrator try { policyEnforcedEntity = await this.options.policy.enforce(entity); } catch (e) { - throw new InputError('Policy check failed', e); + throw new InputError( + `Policy check failed for ${stringifyEntityRef(entity)}`, + e, + ); } if (!policyEnforcedEntity) { - throw new Error('Policy unexpectedly returned no data'); + throw new Error( + `Policy unexpectedly returned no data for ${stringifyEntityRef( + entity, + )}`, + ); } return policyEnforcedEntity; From 3dc550cf65f32d2b5b7684986e9407c2a1cf5bad Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 17 Aug 2022 15:36:23 +0200 Subject: [PATCH 004/198] chore: now we have hubspot! Signed-off-by: blam --- microsite/core/HubSpotForm.js | 40 ++ microsite/core/Typeform.js | 26 - microsite/pages/en/index.js | 1037 ++++++++++++++++--------------- microsite/static/css/custom.css | 63 ++ 4 files changed, 631 insertions(+), 535 deletions(-) create mode 100644 microsite/core/HubSpotForm.js delete mode 100644 microsite/core/Typeform.js diff --git a/microsite/core/HubSpotForm.js b/microsite/core/HubSpotForm.js new file mode 100644 index 0000000000..2905909ffe --- /dev/null +++ b/microsite/core/HubSpotForm.js @@ -0,0 +1,40 @@ +import React from 'react'; + +export class HubSpotForm extends React.Component { + render() { + return ( + <> + + + ); + } +} diff --git a/microsite/core/Typeform.js b/microsite/core/Typeform.js deleted file mode 100644 index ff0c5da0ee..0000000000 --- a/microsite/core/Typeform.js +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react'; - -export class Typeform extends React.Component { - componentDidMount() { - console.log('ere'); - } - render() { - return ( -
-
- - -
- ); - } -} diff --git a/microsite/pages/en/index.js b/microsite/pages/en/index.js index 4f2a0ecf3d..00110fdf9d 100644 --- a/microsite/pages/en/index.js +++ b/microsite/pages/en/index.js @@ -6,540 +6,559 @@ */ const React = require('react'); +const { HubSpotForm } = require(`${process.cwd()}/core/HubSpotForm.js`); const Components = require(`${process.cwd()}/core/Components.js`); const Block = Components.Block; const ActionBlock = Components.ActionBlock; const Breakpoint = Components.Breakpoint; const BulletLine = Components.BulletLine; const Banner = Components.Banner; -const { Typeform } = require(`${process.cwd()}/core/Typeform.js`); class Index extends React.Component { render() { const { config: siteConfig } = this.props; const { baseUrl } = siteConfig; return ( -
- - - -
- 🗞️ Want to stay up to date with Backstage? Sign up for our{' '} - - Newsletter - - ! -
-
-
+ +
+ + +
+ 🗞️ Want to stay up to date with Backstage? Sign up for our{' '} + + Newsletter + + ! +
+
+
- - - - - An open platform for building developer portals - - - Powered by a centralized software catalog, Backstage restores - order to your infrastructure and enables your product teams to - ship high-quality code quickly — without compromising autonomy. - - - GitHub - - - - - - - - + + + + + An open platform for building developer portals + + + Powered by a centralized software catalog, Backstage restores + order to your infrastructure and enables your product teams to + ship high-quality code quickly — without compromising + autonomy. + + + GitHub + + + + + + + + - - - - - The Speed Paradox - - At Spotify, we’ve always believed in the speed and ingenuity - that comes from having autonomous development teams. But as we - learned firsthand, the faster you grow, the more fragmented and - complex your software ecosystem becomes. And then everything - slows down again. - - - - - The Standards Paradox - - By centralizing services and standardizing your tooling, - Backstage streamlines your development environment from end to - end. Instead of restricting autonomy, standardization frees your - engineers from infrastructure complexity. So you can return to - building and scaling, quickly and safely. - - - - + + + + + The Speed Paradox + + At Spotify, we’ve always believed in the speed and ingenuity + that comes from having autonomous development teams. But as we + learned firsthand, the faster you grow, the more fragmented + and complex your software ecosystem becomes. And then + everything slows down again. + + + + + The Standards Paradox + + By centralizing services and standardizing your tooling, + Backstage streamlines your development environment from end to + end. Instead of restricting autonomy, standardization frees + your engineers from infrastructure complexity. So you can + return to building and scaling, quickly and safely. + + + + - - - - {' '} - - Backstage Software Catalog - - Build an ecosystem, not a wilderness - - - - - - } - /> - - - - Manage all your software, all in one place{' '} - - - Backstage makes it easy for one team to manage 10 services — and - makes it possible for your company to manage thousands of them - - - - - A uniform overview - - Every team can see all the services they own and related - resources (deployments, data pipelines, pull request status, - etc.) - - - - - - Metadata on tap - - All that information can be shared with plugins inside Backstage - to enable other management features, like resource monitoring - and testing - - - - - - Not just services - - Libraries, websites, ML models — you name it, Backstage knows - all about it, including who owns it, dependencies, and more - - - - - - - Discoverability & accountability - - - No more orphan software hiding in the dark corners of your tech - stack - - - - - - - - - Learn more about the software catalog - - - Read - - - - - - - - Backstage Software Templates - Standards can set you free - - - - - } - /> - - - - Like automated getting started guides - - - Using templates, engineers can spin up a new microservice with - your organization’s best practices built-in, right from the - start - - - - - - Push-button deployment - - Click a button to create a Spring Boot project with your repo - automatically configured on GitHub and your CI already running - the first build - - - - - - Built to your standards - - Go instead of Java? CircleCI instead of Jenkins? Serverless - instead of Kubernetes? GCP instead of AWS? Customize your - recipes with your best practices baked-in - - - - - - - Golden Paths pave the way - - - When the right way is also the easiest way, engineers get up and - running faster — and more safely - - - - - - } - /> - - - - - - Build your own software templates - - - Contribute - - - - - - - - - Backstage TechDocs - Docs like code - - - + + + + {' '} + + Backstage Software Catalog + + Build an ecosystem, not a wilderness + + + - - } - /> - - - Free documentation - - Whenever you use a Backstage Software Template, your project - automatically gets a TechDocs site, for free - - - - - - Easy to write - - With our docs-like-code approach, engineers write their - documentation in Markdown files right alongside their code - - - - - - Easy to maintain - - Updating code? Update your documentation while you’re there — - with docs and code in the same place, it becomes a natural part - of your workstream - - - - - - Easy to find and use - - Since all your documentation is in Backstage, finding any - TechDoc is just a search query away - - - - - - - } - /> - - - - - Learn more about TechDocs - - Docs - - - - - - - - - Backstage Kubernetes - - Manage your services, not clusters - - - - - - - Kubernetes made just for service owners - - - Backstage features the first Kubernetes monitoring tool designed - around the needs of service owners, not cluster admins - - - - - - - Your service at a glance - - - Get all your service's deployments in one, aggregated view — no - more digging through cluster logs in a CLI, no more combing - through lists of services you don't own - - - - - - Pick a cloud, any cloud - - Since Backstage uses the Kubernetes API, it's cloud agnostic — - so it works no matter which cloud provider or managed Kubernetes - service you use, and even works in multi-cloud orgs - - - - - - Any K8s, one UI - - Now you don't have to switch dashboards when you move from local - testing to production, or from one cloud provider to another - - - - - - Learn more about the K8s plugin - - Read - - - - - - - + + + Manage all your software, all in one place{' '} + + + Backstage makes it easy for one team to manage 10 services — + and makes it possible for your company to manage thousands of + them + + + + + A uniform overview + + Every team can see all the services they own and related + resources (deployments, data pipelines, pull request status, + etc.) + + + + + + Metadata on tap + + All that information can be shared with plugins inside + Backstage to enable other management features, like resource + monitoring and testing + + - Customize Backstage with plugins - - An app store for your infrastructure - - - - - - } - /> - - - Add functionality - - Want scalable website testing? Add the{' '} - - Lighthouse - {' '} - plugin. Wondering about recommended frameworks? Add the{' '} - - Tech Radar - {' '} - plugin.{' '} - - + + + Not just services + + Libraries, websites, ML models — you name it, Backstage knows + all about it, including who owns it, dependencies, and more + + - - - BYO Plugins - - If you don’t see the plugin you need, it’s simple to build your - own - - + + + + Discoverability & accountability + + + No more orphan software hiding in the dark corners of your + tech stack + + + + + - - + + + Learn more about the software catalog + + + Read + + + + + + + + Backstage Software Templates + Standards can set you free + + + + + } + /> + + + + Like automated getting started guides + + + Using templates, engineers can spin up a new microservice with + your organization’s best practices built-in, right from the + start + + + + + + + Push-button deployment + + + Click a button to create a Spring Boot project with your repo + automatically configured on GitHub and your CI already running + the first build + + + + + + + Built to your standards + + + Go instead of Java? CircleCI instead of Jenkins? Serverless + instead of Kubernetes? GCP instead of AWS? Customize your + recipes with your best practices baked-in + + + + + + + Golden Paths pave the way + + + When the right way is also the easiest way, engineers get up + and running faster — and more safely + + + + + + } + /> + + + + + + Build your own software templates + + + Contribute + + + + + + + + + Backstage TechDocs + Docs like code + + + + + + + } + /> + + + Free documentation + + Whenever you use a Backstage Software Template, your project + automatically gets a TechDocs site, for free + + + + + + Easy to write + + With our docs-like-code approach, engineers write their + documentation in Markdown files right alongside their code + + + + + + Easy to maintain + + Updating code? Update your documentation while you’re there — + with docs and code in the same place, it becomes a natural + part of your workstream + + + + + + Easy to find and use + + Since all your documentation is in Backstage, finding any + TechDoc is just a search query away + + + + + + + } + /> + + + + + Learn more about TechDocs + + Docs + + + + + + + + + Backstage Kubernetes + + Manage your services, not clusters + + + + + + + Kubernetes made just for service owners + + + Backstage features the first Kubernetes monitoring tool + designed around the needs of service owners, not cluster + admins + + + + + + + Your service at a glance + + + Get all your service's deployments in one, aggregated view — + no more digging through cluster logs in a CLI, no more combing + through lists of services you don't own + + + + + + + Pick a cloud, any cloud + + + Since Backstage uses the Kubernetes API, it's cloud agnostic — + so it works no matter which cloud provider or managed + Kubernetes service you use, and even works in multi-cloud orgs + + + + + + Any K8s, one UI + + Now you don't have to switch dashboards when you move from + local testing to production, or from one cloud provider to + another + + + + + + + Learn more about the K8s plugin + + + Read + + + + + + + + + + Customize Backstage with plugins + + + An app store for your infrastructure + + + + + + } + /> + + + Add functionality + + Want scalable website testing? Add the{' '} + + Lighthouse + {' '} + plugin. Wondering about recommended frameworks? Add the{' '} + + Tech Radar + {' '} + plugin.{' '} + + + + + + BYO Plugins + + If you don’t see the plugin you need, it’s simple to build + your own + + + + + + + Integrate your own custom tooling + + + Building internal plugins lets you tailor your version of + Backstage to be a perfect fit for your infrastructure + + + + + + + Share with the community + + + Building open source plugins{' '} + contributes to the entire Backstage ecosystem, which benefits + everyone + + + + } + /> + + + + + Build a plugin + + Contribute + + + + + - Integrate your own custom tooling + Backstage is a{' '} + + Cloud Native Computing Foundation + {' '} + incubation project +
- - Building internal plugins lets you tailor your version of - Backstage to be a perfect fit for your infrastructure - - - - - - - Share with the community - - - Building open source plugins contributes - to the entire Backstage ecosystem, which benefits everyone - - - - } - /> - - - - - Build a plugin - - Contribute - - - - - - - Backstage is a{' '} - - Cloud Native Computing Foundation - {' '} - incubation project -
- - - -
+ + +
+ + ); } } diff --git a/microsite/static/css/custom.css b/microsite/static/css/custom.css index 30267a9f42..71adbc2a4e 100644 --- a/microsite/static/css/custom.css +++ b/microsite/static/css/custom.css @@ -1227,3 +1227,66 @@ code { h3.collapsible span.arrow { margin-right: 4px; } + +.Sidebar__Container { + top: 50%; + right: 0; + position: fixed; + color: rgb(0, 0, 0); + transition: transform 250ms ease-in-out; + display: flex; + align-items: center; + transform: translateY(-50%) translateX(500px); +} + +.Sidebar__Container--open { + transform: translateY(-50%); +} + +.Sidebar__Button { + transform: rotate(-90deg) translateY(48px); + padding: 12px 16px; + border-radius: 8px 8px 0 0; + background-color: rgb(92, 214, 200); + color: rgb(0, 0, 0); + outline: 0; + border: 0; + font-family: Helvetica Neue, sans-serif; + max-height: 48px; + max-width: 150px; + font-size: 16px; + cursor: pointer; +} + +.Sidebar__Button:hover { + transform: rotate(-90deg) translateY(48px) scale(1.01); +} + +#Sidebar__HubSpotContainer { + width: 500px; + background-color: white; + border-radius: 8px 0 0 8px; + padding: 16px; + padding-bottom: 0px; + z-index: 10001; + min-height: 260px; +} + +#Sidebar__HubSpotContainer .hs-button { + padding: 12px 16px; + border-radius: 8px; + background-color: rgb(92, 214, 200); + color: rgb(0, 0, 0); + border: 0; +} +#Sidebar__HubSpotContainer.submitted-message { + min-height: 260px; + display: flex; + flex-direction: column; + justify-content: center; + padding: 0 16px; +} + +#Sidebar__HubSpotContainer.submitted-message p { + color: rgb(0, 0, 0); +} From 61d1e08b51989b54454007d9e693c93d68ffb51c Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 17 Aug 2022 15:37:48 +0200 Subject: [PATCH 005/198] chore: replacing the links to the letter Signed-off-by: blam --- microsite/blog/2020-06-22-backstage-service-catalog-alpha.md | 2 +- .../2020-08-05-announcing-backstage-software-templates.md | 2 +- microsite/blog/2020-09-23-backstage-cncf-sandbox.md | 2 +- microsite/blog/2021-06-22-spotify-backstage-is-growing.md | 2 +- microsite/blog/2021-09-30-50-public-adopters.md | 2 +- microsite/core/Footer.js | 2 +- microsite/pages/en/community.js | 4 ++-- microsite/pages/en/index.js | 2 +- microsite/pages/en/live.js | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/microsite/blog/2020-06-22-backstage-service-catalog-alpha.md b/microsite/blog/2020-06-22-backstage-service-catalog-alpha.md index 4519f16d96..7f8fe01e11 100644 --- a/microsite/blog/2020-06-22-backstage-service-catalog-alpha.md +++ b/microsite/blog/2020-06-22-backstage-service-catalog-alpha.md @@ -51,4 +51,4 @@ As with most alpha releases, you should expect things to change quite a lot unti If you have feedback or questions, please open a [GitHub issue](https://github.com/backstage/backstage/issues), ping us on [Discord chat](https://discord.gg/EBHEGzX) or send us an email at [backstage-interest@spotify.com](mailto:backstage-interest@spotify.com) 🙏 -To get regular product updates and news about the Backstage community, sign up for the [Backstage newsletter](https://mailchi.mp/spotify/backstage-community). +To get regular product updates and news about the Backstage community, sign up for the [Backstage newsletter](https://info.backstage.spotify.com/newsletter_subscribe). diff --git a/microsite/blog/2020-08-05-announcing-backstage-software-templates.md b/microsite/blog/2020-08-05-announcing-backstage-software-templates.md index 0bf8d7e581..18bfa64c19 100644 --- a/microsite/blog/2020-08-05-announcing-backstage-software-templates.md +++ b/microsite/blog/2020-08-05-announcing-backstage-software-templates.md @@ -75,4 +75,4 @@ We have learned that one of the keys to getting these standards adopted is to ke If you have feedback or questions, please open a [GitHub issue](https://github.com/backstage/backstage/issues), ping us on [Discord chat](https://discord.gg/EBHEGzX) or send us an email at [backstage-interest@spotify.com](mailto:backstage-interest@spotify.com) 🙏 -To get regular product updates and news about the Backstage community, sign up for the [Backstage newsletter](https://mailchi.mp/spotify/backstage-community). +To get regular product updates and news about the Backstage community, sign up for the [Backstage newsletter](https://info.backstage.spotify.com/newsletter_subscribe). diff --git a/microsite/blog/2020-09-23-backstage-cncf-sandbox.md b/microsite/blog/2020-09-23-backstage-cncf-sandbox.md index 48a67e878c..70ef06f242 100644 --- a/microsite/blog/2020-09-23-backstage-cncf-sandbox.md +++ b/microsite/blog/2020-09-23-backstage-cncf-sandbox.md @@ -18,4 +18,4 @@ The Backstage community is healthy and growing quickly. Over [130 people](https: We’re excited to embark on this journey with the CNCF community. There’s so much great tech being built here, and it’s about time we share it to build even greater products, together. Entering into the CNCF Sandbox is just the first step. We are committed to working with the community to bring Backstage through the Incubation step, and finally all the way to becoming a Graduated, top-level project. -Thanks to everyone for your support so far. We hope you [join us](https://mailchi.mp/spotify/backstage-community) in this next chapter of Backstage's journey. If you have questions or feedback, feel free to [email](mailto:backstage-interest@spotify.com) me directly. +Thanks to everyone for your support so far. We hope you [join us](https://info.backstage.spotify.com/newsletter_subscribe) in this next chapter of Backstage's journey. If you have questions or feedback, feel free to [email](mailto:backstage-interest@spotify.com) me directly. diff --git a/microsite/blog/2021-06-22-spotify-backstage-is-growing.md b/microsite/blog/2021-06-22-spotify-backstage-is-growing.md index 2507192a4a..a12ddf7443 100644 --- a/microsite/blog/2021-06-22-spotify-backstage-is-growing.md +++ b/microsite/blog/2021-06-22-spotify-backstage-is-growing.md @@ -49,7 +49,7 @@ We’ve launched a new website at: [backstage.spotify.com](https://backstage.spo You’ll find a high-level introduction to the platform, tips and tricks tested by Spotify to accelerate developer effectiveness, and access to a group of partners that have scaled Backstage for numerous adopters. You can also use the site to book product overviews, demos, and technical deep dives with members of the Spotify team. -We will continue to post important product announcements, technical documentation, feature demos, and community news here on Backstage.io. ([Subscribe to the newsletter](https://mailchi.mp/spotify/backstage-community) to stay up to date.) And both contributors and adopting companies can continue to find around-the-clock/around-the-world technical support on [GitHub](https://github.com/backstage/backstage) and [Discord](https://discord.gg/MUpMjP2). +We will continue to post important product announcements, technical documentation, feature demos, and community news here on Backstage.io. ([Subscribe to the newsletter](https://info.backstage.spotify.com/newsletter_subscribe) to stay up to date.) And both contributors and adopting companies can continue to find around-the-clock/around-the-world technical support on [GitHub](https://github.com/backstage/backstage) and [Discord](https://discord.gg/MUpMjP2). ## Separate community sessions for adopters and contributors diff --git a/microsite/blog/2021-09-30-50-public-adopters.md b/microsite/blog/2021-09-30-50-public-adopters.md index 3e96cade69..6a4652b99f 100644 --- a/microsite/blog/2021-09-30-50-public-adopters.md +++ b/microsite/blog/2021-09-30-50-public-adopters.md @@ -41,5 +41,5 @@ If you are a Backstage enthusiast, please [join me][news] and the entire Backsta [da]: https://medium.com/dazn-tech/developer-experience-dx-at-dazn-e6de9a0208d2 [ex]: https://backstage.spotify.com/blog/community-session/firehydrant-expedia-loblaw/ [plugins]: https://backstage.io/plugins -[news]: https://mailchi.mp/spotify/backstage-community +[news]: https://info.backstage.spotify.com/newsletter_subscribe [gh]: https://github.com/backstage/backstage/blob/master/ADOPTERS.md diff --git a/microsite/core/Footer.js b/microsite/core/Footer.js index f0917d3255..327e42f38a 100644 --- a/microsite/core/Footer.js +++ b/microsite/core/Footer.js @@ -48,7 +48,7 @@ class Footer extends React.Component { Community Sessions - + Subscribe to our newsletter CNCF Incubation diff --git a/microsite/pages/en/community.js b/microsite/pages/en/community.js index 3d79c82f93..2e7801d581 100644 --- a/microsite/pages/en/community.js +++ b/microsite/pages/en/community.js @@ -76,7 +76,7 @@ const Background = props => {
  • Subscribe to the{' '} - + Community newsletter @@ -122,7 +122,7 @@ const Background = props => { The official monthly Backstage newsletter. Don't miss the latest news from your favorite project! - + Subscribe diff --git a/microsite/pages/en/index.js b/microsite/pages/en/index.js index 00110fdf9d..3d42ef6280 100644 --- a/microsite/pages/en/index.js +++ b/microsite/pages/en/index.js @@ -25,7 +25,7 @@ class Index extends React.Component {
    🗞️ Want to stay up to date with Backstage? Sign up for our{' '} - + Newsletter ! diff --git a/microsite/pages/en/live.js b/microsite/pages/en/live.js index ee681a0835..2483b2f8bf 100644 --- a/microsite/pages/en/live.js +++ b/microsite/pages/en/live.js @@ -64,7 +64,7 @@ const Background = props => { Good First Issues
    - Subscribe to the{' '} - + Community newsletter
    - Join the{' '} From 09fa81a1ef6214ed7a577bd31526932b697216f0 Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 17 Aug 2022 15:53:07 +0200 Subject: [PATCH 006/198] chore: fix the hubspot links Signed-off-by: blam --- docs/overview/roadmap.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/overview/roadmap.md b/docs/overview/roadmap.md index 2763f95a5a..a84fd6c83c 100644 --- a/docs/overview/roadmap.md +++ b/docs/overview/roadmap.md @@ -111,5 +111,5 @@ guidelines to get started. If you have specific questions about the roadmap, please create an [issue](https://github.com/backstage/backstage/issues/new/choose), ping us on -[Discord](https://discord.gg/qxsEfa8Vq8), or [book -time](http://calendly.com/spotify-backstage) with the Spotify team. +[Discord](https://discord.gg/qxsEfa8Vq8), or [book +time](https://info.backstage.spotify.com/office-hours) with the Spotify team. From a69ac5b63aa16f7b92707f9ef41169e9e62e8260 Mon Sep 17 00:00:00 2001 From: Tomasz Szuba Date: Wed, 17 Aug 2022 15:53:56 +0200 Subject: [PATCH 007/198] [gcalendar] Upgrade `react-query:3` to `@tanstack/react-query:4` Signed-off-by: Tomasz Szuba --- .changeset/rich-melons-compete.md | 5 + plugins/gcalendar/package.json | 2 +- .../CalendarCard/HomePageCalendar.tsx | 2 +- .../gcalendar/src/hooks/useCalendarsQuery.ts | 2 +- plugins/gcalendar/src/hooks/useEventsQuery.ts | 12 +-- yarn.lock | 102 +++++------------- 6 files changed, 39 insertions(+), 86 deletions(-) create mode 100644 .changeset/rich-melons-compete.md diff --git a/.changeset/rich-melons-compete.md b/.changeset/rich-melons-compete.md new file mode 100644 index 0000000000..68297159f7 --- /dev/null +++ b/.changeset/rich-melons-compete.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-gcalendar': patch +--- + +Upgrade `react-query:3` to `@tanstack/react-query:4` diff --git a/plugins/gcalendar/package.json b/plugins/gcalendar/package.json index cc7fdfa61c..6983bfcd8e 100644 --- a/plugins/gcalendar/package.json +++ b/plugins/gcalendar/package.json @@ -30,13 +30,13 @@ "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", "@maxim_mazurok/gapi.client.calendar": "^3.0.20220408", + "@tanstack/react-query": "^4.1.3", "classnames": "^2.3.1", "cross-fetch": "^3.1.5", "dompurify": "^2.3.6", "lodash": "^4.17.21", "luxon": "^3.0.0", "material-ui-popup-state": "^1.9.3", - "react-query": "^3.34.16", "react-use": "^17.2.4" }, "peerDependencies": { diff --git a/plugins/gcalendar/src/components/CalendarCard/HomePageCalendar.tsx b/plugins/gcalendar/src/components/CalendarCard/HomePageCalendar.tsx index afe7a0fada..406a4dfca6 100644 --- a/plugins/gcalendar/src/components/CalendarCard/HomePageCalendar.tsx +++ b/plugins/gcalendar/src/components/CalendarCard/HomePageCalendar.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ import React from 'react'; -import { QueryClient, QueryClientProvider } from 'react-query'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { CalendarCard } from './CalendarCard'; diff --git a/plugins/gcalendar/src/hooks/useCalendarsQuery.ts b/plugins/gcalendar/src/hooks/useCalendarsQuery.ts index a76142ff09..ab581c5782 100644 --- a/plugins/gcalendar/src/hooks/useCalendarsQuery.ts +++ b/plugins/gcalendar/src/hooks/useCalendarsQuery.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { errorApiRef, useApi } from '@backstage/core-plugin-api'; diff --git a/plugins/gcalendar/src/hooks/useEventsQuery.ts b/plugins/gcalendar/src/hooks/useEventsQuery.ts index 8f8ca68e4f..5dd5fb9b32 100644 --- a/plugins/gcalendar/src/hooks/useEventsQuery.ts +++ b/plugins/gcalendar/src/hooks/useEventsQuery.ts @@ -15,12 +15,11 @@ */ import { compact, unescape } from 'lodash'; import { useMemo } from 'react'; -import { useQueries } from 'react-query'; +import { useQueries } from '@tanstack/react-query'; import { useApi } from '@backstage/core-plugin-api'; -import { gcalendarApiRef } from '../api'; -import { GCalendar, GCalendarEvent } from '../api'; +import { gcalendarApiRef, GCalendar, GCalendarEvent } from '../api'; type Options = { selectedCalendars?: string[]; @@ -41,8 +40,8 @@ export const useEventsQuery = ({ timeZone, }: Options) => { const calendarApi = useApi(gcalendarApiRef); - const eventQueries = useQueries( - selectedCalendars + const eventQueries = useQueries({ + queries: selectedCalendars .filter(id => calendars.find(c => c.id === id)) .map(calendarId => { const calendar = calendars.find(c => c.id === calendarId); @@ -53,6 +52,7 @@ export const useEventsQuery = ({ initialData: [], refetchInterval: 60000, refetchIntervalInBackground: true, + queryFn: async (): Promise => { const data = await calendarApi.getEvents(calendarId, { calendarId, @@ -82,7 +82,7 @@ export const useEventsQuery = ({ }, }; }), - ); + }); const events = useMemo( () => compact(eventQueries.map(({ data }) => data).flat()), diff --git a/yarn.lock b/yarn.lock index 6f8286da14..24471f7b22 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1929,7 +1929,7 @@ core-js-pure "^3.20.2" regenerator-runtime "^0.13.4" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.6", "@babel/runtime@^7.15.4", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.6.2", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.6", "@babel/runtime@^7.15.4", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": version "7.17.7" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.7.tgz#a5f3328dc41ff39d803f311cfe17703418cf9825" integrity sha512-L6rvG9GDxaLgFjg41K+5Yv9OMrU98sWe+Ykmc6FDJW/+vYZMhdOMKkISgzptMaERHvS2Y2lw9MDRm2gHhlQQoA== @@ -6301,6 +6301,20 @@ dependencies: defer-to-connect "^2.0.0" +"@tanstack/query-core@^4.0.0-beta.1": + version "4.2.1" + resolved "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.2.1.tgz#21ff3a33f27bf038c990ea53af89cf7c7e8078fc" + integrity sha512-UOyOhHKLS/5i9qG2iUnZNVV3R9riJJmG9eG+hnMFIPT/oRh5UzAfjxCtBneNgPQZLDuP8y6YtRYs/n4qVAD5Ng== + +"@tanstack/react-query@^4.1.3": + version "4.2.1" + resolved "https://registry.npmjs.org/@tanstack/react-query/-/react-query-4.2.1.tgz#1f00f03573b35a353e62fa64f904bbb0286a1808" + integrity sha512-w02oTOYpoxoBzD/onAGRQNeLAvggLn7WZjS811cT05WAE/4Q3br0PTp388M7tnmyYGbgOOhFq0MkhH0wIfAKqA== + dependencies: + "@tanstack/query-core" "^4.0.0-beta.1" + "@types/use-sync-external-store" "^0.0.3" + use-sync-external-store "^1.2.0" + "@testing-library/cypress@^8.0.2": version "8.0.3" resolved "https://registry.npmjs.org/@testing-library/cypress/-/cypress-8.0.3.tgz#24ab34df34d7896866603ade705afbdd186e273c" @@ -7753,6 +7767,11 @@ resolved "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d" integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ== +"@types/use-sync-external-store@^0.0.3": + version "0.0.3" + resolved "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz#b6725d5f4af24ace33b36fafd295136e75509f43" + integrity sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA== + "@types/uuid@^8.0.0": version "8.3.4" resolved "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" @@ -9341,11 +9360,6 @@ bfj@^7.0.2: hoopy "^0.1.4" tryer "^1.0.1" -big-integer@^1.6.16: - version "1.6.51" - resolved "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" - integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== - big.js@^5.2.2: version "5.2.2" resolved "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" @@ -9538,20 +9552,6 @@ breakword@^1.0.5: dependencies: wcwidth "^1.0.1" -broadcast-channel@^3.4.1: - version "3.7.0" - resolved "https://registry.npmjs.org/broadcast-channel/-/broadcast-channel-3.7.0.tgz#2dfa5c7b4289547ac3f6705f9c00af8723889937" - integrity sha512-cIAKJXAxGJceNZGTZSBzMxzyOn72cVgPnKx4dc6LRjQgbaJUQqhy5rzL3zbMxkMWsGKkv2hSFkPRMEXfoMZ2Mg== - dependencies: - "@babel/runtime" "^7.7.2" - detect-node "^2.1.0" - js-sha3 "0.8.0" - microseconds "0.2.0" - nano-time "1.0.0" - oblivious-set "1.0.0" - rimraf "3.0.2" - unload "2.2.0" - brorand@^1.0.1, brorand@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" @@ -11966,11 +11966,6 @@ detect-node@^2.0.4: resolved "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw== -detect-node@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" - integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== - detect-port-alt@^1.1.6: version "1.1.6" resolved "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz#24707deabe932d4a3cf621302027c2b266568275" @@ -16823,11 +16818,6 @@ js-levenshtein@^1.1.6: resolved "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d" integrity sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g== -js-sha3@0.8.0: - version "0.8.0" - resolved "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" - integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== - "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -18248,14 +18238,6 @@ marked@^4.0.14: resolved "https://registry.npmjs.org/marked/-/marked-4.0.18.tgz#cd0ac54b2e5610cfb90e8fd46ccaa8292c9ed569" integrity sha512-wbLDJ7Zh0sqA0Vdg6aqlbT+yPxqLblpAZh1mK2+AO2twQkPywvvqQNfEPVwSSRjZ7dZcdeVBIAgiO7MMp3Dszw== -match-sorter@^6.0.2: - version "6.3.1" - resolved "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.1.tgz#98cc37fda756093424ddf3cbc62bfe9c75b92bda" - integrity sha512-mxybbo3pPNuA+ZuCUhm5bwNkXrJTbsk5VWbR5wiwz/GC6LIiegBGn2w3O08UG/jdbYLinw51fSQ5xNU1U3MgBw== - dependencies: - "@babel/runtime" "^7.12.5" - remove-accents "0.4.2" - matcher@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz#bd9060f4c5b70aa8041ccc6f80368760994f30ca" @@ -18843,11 +18825,6 @@ micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: braces "^3.0.2" picomatch "^2.3.1" -microseconds@0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/microseconds/-/microseconds-0.2.0.tgz#233b25f50c62a65d861f978a4a4f8ec18797dc39" - integrity sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA== - miller-rabin@^4.0.0: version "4.0.1" resolved "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" @@ -19328,13 +19305,6 @@ nano-css@^5.3.1: stacktrace-js "^2.0.2" stylis "^4.0.6" -nano-time@1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/nano-time/-/nano-time-1.0.0.tgz#b0554f69ad89e22d0907f7a12b0993a5d96137ef" - integrity sha1-sFVPaa2J4i0JB/ehKwmTpdlhN+8= - dependencies: - big-integer "^1.6.16" - nanoclone@^0.2.1: version "0.2.1" resolved "https://registry.npmjs.org/nanoclone/-/nanoclone-0.2.1.tgz#dd4090f8f1a110d26bb32c49ed2f5b9235209ed4" @@ -19938,11 +19908,6 @@ object.values@^1.1.5: define-properties "^1.1.3" es-abstract "^1.19.1" -oblivious-set@1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/oblivious-set/-/oblivious-set-1.0.0.tgz#c8316f2c2fb6ff7b11b6158db3234c49f733c566" - integrity sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw== - obuf@^1.0.0, obuf@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" @@ -22108,15 +22073,6 @@ react-markdown@^8.0.0: unist-util-visit "^4.0.0" vfile "^5.0.0" -react-query@^3.34.16: - version "3.39.2" - resolved "https://registry.npmjs.org/react-query/-/react-query-3.39.2.tgz#9224140f0296f01e9664b78ed6e4f69a0cc9216f" - integrity sha512-F6hYDKyNgDQfQOuR1Rsp3VRzJnWHx6aRnnIZHMNGGgbL3SBgpZTDg8MQwmxOgpCAoqZJA+JSNCydF1xGJqKOCA== - dependencies: - "@babel/runtime" "^7.5.5" - broadcast-channel "^3.4.1" - match-sorter "^6.0.2" - react-redux@^7.1.1, react-redux@^7.2.4: version "7.2.5" resolved "https://registry.npmjs.org/react-redux/-/react-redux-7.2.5.tgz#213c1b05aa1187d9c940ddfc0b29450957f6a3b8" @@ -22773,11 +22729,6 @@ remedial@^1.0.7: resolved "https://registry.npmjs.org/remedial/-/remedial-1.0.8.tgz#a5e4fd52a0e4956adbaf62da63a5a46a78c578a0" integrity sha512-/62tYiOe6DzS5BqVsNpH/nkGlX45C/Sp6V+NtiN6JQNS1Viay7cWkazmRkrQrdFj2eshDe96SIQNIoMxqhzBOg== -remove-accents@0.4.2: - version "0.4.2" - resolved "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz#0a43d3aaae1e80db919e07ae254b285d9e1c7bb5" - integrity sha1-CkPTqq4egNuRngeuJUsoXZ4ce7U= - remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" @@ -25705,14 +25656,6 @@ unixify@^1.0.0: dependencies: normalize-path "^2.1.1" -unload@2.2.0: - version "2.2.0" - resolved "https://registry.npmjs.org/unload/-/unload-2.2.0.tgz#ccc88fdcad345faa06a92039ec0f80b488880ef7" - integrity sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA== - dependencies: - "@babel/runtime" "^7.6.2" - detect-node "^2.0.4" - unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" @@ -25824,6 +25767,11 @@ use-resize-observer@^8.0.0: dependencies: "@juggle/resize-observer" "^3.3.1" +use-sync-external-store@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" + integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== + use@^3.1.0: version "3.1.1" resolved "https://registry.npmjs.org/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" From d7ef5b056fafd1379f9f4abc9c3481b7b492f668 Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 17 Aug 2022 15:55:27 +0200 Subject: [PATCH 008/198] chore: transition on the height Signed-off-by: blam --- microsite/static/css/custom.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microsite/static/css/custom.css b/microsite/static/css/custom.css index 71adbc2a4e..4b52a72e42 100644 --- a/microsite/static/css/custom.css +++ b/microsite/static/css/custom.css @@ -1233,7 +1233,7 @@ h3.collapsible span.arrow { right: 0; position: fixed; color: rgb(0, 0, 0); - transition: transform 250ms ease-in-out; + transition: transform 250ms ease-in-out, height 250ms ease-in-out; display: flex; align-items: center; transform: translateY(-50%) translateX(500px); From 3da562c01a38e149df5bff416830a638c2f29bb2 Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 17 Aug 2022 16:23:59 +0200 Subject: [PATCH 009/198] chore: fix: Signed-off-by: blam --- docs/overview/roadmap.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/overview/roadmap.md b/docs/overview/roadmap.md index a84fd6c83c..7212fff1e2 100644 --- a/docs/overview/roadmap.md +++ b/docs/overview/roadmap.md @@ -111,5 +111,5 @@ guidelines to get started. If you have specific questions about the roadmap, please create an [issue](https://github.com/backstage/backstage/issues/new/choose), ping us on -[Discord](https://discord.gg/qxsEfa8Vq8), or [book +[Discord](https://discord.gg/qxsEfa8Vq8), or [book time](https://info.backstage.spotify.com/office-hours) with the Spotify team. From 4d5dc47fb790eb0ab38fae07bfac99e7c8d575e6 Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 17 Aug 2022 16:24:40 +0200 Subject: [PATCH 010/198] chore: rework Signed-off-by: blam --- docs/overview/roadmap.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/overview/roadmap.md b/docs/overview/roadmap.md index 7212fff1e2..2ac211bf97 100644 --- a/docs/overview/roadmap.md +++ b/docs/overview/roadmap.md @@ -111,5 +111,4 @@ guidelines to get started. If you have specific questions about the roadmap, please create an [issue](https://github.com/backstage/backstage/issues/new/choose), ping us on -[Discord](https://discord.gg/qxsEfa8Vq8), or [book -time](https://info.backstage.spotify.com/office-hours) with the Spotify team. +[Discord](https://discord.gg/qxsEfa8Vq8), or [book time](https://info.backstage.spotify.com/office-hours) with the Spotify team. From 75e9a7652b40cb2b580a378aa35464d387b03945 Mon Sep 17 00:00:00 2001 From: Tomasz Szuba Date: Wed, 17 Aug 2022 18:02:06 +0200 Subject: [PATCH 011/198] [gcalendar] fix tests Signed-off-by: Tomasz Szuba --- .../src/components/CalendarCard/CalendarCard.tsx | 7 +++---- .../components/CalendarCard/CalendarSelect.tsx | 1 - .../CalendarCard/HomePageCalendar.test.tsx | 16 +++++++++------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/plugins/gcalendar/src/components/CalendarCard/CalendarCard.tsx b/plugins/gcalendar/src/components/CalendarCard/CalendarCard.tsx index b698c23ea1..a5575bc190 100644 --- a/plugins/gcalendar/src/components/CalendarCard/CalendarCard.tsx +++ b/plugins/gcalendar/src/components/CalendarCard/CalendarCard.tsx @@ -15,7 +15,7 @@ */ import { sortBy } from 'lodash'; import { DateTime } from 'luxon'; -import React, { useEffect, useState } from 'react'; +import React, { useState } from 'react'; import { InfoCard, Progress } from '@backstage/core-components'; import { useAnalytics } from '@backstage/core-plugin-api'; @@ -35,6 +35,7 @@ import { CalendarEvent } from './CalendarEvent'; import { CalendarSelect } from './CalendarSelect'; import { SignInContent } from './SignInContent'; import { getStartDate } from './util'; +import useAsync from 'react-use/lib/useAsync'; export const CalendarCard = () => { const [date, setDate] = useState(DateTime.now()); @@ -47,9 +48,7 @@ export const CalendarCard = () => { const { isSignedIn, isInitialized, signIn } = useSignIn(); - useEffect(() => { - signIn(true); - }, [signIn]); + useAsync(async () => signIn(true), [signIn]); const { isLoading: isCalendarLoading, data: calendars = [] } = useCalendarsQuery({ diff --git a/plugins/gcalendar/src/components/CalendarCard/CalendarSelect.tsx b/plugins/gcalendar/src/components/CalendarCard/CalendarSelect.tsx index a1e037a2a3..cd48d9ad3e 100644 --- a/plugins/gcalendar/src/components/CalendarCard/CalendarSelect.tsx +++ b/plugins/gcalendar/src/components/CalendarCard/CalendarSelect.tsx @@ -58,7 +58,6 @@ export const CalendarSelect = ({ calendars, }: CalendarSelectProps) => { const classes = useStyles(); - return (