Merge remote-tracking branch 'origin/master' into orkohunter/techdocs-publish-to-cloud-storage

This commit is contained in:
Himanshu Mishra
2020-12-03 22:53:45 +01:00
200 changed files with 4736 additions and 974 deletions
+12
View File
@@ -1,5 +1,17 @@
# @backstage/plugin-api-docs
## 0.3.1
### Patch Changes
- 7eb8bfe4a: Update swagger-ui-react to 3.37.2
- Updated dependencies [08835a61d]
- Updated dependencies [a9fd599f7]
- Updated dependencies [bcc211a08]
- Updated dependencies [ebf37bbae]
- @backstage/catalog-model@0.4.0
- @backstage/plugin-catalog@0.2.5
## 0.3.0
### Minor Changes
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-api-docs",
"version": "0.3.0",
"version": "0.3.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -20,9 +20,9 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/catalog-model": "^0.3.1",
"@backstage/catalog-model": "^0.4.0",
"@backstage/core": "^0.3.2",
"@backstage/plugin-catalog": "^0.2.4",
"@backstage/plugin-catalog": "^0.2.5",
"@backstage/theme": "^0.2.1",
"@kyma-project/asyncapi-react": "^0.14.2",
"@material-icons/font": "^1.0.2",
@@ -40,9 +40,9 @@
"swagger-ui-react": "^3.37.2"
},
"devDependencies": {
"@backstage/cli": "^0.3.2",
"@backstage/dev-utils": "^0.1.4",
"@backstage/test-utils": "^0.1.3",
"@backstage/cli": "^0.4.0",
"@backstage/dev-utils": "^0.1.5",
"@backstage/test-utils": "^0.1.4",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+10
View File
@@ -1,5 +1,15 @@
# @backstage/plugin-app-backend
## 0.3.2
### Patch Changes
- Updated dependencies [4e7091759]
- Updated dependencies [b4488ddb0]
- Updated dependencies [612368274]
- @backstage/config-loader@0.4.0
- @backstage/backend-common@0.3.3
## 0.3.1
### Patch Changes
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-app-backend",
"version": "0.3.1",
"version": "0.3.2",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -20,8 +20,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/backend-common": "^0.3.2",
"@backstage/config-loader": "^0.3.0",
"@backstage/backend-common": "^0.3.3",
"@backstage/config-loader": "^0.4.0",
"@backstage/config": "^0.1.1",
"@types/express": "^4.17.6",
"express": "^4.17.1",
@@ -31,7 +31,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.3.2",
"@backstage/cli": "^0.4.0",
"@types/supertest": "^2.0.8",
"msw": "^0.20.5",
"supertest": "^4.0.2"
+12
View File
@@ -1,5 +1,17 @@
# @backstage/plugin-auth-backend
## 0.2.5
### Patch Changes
- Updated dependencies [612368274]
- Updated dependencies [08835a61d]
- Updated dependencies [a9fd599f7]
- Updated dependencies [bcc211a08]
- @backstage/backend-common@0.3.3
- @backstage/catalog-model@0.4.0
- @backstage/catalog-client@0.3.2
## 0.2.4
### Patch Changes
+7 -7
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-auth-backend",
"version": "0.2.4",
"version": "0.2.5",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -20,9 +20,9 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/backend-common": "^0.3.2",
"@backstage/catalog-client": "^0.3.1",
"@backstage/catalog-model": "^0.3.1",
"@backstage/backend-common": "^0.3.3",
"@backstage/catalog-client": "^0.3.2",
"@backstage/catalog-model": "^0.4.0",
"@backstage/config": "^0.1.1",
"@types/express": "^4.17.6",
"compression": "^1.7.4",
@@ -36,7 +36,7 @@
"got": "^11.5.2",
"helmet": "^4.0.0",
"jose": "^1.27.1",
"jwt-decode": "2.2.0",
"jwt-decode": "^3.1.0",
"knex": "^0.21.6",
"moment": "^2.26.0",
"morgan": "^1.10.0",
@@ -55,11 +55,11 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.3.2",
"@backstage/cli": "^0.4.0",
"@types/body-parser": "^1.19.0",
"@types/cookie-parser": "^1.4.2",
"@types/express-session": "^1.17.2",
"@types/jwt-decode": "2.2.1",
"@types/jwt-decode": "^3.1.0",
"@types/nock": "^11.1.0",
"@types/openid-client": "^3.7.0",
"@types/passport": "^1.0.3",
+41
View File
@@ -1,5 +1,46 @@
# @backstage/plugin-catalog-backend
## 0.3.0
### Minor Changes
- a9fd599f7: Add Analyze location endpoint to catalog backend. Add catalog-import plugin and replace import-component with it. To start using Analyze location endpoint, you have add it to the `createRouter` function options in the `\backstage\packages\backend\src\plugins\catalog.ts` file:
```ts
export default async function createPlugin(env: PluginEnvironment) {
const builder = new CatalogBuilder(env);
const {
entitiesCatalog,
locationsCatalog,
higherOrderOperation,
locationAnalyzer, //<--
} = await builder.build();
return await createRouter({
entitiesCatalog,
locationsCatalog,
higherOrderOperation,
locationAnalyzer, //<--
logger: env.logger,
});
}
```
### Patch Changes
- b4488ddb0: Added a type alias for PositionError = GeolocationPositionError
- 08835a61d: Add support for relative targets and implicit types in Location entities.
- e42402b47: Gracefully handle missing codeowners.
The CodeOwnersProcessor now also takes a logger as a parameter.
- Updated dependencies [612368274]
- Updated dependencies [08835a61d]
- Updated dependencies [a9fd599f7]
- Updated dependencies [bcc211a08]
- @backstage/backend-common@0.3.3
- @backstage/catalog-model@0.4.0
## 0.2.3
### Patch Changes
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-catalog-backend",
"version": "0.2.3",
"version": "0.3.0",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,8 +21,8 @@
},
"dependencies": {
"@azure/msal-node": "^1.0.0-alpha.8",
"@backstage/backend-common": "^0.3.2",
"@backstage/catalog-model": "^0.3.1",
"@backstage/backend-common": "^0.3.3",
"@backstage/catalog-model": "^0.4.0",
"@backstage/config": "^0.1.1",
"@octokit/graphql": "^4.5.6",
"@types/express": "^4.17.6",
@@ -48,8 +48,8 @@
"yup": "^0.29.3"
},
"devDependencies": {
"@backstage/cli": "^0.3.2",
"@backstage/test-utils": "^0.1.3",
"@backstage/cli": "^0.4.0",
"@backstage/test-utils": "^0.1.4",
"@types/core-js": "^2.5.4",
"@types/git-url-parse": "^9.0.0",
"@types/lodash": "^4.14.151",
@@ -0,0 +1,44 @@
/*
* Copyright 2020 Spotify AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { LocationSpec } from '@backstage/catalog-model';
import { toAbsoluteUrl } from './LocationEntityProcessor';
import path from 'path';
describe('LocationEntityProcessor', () => {
describe('toAbsoluteUrl', () => {
it('handles files', () => {
const base: LocationSpec = {
type: 'file',
target: `some${path.sep}path${path.sep}catalog-info.yaml`,
};
expect(toAbsoluteUrl(base, `.${path.sep}c`)).toBe(
`some${path.sep}path${path.sep}c`,
);
expect(toAbsoluteUrl(base, `${path.sep}c`)).toBe(`${path.sep}c`);
});
it('handles urls', () => {
const base: LocationSpec = {
type: 'url',
target: 'http://a.com/b/catalog-info.yaml',
};
expect(toAbsoluteUrl(base, './c/d')).toBe('http://a.com/b/c/d');
expect(toAbsoluteUrl(base, 'c/d')).toBe('http://a.com/b/c/d');
expect(toAbsoluteUrl(base, 'http://b.com/z')).toBe('http://b.com/z');
});
});
});
@@ -17,27 +17,52 @@
import { Entity, LocationEntity, LocationSpec } from '@backstage/catalog-model';
import * as result from './results';
import { CatalogProcessor, CatalogProcessorEmit } from './types';
import path from 'path';
export function toAbsoluteUrl(base: LocationSpec, target: string): string {
try {
if (base.type === 'file') {
if (target.startsWith('.')) {
return path.join(path.dirname(base.target), target);
}
return target;
}
return new URL(target, base.target).toString();
} catch (e) {
return target;
}
}
export class LocationRefProcessor implements CatalogProcessor {
async postProcessEntity(
entity: Entity,
_location: LocationSpec,
location: LocationSpec,
emit: CatalogProcessorEmit,
): Promise<Entity> {
if (entity.kind === 'Location') {
const location = entity as LocationEntity;
if (location.spec.target) {
const locationEntity = entity as LocationEntity;
const type = locationEntity.spec.type || location.type;
if (type === 'file' && location.target.endsWith(path.sep)) {
emit(
result.location(
{ type: location.spec.type, target: location.spec.target },
false,
result.inputError(
location,
`LocationRefProcessor cannot handle ${type} type location with target ${location.target} that ends with a path separator`,
),
);
}
if (location.spec.targets) {
for (const target of location.spec.targets) {
emit(result.location({ type: location.spec.type, target }, false));
}
const targets = new Array<string>();
if (locationEntity.spec.target) {
targets.push(locationEntity.spec.target);
}
if (locationEntity.spec.targets) {
targets.push(...locationEntity.spec.targets);
}
for (const maybeRelativeTarget of targets) {
const target = toAbsoluteUrl(location, maybeRelativeTarget);
emit(result.location({ type, target }, false));
}
}
@@ -76,7 +76,7 @@ describe('buildMemberOf', () => {
const u: UserEntity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'User',
metadata: { name },
metadata: { name: 'n' },
spec: { profile: {}, memberOf: ['c'] },
};
+11
View File
@@ -1,5 +1,16 @@
# @backstage/plugin-catalog-graphql
## 0.2.3
### Patch Changes
- Updated dependencies [612368274]
- Updated dependencies [08835a61d]
- Updated dependencies [a9fd599f7]
- Updated dependencies [bcc211a08]
- @backstage/backend-common@0.3.3
- @backstage/catalog-model@0.4.0
## 0.2.2
### Patch Changes
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-catalog-graphql",
"version": "0.2.2",
"version": "0.2.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -20,8 +20,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/backend-common": "^0.3.1",
"@backstage/catalog-model": "^0.3.0",
"@backstage/backend-common": "^0.3.3",
"@backstage/catalog-model": "^0.4.0",
"@backstage/config": "^0.1.1",
"@graphql-modules/core": "^0.7.17",
"apollo-server": "^2.16.1",
@@ -32,8 +32,8 @@
"winston": "^3.2.1"
},
"devDependencies": {
"@backstage/cli": "^0.3.1",
"@backstage/test-utils": "^0.1.3",
"@backstage/cli": "^0.4.0",
"@backstage/test-utils": "^0.1.4",
"@graphql-codegen/cli": "^1.17.7",
"@graphql-codegen/typescript": "^1.17.7",
"@graphql-codegen/typescript-resolvers": "^1.17.7",
+39
View File
@@ -0,0 +1,39 @@
# @backstage/plugin-catalog-import
## 0.3.0
### Minor Changes
- a9fd599f7: Add Analyze location endpoint to catalog backend. Add catalog-import plugin and replace import-component with it. To start using Analyze location endpoint, you have add it to the `createRouter` function options in the `\backstage\packages\backend\src\plugins\catalog.ts` file:
```ts
export default async function createPlugin(env: PluginEnvironment) {
const builder = new CatalogBuilder(env);
const {
entitiesCatalog,
locationsCatalog,
higherOrderOperation,
locationAnalyzer, //<--
} = await builder.build();
return await createRouter({
entitiesCatalog,
locationsCatalog,
higherOrderOperation,
locationAnalyzer, //<--
logger: env.logger,
});
}
```
### Patch Changes
- Updated dependencies [b4488ddb0]
- Updated dependencies [08835a61d]
- Updated dependencies [a9fd599f7]
- Updated dependencies [e42402b47]
- Updated dependencies [bcc211a08]
- Updated dependencies [ebf37bbae]
- @backstage/plugin-catalog-backend@0.3.0
- @backstage/catalog-model@0.4.0
- @backstage/plugin-catalog@0.2.5
+7 -7
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-catalog-import",
"version": "0.2.0",
"version": "0.3.0",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,10 +21,10 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/catalog-model": "^0.3.0",
"@backstage/catalog-model": "^0.4.0",
"@backstage/core": "^0.3.2",
"@backstage/plugin-catalog": "^0.2.0",
"@backstage/plugin-catalog-backend": "^0.2.2",
"@backstage/plugin-catalog": "^0.2.5",
"@backstage/plugin-catalog-backend": "^0.3.0",
"@backstage/theme": "^0.2.1",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -40,9 +40,9 @@
"yaml": "^1.10.0"
},
"devDependencies": {
"@backstage/cli": "^0.3.2",
"@backstage/dev-utils": "^0.1.4",
"@backstage/test-utils": "^0.1.3",
"@backstage/cli": "^0.4.0",
"@backstage/dev-utils": "^0.1.5",
"@backstage/test-utils": "^0.1.4",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+14
View File
@@ -1,5 +1,19 @@
# @backstage/plugin-catalog
## 0.2.5
### Patch Changes
- ebf37bbae: Use the OWNED_BY relation and compare it to the users MEMBER_OF relation. The user entity is searched by name, based on the userId of the identity.
- Updated dependencies [08835a61d]
- Updated dependencies [a9fd599f7]
- Updated dependencies [bcc211a08]
- Updated dependencies [da2ad65cb]
- @backstage/catalog-model@0.4.0
- @backstage/plugin-scaffolder@0.3.2
- @backstage/plugin-techdocs@0.3.1
- @backstage/catalog-client@0.3.2
## 0.2.4
### Patch Changes
+8 -8
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-catalog",
"version": "0.2.4",
"version": "0.2.5",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,11 +21,11 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/catalog-client": "^0.3.1",
"@backstage/catalog-model": "^0.3.1",
"@backstage/catalog-client": "^0.3.2",
"@backstage/catalog-model": "^0.4.0",
"@backstage/core": "^0.3.2",
"@backstage/plugin-scaffolder": "^0.3.1",
"@backstage/plugin-techdocs": "^0.3.0",
"@backstage/plugin-scaffolder": "^0.3.2",
"@backstage/plugin-techdocs": "^0.3.1",
"@backstage/theme": "^0.2.1",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -43,9 +43,9 @@
"swr": "^0.3.0"
},
"devDependencies": {
"@backstage/cli": "^0.3.2",
"@backstage/dev-utils": "^0.1.4",
"@backstage/test-utils": "^0.1.3",
"@backstage/cli": "^0.4.0",
"@backstage/dev-utils": "^0.1.5",
"@backstage/test-utils": "^0.1.4",
"@microsoft/microsoft-graph-types": "^1.25.0",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+5 -4
View File
@@ -21,20 +21,21 @@ import { identityApiRef, useApi } from '@backstage/core';
import { catalogApiRef } from '../plugin';
/**
* Get the group memberships of the logged-in user.
* Get the catalog User entity (if any) that matches the logged-in user.
*/
export function useOwnUser(): AsyncState<UserEntity> {
export function useOwnUser(): AsyncState<UserEntity | undefined> {
const catalogApi = useApi(catalogApiRef);
const identityApi = useApi(identityApiRef);
// TODO: get the full entity (or at least the full entity name) from the identityApi
// TODO: get the full entity (or at least the full entity name) from the
// identityApi
return useAsync(
() =>
catalogApi.getEntityByName({
kind: 'User',
namespace: 'default',
name: identityApi.getUserId(),
}) as Promise<UserEntity>,
}) as Promise<UserEntity | undefined>,
[catalogApi, identityApi],
);
}
+11
View File
@@ -1,5 +1,16 @@
# @backstage/plugin-circleci
## 0.2.3
### Patch Changes
- Updated dependencies [08835a61d]
- Updated dependencies [a9fd599f7]
- Updated dependencies [bcc211a08]
- Updated dependencies [ebf37bbae]
- @backstage/catalog-model@0.4.0
- @backstage/plugin-catalog@0.2.5
## 0.2.2
### Patch Changes
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-circleci",
"version": "0.2.2",
"version": "0.2.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,9 +21,9 @@
"postpack": "backstage-cli postpack"
},
"dependencies": {
"@backstage/catalog-model": "^0.3.0",
"@backstage/catalog-model": "^0.4.0",
"@backstage/core": "^0.3.2",
"@backstage/plugin-catalog": "^0.2.3",
"@backstage/plugin-catalog": "^0.2.5",
"@backstage/theme": "^0.2.1",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -40,9 +40,9 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.3.2",
"@backstage/dev-utils": "^0.1.4",
"@backstage/test-utils": "^0.1.3",
"@backstage/cli": "^0.4.0",
"@backstage/dev-utils": "^0.1.5",
"@backstage/test-utils": "^0.1.4",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+95
View File
@@ -0,0 +1,95 @@
/*
* Copyright 2020 Spotify AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
CircleCIOptions,
getMe,
getBuildSummaries,
getFullBuild,
postBuildActions,
BuildAction,
BuildWithSteps,
BuildStepAction,
BuildSummary,
GitType,
} from 'circleci-api';
import { createApiRef, DiscoveryApi } from '@backstage/core';
export { GitType };
export type { BuildWithSteps, BuildStepAction, BuildSummary };
export const circleCIApiRef = createApiRef<CircleCIApi>({
id: 'plugin.circleci.service',
description: 'Used by the CircleCI plugin to make requests',
});
const DEFAULT_PROXY_PATH = '/circleci/api';
type Options = {
discoveryApi: DiscoveryApi;
/**
* Path to use for requests via the proxy, defaults to /circleci/api
*/
proxyPath?: string;
};
export class CircleCIApi {
private readonly discoveryApi: DiscoveryApi;
private readonly proxyPath: string;
constructor(options: Options) {
this.discoveryApi = options.discoveryApi;
this.proxyPath = options.proxyPath ?? DEFAULT_PROXY_PATH;
}
async retry(buildNumber: number, options: Partial<CircleCIOptions>) {
return postBuildActions('', buildNumber, BuildAction.RETRY, {
circleHost: await this.getApiUrl(),
...options.vcs,
});
}
async getBuilds(
{ limit = 10, offset = 0 }: { limit: number; offset: number },
options: Partial<CircleCIOptions>,
) {
return getBuildSummaries('', {
options: {
limit,
offset,
},
vcs: {},
circleHost: await this.getApiUrl(),
...options,
});
}
async getUser(options: Partial<CircleCIOptions>) {
return getMe('', { circleHost: await this.getApiUrl(), ...options });
}
async getBuild(buildNumber: number, options: Partial<CircleCIOptions>) {
return getFullBuild('', buildNumber, {
circleHost: await this.getApiUrl(),
...options.vcs,
});
}
private async getApiUrl() {
const proxyUrl = await this.discoveryApi.getBaseUrl('proxy');
return proxyUrl + this.proxyPath;
}
}
+3 -76
View File
@@ -14,82 +14,9 @@
* limitations under the License.
*/
import {
CircleCIOptions,
getMe,
getBuildSummaries,
getFullBuild,
postBuildActions,
BuildAction,
export { CircleCIApi, circleCIApiRef, GitType } from './CircleCIApi';
export type {
BuildWithSteps,
BuildStepAction,
BuildSummary,
GitType,
} from 'circleci-api';
import { createApiRef, DiscoveryApi } from '@backstage/core';
export { GitType };
export type { BuildWithSteps, BuildStepAction, BuildSummary };
export const circleCIApiRef = createApiRef<CircleCIApi>({
id: 'plugin.circleci.service',
description: 'Used by the CircleCI plugin to make requests',
});
const DEFAULT_PROXY_PATH = '/circleci/api';
type Options = {
discoveryApi: DiscoveryApi;
/**
* Path to use for requests via the proxy, defaults to /circleci/api
*/
proxyPath?: string;
};
export class CircleCIApi {
private readonly discoveryApi: DiscoveryApi;
private readonly proxyPath: string;
constructor(options: Options) {
this.discoveryApi = options.discoveryApi;
this.proxyPath = options.proxyPath ?? DEFAULT_PROXY_PATH;
}
async retry(buildNumber: number, options: Partial<CircleCIOptions>) {
return postBuildActions('', buildNumber, BuildAction.RETRY, {
circleHost: await this.getApiUrl(),
...options.vcs,
});
}
async getBuilds(
{ limit = 10, offset = 0 }: { limit: number; offset: number },
options: Partial<CircleCIOptions>,
) {
return getBuildSummaries('', {
options: {
limit,
offset,
},
vcs: {},
circleHost: await this.getApiUrl(),
...options,
});
}
async getUser(options: Partial<CircleCIOptions>) {
return getMe('', { circleHost: await this.getApiUrl(), ...options });
}
async getBuild(buildNumber: number, options: Partial<CircleCIOptions>) {
return getFullBuild('', buildNumber, {
circleHost: await this.getApiUrl(),
...options.vcs,
});
}
private async getApiUrl() {
const proxyUrl = await this.discoveryApi.getBaseUrl('proxy');
return proxyUrl + this.proxyPath;
}
}
} from './CircleCIApi';
@@ -16,7 +16,7 @@
import { errorApiRef, useApi } from '@backstage/core';
import { useCallback, useMemo } from 'react';
import { useAsyncRetry } from 'react-use';
import { circleCIApiRef } from '../api/index';
import { circleCIApiRef } from '../api';
import { useAsyncPolling } from './useAsyncPolling';
import { useProjectSlugFromEntity, mapVcsType } from './useBuilds';
+1 -1
View File
@@ -18,7 +18,7 @@ import { errorApiRef, useApi } from '@backstage/core';
import { BuildSummary, GitType } from 'circleci-api';
import { useCallback, useEffect, useState } from 'react';
import { useAsyncRetry } from 'react-use';
import { circleCIApiRef } from '../api/index';
import { circleCIApiRef } from '../api';
import type { CITableBuildInfo } from '../components/BuildsPage/lib/CITable';
import { useEntity } from '@backstage/plugin-catalog';
import { CIRCLECI_ANNOTATION } from '../constants';
+11
View File
@@ -1,5 +1,16 @@
# @backstage/plugin-cloudbuild
## 0.2.3
### Patch Changes
- Updated dependencies [08835a61d]
- Updated dependencies [a9fd599f7]
- Updated dependencies [bcc211a08]
- Updated dependencies [ebf37bbae]
- @backstage/catalog-model@0.4.0
- @backstage/plugin-catalog@0.2.5
## 0.2.2
### Patch Changes
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-cloudbuild",
"version": "0.2.2",
"version": "0.2.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -20,9 +20,9 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/catalog-model": "^0.3.0",
"@backstage/catalog-model": "^0.4.0",
"@backstage/core": "^0.3.2",
"@backstage/plugin-catalog": "^0.2.3",
"@backstage/plugin-catalog": "^0.2.5",
"@backstage/theme": "^0.2.1",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -39,9 +39,9 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.3.2",
"@backstage/dev-utils": "^0.1.4",
"@backstage/test-utils": "^0.1.3",
"@backstage/cli": "^0.4.0",
"@backstage/dev-utils": "^0.1.5",
"@backstage/test-utils": "^0.1.4",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+13
View File
@@ -1,5 +1,18 @@
# @backstage/plugin-cost-insights
## 0.4.2
### Patch Changes
- fe7257ff0: enable SKU breakdown for unlabeled entities
- a2cfa311a: Add breakdown view to the Cost Overview panel
- 69f38457f: Add support for non-SKU breakdowns for entities in the product panels.
- bec334b33: disable support button
- b4488ddb0: Added a type alias for PositionError = GeolocationPositionError
- 00670a96e: sort product panels and navigation menu by greatest cost
update tsconfig.json to use ES2020 api
- @backstage/test-utils@0.1.4
## 0.4.1
### Patch Changes
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-cost-insights",
"version": "0.4.1",
"version": "0.4.2",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -23,7 +23,7 @@
"dependencies": {
"@backstage/config": "^0.1.1",
"@backstage/core": "^0.3.2",
"@backstage/test-utils": "^0.1.3",
"@backstage/test-utils": "^0.1.4",
"@backstage/theme": "^0.2.1",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -46,9 +46,9 @@
"yup": "^0.29.3"
},
"devDependencies": {
"@backstage/cli": "^0.3.2",
"@backstage/dev-utils": "^0.1.4",
"@backstage/test-utils": "^0.1.3",
"@backstage/cli": "^0.4.0",
"@backstage/dev-utils": "^0.1.5",
"@backstage/test-utils": "^0.1.4",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
@@ -32,7 +32,8 @@ import {
import { CostInsightsNavigation } from '../CostInsightsNavigation';
import { CostOverviewCard } from '../CostOverviewCard';
import { ProductInsights } from '../ProductInsights';
import { CostInsightsSupportButton } from '../CostInsightsSupportButton';
/* https://github.com/backstage/backstage/issues/2574 */
// import { CostInsightsSupportButton } from '../CostInsightsSupportButton';
import {
useConfig,
useCurrency,
@@ -164,7 +165,7 @@ export const CostInsightsPage = () => {
<CostInsightsLayout groups={groups}>
<Box textAlign="right">
<CopyUrlToClipboard />
<CostInsightsSupportButton />
{/* <CostInsightsSupportButton /> */}
</Box>
<Container maxWidth="lg">
<CostInsightsHeaderNoGroups />
@@ -239,7 +240,7 @@ export const CostInsightsPage = () => {
mb={2}
>
<CopyUrlToClipboard />
<CostInsightsSupportButton />
{/* <CostInsightsSupportButton /> */}
</Box>
<Container maxWidth="lg" disableGutters>
<Grid container direction="column">
@@ -29,7 +29,7 @@ function createRenderer(col: keyof RowData, classes: Record<string, string>) {
const row = rowData as RowData;
const rowStyles = classnames(classes.row, {
[classes.rowTotal]: row.id === 'total',
[classes.colFirst]: col === 'sku',
[classes.colFirst]: col === 'label',
[classes.colLast]: col === 'ratio',
});
@@ -50,7 +50,7 @@ function createRenderer(col: keyof RowData, classes: Record<string, string>) {
/>
);
default:
return <Typography className={rowStyles}>{row.sku}</Typography>;
return <Typography className={rowStyles}>{row.label}</Typography>;
}
};
}
@@ -63,7 +63,7 @@ function createSorter(field?: keyof Omit<RowData, 'id'>) {
const b = data2 as RowData;
if (a.id === 'total') return 1;
if (b.id === 'total') return 1;
if (field === 'sku') return a.sku.localeCompare(b.sku);
if (field === 'label') return a.label.localeCompare(b.label);
return field
? a[field] - b[field]
@@ -80,7 +80,7 @@ const defaultEntity: Entity = {
type RowData = {
id: string;
sku: string;
label: string;
previous: number;
current: number;
ratio: number;
@@ -93,6 +93,7 @@ type ProductEntityDialogOptions = Partial<
type ProductEntityDialogProps = {
open: boolean;
entity?: Entity;
entitiesLabel: string;
options?: ProductEntityDialogOptions;
onClose: () => void;
};
@@ -100,6 +101,7 @@ type ProductEntityDialogProps = {
export const ProductEntityDialog = ({
open,
entity = defaultEntity,
entitiesLabel,
options = {},
onClose,
}: ProductEntityDialogProps) => {
@@ -118,10 +120,12 @@ export const ProductEntityDialog = ({
const columns: TableColumn[] = [
{
field: 'sku',
title: <Typography className={firstColClasses}>SKU</Typography>,
render: createRenderer('sku', classes),
customSort: createSorter('sku'),
field: 'label',
title: (
<Typography className={firstColClasses}>{entitiesLabel}</Typography>
),
render: createRenderer('label', classes),
customSort: createSorter('label'),
width: '33.33%',
},
{
@@ -154,14 +158,14 @@ export const ProductEntityDialog = ({
const rowData: RowData[] = entity.entities
.map(e => ({
id: e.id || 'Unknown',
sku: e.id || 'Unknown',
label: e.id || 'Unknown',
previous: e.aggregation[0],
current: e.aggregation[1],
ratio: e.change.ratio,
}))
.concat({
id: 'total',
sku: 'Total',
label: 'Total',
previous: entity.aggregation[0],
current: entity.aggregation[1],
ratio: entity.change.ratio,
@@ -176,7 +180,7 @@ export const ProductEntityDialog = ({
<Table
columns={columns}
data={rowData}
title={entity.id || 'Unknown'}
title={entity.id || 'Unlabeled'}
subtitle="Resource breakdown"
options={{
paging: false,
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import React, { useEffect, useState } from 'react';
import React, { useMemo, useState } from 'react';
import {
ContentRenderer,
TooltipProps as RechartsTooltipProps,
@@ -33,14 +33,15 @@ import {
BarChartLegendOptions,
} from '../BarChart';
import { pluralOf } from '../../utils/grammar';
import { findAlways, notEmpty } from '../../utils/assert';
import { findAlways, notEmpty, isUndefined } from '../../utils/assert';
import { formatPeriod, formatPercent } from '../../utils/formatters';
import {
titleOf,
tooltipItemOf,
resourceOf,
isInvalid,
isActiveLabel,
isLabeled,
isUnlabeled,
} from '../../utils/graphs';
import {
useProductInsightsChartStyles as useStyles,
@@ -61,10 +62,14 @@ export const ProductInsightsChart = ({
}: ProductInsightsChartProps) => {
const classes = useStyles();
const layoutClasses = useLayoutStyles();
const [isOpen, setOpen] = useState(false);
const [isClickable, setClickable] = useState(true);
const [selectLabel, setSelected] = useState<Maybe<string>>(null);
const [activeLabel, setActive] = useState<Maybe<string>>(null);
const [activeLabel, setActive] = useState<Maybe<string>>();
const [selectLabel, setSelected] = useState<Maybe<string>>();
const isSelected = useMemo(() => !isUndefined(selectLabel), [selectLabel]);
const isClickable = useMemo(() => {
const breakdownEntities =
entity.entities.find(e => e.id === activeLabel)?.entities ?? [];
return breakdownEntities.length > 0;
}, [entity, activeLabel]);
const legendTitle = `Cost ${entity.change.ratio <= 0 ? 'Savings' : 'Growth'}`;
const costStart = entity.aggregation[0];
@@ -76,52 +81,25 @@ export const ProductInsightsChart = ({
currentName: formatPeriod(duration, billingDate, true),
};
useEffect(() => {
function toggleModal() {
if (selectLabel) {
setOpen(true);
} else {
setOpen(false);
}
}
toggleModal();
}, [selectLabel]);
useEffect(() => {
// disable click if an entity is unlabeled or if it does not have any skus
function toggleClickableEntity() {
if (activeLabel) {
const hasSkus = entity.entities.find(e => e.id === activeLabel)
?.entities.length;
if (hasSkus) {
setClickable(true);
} else {
setClickable(false);
}
} else {
setClickable(false);
}
}
toggleClickableEntity();
}, [activeLabel, entity]);
const onMouseMove: RechartsFunction = (
data: Record<'activeLabel', string | undefined>,
) => {
if (isActiveLabel(data)) {
if (isLabeled(data)) {
setActive(data.activeLabel!);
} else {
} else if (isUnlabeled(data)) {
setActive(null);
} else {
setActive(undefined);
}
};
const onClick: RechartsFunction = (data: Record<'activeLabel', string>) => {
if (isActiveLabel(data)) {
if (isLabeled(data)) {
setSelected(data.activeLabel);
} else {
} else if (isUnlabeled(data)) {
setSelected(null);
} else {
setSelected(undefined);
}
};
@@ -144,10 +122,13 @@ export const ProductInsightsChart = ({
const activeEntity = findAlways(entity.entities, e => e.id === id);
const ratio = activeEntity.change.ratio;
const skus = activeEntity.entities;
const subtitle = `${skus.length} ${pluralOf(skus.length, 'SKU')}`;
const breakdownEntities = activeEntity.entities;
const subtitle = `${breakdownEntities.length} ${pluralOf(
breakdownEntities.length,
entity.entitiesLabel || 'SKU',
)}`;
if (skus.length) {
if (breakdownEntities.length) {
return (
<BarChartTooltip
title={title}
@@ -173,7 +154,7 @@ export const ProductInsightsChart = ({
);
}
// If an entity doesn't have any skus, there aren't any costs to break down.
// If an entity doesn't have any sub-entities, there aren't any costs to break down.
return (
<BarChartTooltip
title={title}
@@ -213,12 +194,13 @@ export const ProductInsightsChart = ({
options={options}
{...barChartProps}
/>
{selectLabel && entity.entities.length && (
{isSelected && entity.entities.length && (
<ProductEntityDialog
open={isOpen}
onClose={() => setSelected(null)}
open={isSelected}
onClose={() => setSelected(undefined)}
entity={entity.entities.find(e => e.id === selectLabel)}
options={options}
entitiesLabel={entity.entitiesLabel || 'SKU'}
/>
)}
</Box>
@@ -22,6 +22,7 @@ export interface Entity {
aggregation: [number, number];
entities: Entity[];
change: ChangeStatistic;
entitiesLabel?: string;
}
/*
+9 -1
View File
@@ -17,7 +17,15 @@
export function notEmpty<TValue>(
value: TValue | null | undefined,
): value is TValue {
return value !== null && value !== undefined;
return !isNull(value) && !isUndefined(value);
}
export function isUndefined(value: any): boolean {
return value === undefined;
}
export function isNull(value: any): boolean {
return value === null;
}
// Utility for exhaustiveness checking in switch statements
+6 -2
View File
@@ -72,8 +72,12 @@ export const isInvalid = ({ label, payload }: TooltipProps) => {
return label === undefined || !payload || !payload.length;
};
export const isActiveLabel = (
export const isLabeled = (data?: Record<'activeLabel', string | undefined>) => {
return data?.activeLabel && data?.activeLabel !== '';
};
export const isUnlabeled = (
data?: Record<'activeLabel', string | undefined>,
) => {
return data?.activeLabel && data.activeLabel !== '';
return data?.activeLabel === '';
};
+109 -2
View File
@@ -563,7 +563,26 @@ export const SampleCloudDataflowInsights: Entity = {
ratio: 0.2,
amount: 2_000,
},
entities: [],
entities: [
{
id: 'Sample SKU A',
aggregation: [3_000, 4_000],
change: {
ratio: 0.333333,
amount: 1_000,
},
entities: [],
},
{
id: 'Sample SKU B',
aggregation: [7_000, 8_000],
change: {
ratio: 0.14285714,
amount: 1_000,
},
entities: [],
},
],
},
{
id: 'entity-a',
@@ -793,7 +812,7 @@ export const SampleComputeEngineInsights: Entity = {
id: 'Sample SKU A',
aggregation: [1_000, 2_000],
change: {
ratio: 0.5,
ratio: 1,
amount: 1_000,
},
entities: [],
@@ -830,6 +849,92 @@ export const SampleComputeEngineInsights: Entity = {
],
};
export const SampleEventsInsights: Entity = {
id: 'events',
aggregation: [20_000, 10_000],
change: {
ratio: -0.5,
amount: -10_000,
},
entitiesLabel: 'Product',
entities: [
{
id: 'entity-a',
aggregation: [15_000, 7_000],
change: {
ratio: -0.53333333333,
amount: -8_000,
},
entities: [
{
id: 'Sample Product A',
aggregation: [5_000, 2_000],
change: {
ratio: -0.6,
amount: -3_000,
},
entities: [],
},
{
id: 'Sample Product B',
aggregation: [7_000, 2_500],
change: {
ratio: -0.64285714285,
amount: -4_500,
},
entities: [],
},
{
id: 'Sample Product C',
aggregation: [3_000, 2_500],
change: {
ratio: -0.16666666666,
amount: -500,
},
entities: [],
},
],
},
{
id: 'entity-b',
aggregation: [5_000, 3_000],
change: {
ratio: -0.4,
amount: -2_000,
},
entities: [
{
id: 'Sample Product A',
aggregation: [2_000, 1_000],
change: {
ratio: -0.5,
amount: -1_000,
},
entities: [],
},
{
id: 'Sample Product B',
aggregation: [1_000, 1_500],
change: {
ratio: 0.5,
amount: 500,
},
entities: [],
},
{
id: 'Sample Product C',
aggregation: [2_000, 500],
change: {
ratio: -0.75,
amount: -1_500,
},
entities: [],
},
],
},
],
};
export function entityOf(product: string): Entity {
switch (product) {
case 'computeEngine':
@@ -840,6 +945,8 @@ export function entityOf(product: string): Entity {
return SampleCloudStorageInsights;
case 'bigQuery':
return SampleBigQueryInsights;
case 'events':
return SampleEventsInsights;
default:
throw new Error(
`Cannot get insights for ${product}. Make sure product matches product property in app-info.yaml`,
+38 -44
View File
@@ -222,16 +222,13 @@ export const useBarChartLabelStyles = makeStyles<BackstageTheme>(theme =>
}),
);
export const useCostInsightsStyles = makeStyles<BackstageTheme>(
(theme: BackstageTheme) =>
createStyles({
h6Subtle: {
...theme.typography.h6,
fontWeight: 'normal',
color: theme.palette.textSubtle,
},
}),
);
export const useCostInsightsStyles = makeStyles<BackstageTheme>(theme => ({
h6Subtle: {
...theme.typography.h6,
fontWeight: 'normal',
color: theme.palette.textSubtle,
},
}));
export const useCostInsightsTabsStyles = makeStyles<BackstageTheme>(
(theme: BackstageTheme) => ({
@@ -310,40 +307,37 @@ export const useCostGrowthStyles = makeStyles<BackstageTheme>(
}),
);
export const useCostGrowthLegendStyles = makeStyles<BackstageTheme>(
(theme: BackstageTheme) =>
createStyles({
h5: {
...theme.typography.h5,
fontWeight: 500,
padding: 0,
},
marker: {
display: 'inherit',
marginRight: theme.spacing(1),
},
helpIcon: {
display: 'inherit',
},
title: {
...theme.typography.overline,
fontWeight: 500,
lineHeight: 0,
marginRight: theme.spacing(1),
color: theme.palette.textSubtle,
},
tooltip: {
display: 'block',
padding: theme.spacing(1),
backgroundColor: theme.palette.navigation.background,
},
tooltipText: {
color: theme.palette.background.default,
fontSize: theme.typography.fontSize,
lineHeight: 1.5,
},
}),
);
export const useCostGrowthLegendStyles = makeStyles<BackstageTheme>(theme => ({
h5: {
...theme.typography.h5,
fontWeight: 500,
padding: 0,
},
marker: {
display: 'inherit',
marginRight: theme.spacing(1),
},
helpIcon: {
display: 'inherit',
},
title: {
...theme.typography.overline,
fontWeight: 500,
lineHeight: 0,
marginRight: theme.spacing(1),
color: theme.palette.textSubtle,
},
tooltip: {
display: 'block',
padding: theme.spacing(1),
backgroundColor: theme.palette.navigation.background,
},
tooltipText: {
color: theme.palette.background.default,
fontSize: theme.typography.fontSize,
lineHeight: 1.5,
},
}));
export const useBarChartStepperStyles = makeStyles<BackstageTheme>(
(theme: BackstageTheme) =>
+3 -3
View File
@@ -33,9 +33,9 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.3.2",
"@backstage/dev-utils": "^0.1.4",
"@backstage/test-utils": "^0.1.3",
"@backstage/cli": "^0.4.0",
"@backstage/dev-utils": "^0.1.5",
"@backstage/test-utils": "^0.1.4",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+3 -3
View File
@@ -31,9 +31,9 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.3.2",
"@backstage/dev-utils": "^0.1.4",
"@backstage/test-utils": "^0.1.3",
"@backstage/cli": "^0.4.0",
"@backstage/dev-utils": "^0.1.5",
"@backstage/test-utils": "^0.1.4",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+13
View File
@@ -1,5 +1,18 @@
# @backstage/plugin-github-actions
## 0.2.3
### Patch Changes
- Updated dependencies [b4488ddb0]
- Updated dependencies [08835a61d]
- Updated dependencies [a9fd599f7]
- Updated dependencies [bcc211a08]
- Updated dependencies [ebf37bbae]
- @backstage/core-api@0.2.4
- @backstage/catalog-model@0.4.0
- @backstage/plugin-catalog@0.2.5
## 0.2.2
### Patch Changes
+7 -7
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-github-actions",
"version": "0.2.2",
"version": "0.2.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,10 +21,10 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/catalog-model": "^0.3.0",
"@backstage/catalog-model": "^0.4.0",
"@backstage/core": "^0.3.2",
"@backstage/core-api": "^0.2.1",
"@backstage/plugin-catalog": "^0.2.3",
"@backstage/core-api": "^0.2.4",
"@backstage/plugin-catalog": "^0.2.5",
"@backstage/theme": "^0.2.1",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -40,9 +40,9 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.3.2",
"@backstage/dev-utils": "^0.1.4",
"@backstage/test-utils": "^0.1.3",
"@backstage/cli": "^0.4.0",
"@backstage/dev-utils": "^0.1.5",
"@backstage/test-utils": "^0.1.4",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+3 -3
View File
@@ -32,9 +32,9 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.3.2",
"@backstage/dev-utils": "^0.1.4",
"@backstage/test-utils": "^0.1.3",
"@backstage/cli": "^0.4.0",
"@backstage/dev-utils": "^0.1.5",
"@backstage/test-utils": "^0.1.4",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+4 -4
View File
@@ -43,13 +43,13 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.3.2",
"@backstage/dev-utils": "^0.1.4",
"@backstage/test-utils": "^0.1.3",
"@backstage/cli": "^0.4.0",
"@backstage/dev-utils": "^0.1.5",
"@backstage/test-utils": "^0.1.4",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
"@types/codemirror": "^0.0.97",
"@types/codemirror": "^0.0.100",
"@types/jest": "^26.0.7",
"@types/node": "^12.0.0",
"cross-fetch": "^3.0.6",
+3 -3
View File
@@ -19,9 +19,9 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/backend-common": "^0.3.0",
"@backstage/backend-common": "^0.3.3",
"@backstage/config": "^0.1.1",
"@backstage/plugin-catalog-graphql": "^0.2.1",
"@backstage/plugin-catalog-graphql": "^0.2.3",
"@graphql-modules/core": "^0.7.17",
"@types/express": "^4.17.6",
"apollo-server": "^2.16.1",
@@ -35,7 +35,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.3.0",
"@backstage/cli": "^0.4.0",
"@types/supertest": "^2.0.8",
"eslint-plugin-graphql": "^4.0.0",
"msw": "^0.20.5",
+11
View File
@@ -1,5 +1,16 @@
# @backstage/plugin-jenkins
## 0.3.2
### Patch Changes
- Updated dependencies [08835a61d]
- Updated dependencies [a9fd599f7]
- Updated dependencies [bcc211a08]
- Updated dependencies [ebf37bbae]
- @backstage/catalog-model@0.4.0
- @backstage/plugin-catalog@0.2.5
## 0.3.1
### Patch Changes
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-jenkins",
"version": "0.3.1",
"version": "0.3.2",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,9 +21,9 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/catalog-model": "^0.3.0",
"@backstage/catalog-model": "^0.4.0",
"@backstage/core": "^0.3.2",
"@backstage/plugin-catalog": "^0.2.3",
"@backstage/plugin-catalog": "^0.2.5",
"@backstage/theme": "^0.2.1",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -36,9 +36,9 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.3.2",
"@backstage/dev-utils": "^0.1.4",
"@backstage/test-utils": "^0.1.3",
"@backstage/cli": "^0.4.0",
"@backstage/dev-utils": "^0.1.5",
"@backstage/test-utils": "^0.1.4",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+233
View File
@@ -0,0 +1,233 @@
/*
* Copyright 2020 Spotify AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { createApiRef, DiscoveryApi } from '@backstage/core';
import { CITableBuildInfo } from '../components/BuildsPage/lib/CITable';
const jenkins = require('jenkins');
export const jenkinsApiRef = createApiRef<JenkinsApi>({
id: 'plugin.jenkins.service',
description: 'Used by the Jenkins plugin to make requests',
});
const DEFAULT_PROXY_PATH = '/jenkins/api';
type Options = {
discoveryApi: DiscoveryApi;
/**
* Path to use for requests via the proxy, defaults to /jenkins/api
*/
proxyPath?: string;
};
export class JenkinsApi {
private readonly discoveryApi: DiscoveryApi;
private readonly proxyPath: string;
constructor(options: Options) {
this.discoveryApi = options.discoveryApi;
this.proxyPath = options.proxyPath ?? DEFAULT_PROXY_PATH;
}
private async getClient() {
const proxyUrl = await this.discoveryApi.getBaseUrl('proxy');
return jenkins({ baseUrl: proxyUrl + this.proxyPath, promisify: true });
}
async retry(buildName: string) {
const client = await this.getClient();
// looks like the current SDK only supports triggering a new build
// can't see any support for replay (re-running the specific build with the same SCM info)
return await client.job.build(buildName);
}
async getLastBuild(jobName: string) {
const client = await this.getClient();
const job = await client.job.get(jobName);
const lastBuild = await client.build.get(jobName, job.lastBuild.number);
return lastBuild;
}
extractScmDetailsFromJob(jobDetails: any): any {
const scmInfo = jobDetails.actions
.filter(
(action: any) =>
action._class === 'jenkins.scm.api.metadata.ObjectMetadataAction',
)
.map((action: any) => {
return {
url: action?.objectUrl,
// https://javadoc.jenkins.io/plugin/scm-api/jenkins/scm/api/metadata/ObjectMetadataAction.html
// branch name for regular builds, pull request title on pull requests
displayName: action?.objectDisplayName,
};
})
.pop();
const author = jobDetails.actions
.filter(
(action: any) =>
action._class ===
'jenkins.scm.api.metadata.ContributorMetadataAction',
)
.map((action: any) => {
return action.contributorDisplayName;
})
.pop();
if (author) {
scmInfo.author = author;
}
return scmInfo;
}
async getJob(jobName: string) {
const client = await this.getClient();
return client.job.get({
name: jobName,
depth: 1,
});
}
async getFolder(folderName: string) {
const client = await this.getClient();
const folder = await client.job.get(folderName);
const results = [];
for (const jobSummary of folder.jobs) {
const jobDetails = await client.job.get({
name: `${folderName}/${jobSummary.name}`,
depth: 1,
});
const jobScmInfo = this.extractScmDetailsFromJob(jobDetails);
if (jobDetails.jobs) {
// skipping folders inside folders for now
} else {
for (const buildDetails of jobDetails.builds) {
const build = await client.build.get({
name: `${folderName}/${jobSummary.name}`,
number: buildDetails.number,
depth: 1,
});
const ciTable = this.mapJenkinsBuildToCITable(build, jobScmInfo);
results.push(ciTable);
}
}
}
return results;
}
private getTestReport(
jenkinsResult: any,
): {
total: number;
passed: number;
skipped: number;
failed: number;
testUrl: string;
} {
return jenkinsResult.actions
.filter(
(action: any) =>
action._class === 'hudson.tasks.junit.TestResultAction',
)
.map((action: any) => {
return {
total: action.totalCount,
passed: action.totalCount - action.failCount - action.skipCount,
skipped: action.skipCount,
failed: action.failCount,
testUrl: `${jenkinsResult.url}${action.urlName}/`,
};
})
.pop();
}
mapJenkinsBuildToCITable(
jenkinsResult: any,
jobScmInfo?: any,
): CITableBuildInfo {
const source =
jenkinsResult.actions
.filter(
(action: any) =>
action._class === 'hudson.plugins.git.util.BuildData',
)
.map((action: any) => {
const [first]: any = Object.values(action.buildsByBranchName);
const branch = first.revision.branch[0];
return {
branchName: branch.name,
commit: {
hash: branch.SHA1.substring(0, 8),
},
};
})
.pop() || {};
if (jobScmInfo) {
source.url = jobScmInfo?.url;
source.displayName = jobScmInfo?.displayName;
source.author = jobScmInfo?.author;
}
const path = new URL(jenkinsResult.url).pathname;
return {
id: path,
buildNumber: jenkinsResult.number,
buildUrl: jenkinsResult.url,
buildName: jenkinsResult.fullDisplayName,
status: jenkinsResult.building ? 'running' : jenkinsResult.result,
onRestartClick: () => {
// TODO: this won't handle non root context path, need a better way to get the job name
const { jobName } = this.extractJobDetailsFromBuildName(path);
return this.retry(jobName);
},
source: source,
tests: this.getTestReport(jenkinsResult),
};
}
async getBuild(buildName: string) {
const client = await this.getClient();
const { jobName, buildNumber } = this.extractJobDetailsFromBuildName(
buildName,
);
const buildResult = await client.build.get(jobName, buildNumber);
return buildResult;
}
extractJobDetailsFromBuildName(buildName: string) {
const trimmedBuild = buildName.replace(/\/job/g, '').replace(/\/$/, '');
const split = trimmedBuild.split('/');
const buildNumber = parseInt(split[split.length - 1], 10);
const jobName = trimmedBuild.slice(
0,
trimmedBuild.length - buildNumber.toString(10).length - 1,
);
return {
jobName,
buildNumber,
};
}
}
+1 -217
View File
@@ -14,220 +14,4 @@
* limitations under the License.
*/
import { createApiRef, DiscoveryApi } from '@backstage/core';
import { CITableBuildInfo } from '../components/BuildsPage/lib/CITable';
const jenkins = require('jenkins');
export const jenkinsApiRef = createApiRef<JenkinsApi>({
id: 'plugin.jenkins.service',
description: 'Used by the Jenkins plugin to make requests',
});
const DEFAULT_PROXY_PATH = '/jenkins/api';
type Options = {
discoveryApi: DiscoveryApi;
/**
* Path to use for requests via the proxy, defaults to /jenkins/api
*/
proxyPath?: string;
};
export class JenkinsApi {
private readonly discoveryApi: DiscoveryApi;
private readonly proxyPath: string;
constructor(options: Options) {
this.discoveryApi = options.discoveryApi;
this.proxyPath = options.proxyPath ?? DEFAULT_PROXY_PATH;
}
private async getClient() {
const proxyUrl = await this.discoveryApi.getBaseUrl('proxy');
return jenkins({ baseUrl: proxyUrl + this.proxyPath, promisify: true });
}
async retry(buildName: string) {
const client = await this.getClient();
// looks like the current SDK only supports triggering a new build
// can't see any support for replay (re-running the specific build with the same SCM info)
return await client.job.build(buildName);
}
async getLastBuild(jobName: string) {
const client = await this.getClient();
const job = await client.job.get(jobName);
const lastBuild = await client.build.get(jobName, job.lastBuild.number);
return lastBuild;
}
extractScmDetailsFromJob(jobDetails: any): any {
const scmInfo = jobDetails.actions
.filter(
(action: any) =>
action._class === 'jenkins.scm.api.metadata.ObjectMetadataAction',
)
.map((action: any) => {
return {
url: action?.objectUrl,
// https://javadoc.jenkins.io/plugin/scm-api/jenkins/scm/api/metadata/ObjectMetadataAction.html
// branch name for regular builds, pull request title on pull requests
displayName: action?.objectDisplayName,
};
})
.pop();
const author = jobDetails.actions
.filter(
(action: any) =>
action._class ===
'jenkins.scm.api.metadata.ContributorMetadataAction',
)
.map((action: any) => {
return action.contributorDisplayName;
})
.pop();
if (author) {
scmInfo.author = author;
}
return scmInfo;
}
async getJob(jobName: string) {
const client = await this.getClient();
return client.job.get({
name: jobName,
depth: 1,
});
}
async getFolder(folderName: string) {
const client = await this.getClient();
const folder = await client.job.get(folderName);
const results = [];
for (const jobSummary of folder.jobs) {
const jobDetails = await client.job.get({
name: `${folderName}/${jobSummary.name}`,
depth: 1,
});
const jobScmInfo = this.extractScmDetailsFromJob(jobDetails);
if (jobDetails.jobs) {
// skipping folders inside folders for now
} else {
for (const buildDetails of jobDetails.builds) {
const build = await client.build.get({
name: `${folderName}/${jobSummary.name}`,
number: buildDetails.number,
depth: 1,
});
const ciTable = this.mapJenkinsBuildToCITable(build, jobScmInfo);
results.push(ciTable);
}
}
}
return results;
}
private getTestReport(
jenkinsResult: any,
): {
total: number;
passed: number;
skipped: number;
failed: number;
testUrl: string;
} {
return jenkinsResult.actions
.filter(
(action: any) =>
action._class === 'hudson.tasks.junit.TestResultAction',
)
.map((action: any) => {
return {
total: action.totalCount,
passed: action.totalCount - action.failCount - action.skipCount,
skipped: action.skipCount,
failed: action.failCount,
testUrl: `${jenkinsResult.url}${action.urlName}/`,
};
})
.pop();
}
mapJenkinsBuildToCITable(
jenkinsResult: any,
jobScmInfo?: any,
): CITableBuildInfo {
const source =
jenkinsResult.actions
.filter(
(action: any) =>
action._class === 'hudson.plugins.git.util.BuildData',
)
.map((action: any) => {
const [first]: any = Object.values(action.buildsByBranchName);
const branch = first.revision.branch[0];
return {
branchName: branch.name,
commit: {
hash: branch.SHA1.substring(0, 8),
},
};
})
.pop() || {};
if (jobScmInfo) {
source.url = jobScmInfo?.url;
source.displayName = jobScmInfo?.displayName;
source.author = jobScmInfo?.author;
}
const path = new URL(jenkinsResult.url).pathname;
return {
id: path,
buildNumber: jenkinsResult.number,
buildUrl: jenkinsResult.url,
buildName: jenkinsResult.fullDisplayName,
status: jenkinsResult.building ? 'running' : jenkinsResult.result,
onRestartClick: () => {
// TODO: this won't handle non root context path, need a better way to get the job name
const { jobName } = this.extractJobDetailsFromBuildName(path);
return this.retry(jobName);
},
source: source,
tests: this.getTestReport(jenkinsResult),
};
}
async getBuild(buildName: string) {
const client = await this.getClient();
const { jobName, buildNumber } = this.extractJobDetailsFromBuildName(
buildName,
);
const buildResult = await client.build.get(jobName, buildNumber);
return buildResult;
}
extractJobDetailsFromBuildName(buildName: string) {
const trimmedBuild = buildName.replace(/\/job/g, '').replace(/\/$/, '');
const split = trimmedBuild.split('/');
const buildNumber = parseInt(split[split.length - 1], 10);
const jobName = trimmedBuild.slice(
0,
trimmedBuild.length - buildNumber.toString(10).length - 1,
);
return {
jobName,
buildNumber,
};
}
}
export { JenkinsApi, jenkinsApiRef } from './JenkinsApi';
+12
View File
@@ -1,5 +1,17 @@
# @backstage/plugin-kubernetes-backend
## 0.2.1
### Patch Changes
- bcc211a08: k8s-plugin: refactor approach to use annotation based label-selector
- Updated dependencies [612368274]
- Updated dependencies [08835a61d]
- Updated dependencies [a9fd599f7]
- Updated dependencies [bcc211a08]
- @backstage/backend-common@0.3.3
- @backstage/catalog-model@0.4.0
## 0.2.0
### Minor Changes
@@ -42,7 +42,7 @@ kubernetes:
Mac copy to clipboard:
```
kubectl get secret $(kubectl get sa dice-roller -o=json | jq -r .secrets[0].name) -o=json | jq -r '.data["token"]' | base64 --decode | pbcopy
kubectl get secret $(kubectl get sa dice-roller -o=json | jq -r '.secrets[0].name') -o=json | jq -r '.data["token"]' | base64 --decode | pbcopy
```
Paste into `app-config.local.yaml` `kubernetes.clusters[0].serviceAccountToken`
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-kubernetes-backend",
"version": "0.2.0",
"version": "0.2.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,8 +21,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/backend-common": "^0.3.1",
"@backstage/catalog-model": "^0.3.0",
"@backstage/backend-common": "^0.3.3",
"@backstage/catalog-model": "^0.4.0",
"@backstage/config": "^0.1.1",
"@kubernetes/client-node": "^0.12.1",
"@types/express": "^4.17.6",
@@ -39,7 +39,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.3.1",
"@backstage/cli": "^0.4.0",
"supertest": "^4.0.2"
},
"files": [
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { Config, ConfigReader } from '../../../../packages/config/src';
import { Config, ConfigReader } from '@backstage/config';
import { getCombinedClusterDetails } from './index';
describe('getCombinedClusterDetails', () => {
@@ -15,7 +15,7 @@
*/
import { ClusterDetails, ClusterLocatorMethod } from '..';
import { Config } from '../../../../packages/config/src';
import { Config } from '@backstage/config';
import { ConfigClusterLocator } from './ConfigClusterLocator';
export { ConfigClusterLocator } from './ConfigClusterLocator';
@@ -16,7 +16,6 @@
import { handleGetKubernetesObjectsForService } from './getKubernetesObjectsForServiceHandler';
import { getVoidLogger } from '@backstage/backend-common';
import { ComponentEntityV1alpha1 } from '@backstage/catalog-model';
import { ObjectFetchParams } from '..';
const TEST_SERVICE_ID = 'my-service';
@@ -25,26 +24,6 @@ const fetchObjectsForService = jest.fn();
const getClustersByServiceId = jest.fn();
const goodEntity: ComponentEntityV1alpha1 = {
apiVersion: 'backstage.io/v1beta1',
kind: 'Component',
metadata: {
name: 'test-component',
},
spec: {
type: 'service',
lifecycle: 'production',
owner: 'joe',
kubernetes: {
selector: {
matchLabels: {
'backstage.io/test-label': 'test-component',
},
},
},
},
};
const mockFetch = (mock: jest.Mock) => {
mock.mockImplementation((params: ObjectFetchParams) =>
Promise.resolve({
@@ -111,7 +90,24 @@ describe('handleGetKubernetesObjectsForService', () => {
getClustersByServiceId,
},
getVoidLogger(),
{ entity: goodEntity },
{
entity: {
apiVersion: 'backstage.io/v1beta1',
kind: 'Component',
metadata: {
name: 'test-component',
annotations: {
'backstage.io/kubernetes-labels-selector':
'backstage.io/test-label=test-component',
},
},
spec: {
type: 'service',
lifecycle: 'production',
owner: 'joe',
},
},
},
);
expect(getClustersByServiceId.mock.calls.length).toBe(1);
@@ -186,10 +182,25 @@ describe('handleGetKubernetesObjectsForService', () => {
},
getVoidLogger(),
{
entity: goodEntity,
auth: {
google: 'google_token_123',
},
entity: {
apiVersion: 'backstage.io/v1beta1',
kind: 'Component',
metadata: {
name: 'test-component',
annotations: {
'backstage.io/kubernetes-labels-selector':
'backstage.io/test-label=test-component',
},
},
spec: {
type: 'service',
lifecycle: 'production',
owner: 'joe',
},
},
},
);
@@ -15,7 +15,6 @@
*/
import { Logger } from 'winston';
import { ComponentEntityV1alpha1 } from '@backstage/catalog-model';
import {
KubernetesRequestBody,
ClusterDetails,
@@ -47,18 +46,6 @@ const DEFAULT_OBJECTS = new Set<KubernetesObjectTypes>([
'ingresses',
]);
function parseLabelSelector(entity: ComponentEntityV1alpha1): string {
const matchLabels = entity?.spec?.kubernetes?.selector?.matchLabels;
if (matchLabels) {
// TODO: figure out how to convert the selector to the full query param from the yaml
// (as shown here https://github.com/kubernetes/apimachinery/blob/master/pkg/labels/selector.go)
return Object.keys(matchLabels)
.map(key => `${key}=${matchLabels[key.toString()]}`)
.join(',');
}
return '';
}
// Fans out the request to all clusters that the service lives in, aggregates their responses together
export const handleGetKubernetesObjectsForService: GetKubernetesObjectsForServiceHandler = async (
serviceId,
@@ -92,7 +79,10 @@ export const handleGetKubernetesObjectsForService: GetKubernetesObjectsForServic
.join(', ')}]`,
);
const labelSelector = parseLabelSelector(requestBody.entity);
const labelSelector: string =
requestBody.entity?.metadata?.annotations?.[
'backstage.io/kubernetes-label-selector'
] || `backstage.io/kubernetes-id=${requestBody.entity.metadata.name}`;
return Promise.all(
clusterDetailsDecoratedForAuth.map(clusterDetails => {
@@ -23,7 +23,7 @@ import {
V1ReplicaSet,
V1Service,
} from '@kubernetes/client-node';
import { ComponentEntityV1alpha1 } from '@backstage/catalog-model';
import { Entity } from '@backstage/catalog-model';
export interface ClusterDetails {
name: string;
@@ -36,7 +36,7 @@ export interface KubernetesRequestBody {
auth?: {
google?: string;
};
entity: ComponentEntityV1alpha1;
entity: Entity;
}
export interface ClusterObjects {
+11
View File
@@ -1,5 +1,16 @@
# @backstage/plugin-kubernetes
## 0.3.1
### Patch Changes
- bcc211a08: k8s-plugin: refactor approach to use annotation based label-selector
- Updated dependencies [08835a61d]
- Updated dependencies [a9fd599f7]
- Updated dependencies [bcc211a08]
- @backstage/catalog-model@0.4.0
- @backstage/plugin-kubernetes-backend@0.2.1
## 0.3.0
### Minor Changes
+12 -17
View File
@@ -17,23 +17,7 @@ It is only meant for local development, and the setup for it can be found inside
There are two ways to surface your kubernetes components as part of an entity.
The label selector takes precedence over the annotation/service id.
### Full label selector
#### Adding the entity label selector to the spec
In order for Backstage to detect that an entity has kubernetes components the `kubernetes.selector` must have a valid selector. (Currently only matchLabels is supported)
```yaml
spec:
kubernetes:
selector:
matchLabels:
someKey: someValue
other-key: other-value
app.kubernetes.io/name: dice-roller
```
### Common `backstage.io/kubernetes-id` label on objects
### Common `backstage.io/kubernetes-id` label
#### Adding the entity annotation
@@ -53,3 +37,14 @@ as a part of an entity, Kubernetes components must be labeled with the following
```yaml
'backstage.io/kubernetes-id': <ENTITY_NAME>
```
### label selector query annotation
#### Adding a label selector query annotation
You can write your own custom label selector query that backstage will use to lookup the objects (similar to `kubectl --selector="your query here"`)
review the documentation [here](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/) for more info
```yaml
'backstage.io/kubernetes-label-selector': 'app=my-app,component=front-end'
```
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-kubernetes",
"version": "0.3.0",
"version": "0.3.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,10 +21,10 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/catalog-model": "^0.3.0",
"@backstage/catalog-model": "^0.4.0",
"@backstage/config": "^0.1.1",
"@backstage/core": "^0.3.2",
"@backstage/plugin-kubernetes-backend": "^0.2.0",
"@backstage/plugin-kubernetes-backend": "^0.2.1",
"@backstage/theme": "^0.2.1",
"@kubernetes/client-node": "^0.12.1",
"@material-ui/core": "^4.11.0",
@@ -36,9 +36,9 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.3.2",
"@backstage/dev-utils": "^0.1.4",
"@backstage/test-utils": "^0.1.3",
"@backstage/cli": "^0.4.0",
"@backstage/dev-utils": "^0.1.5",
"@backstage/test-utils": "^0.1.4",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
@@ -26,7 +26,7 @@ import {
TabbedCard,
useApi,
} from '@backstage/core';
import { ComponentEntityV1alpha1, Entity } from '@backstage/catalog-model';
import { Entity } from '@backstage/catalog-model';
import { kubernetesApiRef } from '../../api/types';
import {
KubernetesRequestBody,
@@ -121,7 +121,7 @@ export const KubernetesContent = ({ entity }: KubernetesContentProps) => {
(async () => {
// For each auth type, invoke decorateRequestBodyForAuth on corresponding KubernetesAuthProvider
let requestBody: KubernetesRequestBody = {
entity: entity as ComponentEntityV1alpha1,
entity,
};
for (const authProviderStr of authProviders) {
// Multiple asyncs done sequentially instead of all at once to prevent same requestBody from being modified simultaneously
+13
View File
@@ -1,5 +1,18 @@
# @backstage/plugin-lighthouse
## 0.2.4
### Patch Changes
- Updated dependencies [b4488ddb0]
- Updated dependencies [08835a61d]
- Updated dependencies [a9fd599f7]
- Updated dependencies [bcc211a08]
- Updated dependencies [ebf37bbae]
- @backstage/core-api@0.2.4
- @backstage/catalog-model@0.4.0
- @backstage/plugin-catalog@0.2.5
## 0.2.3
### Patch Changes
+7 -7
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-lighthouse",
"version": "0.2.3",
"version": "0.2.4",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,11 +21,11 @@
"start": "backstage-cli plugin:serve"
},
"dependencies": {
"@backstage/catalog-model": "^0.3.0",
"@backstage/catalog-model": "^0.4.0",
"@backstage/config": "^0.1.1",
"@backstage/core": "^0.3.2",
"@backstage/core-api": "^0.2.1",
"@backstage/plugin-catalog": "^0.2.3",
"@backstage/core-api": "^0.2.4",
"@backstage/plugin-catalog": "^0.2.5",
"@backstage/theme": "^0.2.1",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -38,9 +38,9 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.3.2",
"@backstage/dev-utils": "^0.1.4",
"@backstage/test-utils": "^0.1.3",
"@backstage/cli": "^0.4.0",
"@backstage/dev-utils": "^0.1.5",
"@backstage/test-utils": "^0.1.4",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+3 -3
View File
@@ -31,9 +31,9 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.3.2",
"@backstage/dev-utils": "^0.1.4",
"@backstage/test-utils": "^0.1.3",
"@backstage/cli": "^0.4.0",
"@backstage/dev-utils": "^0.1.5",
"@backstage/test-utils": "^0.1.4",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+11
View File
@@ -1,5 +1,16 @@
# @backstage/plugin-proxy-backend
## 0.2.2
### Patch Changes
- 6a6c7c14e: Filter the headers that are sent from the proxied-targed back to the frontend to not forwarded unwanted authentication or
monitoring contexts from other origins (like `Set-Cookie` with e.g. a google analytics context). The implementation reuses
the `allowedHeaders` configuration that now controls both directions `frontend->target` and `target->frontend`.
- 3619ea4c4: Add configuration schema for the commonly used properties
- Updated dependencies [612368274]
- @backstage/backend-common@0.3.3
## 0.2.1
### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-proxy-backend",
"version": "0.2.1",
"version": "0.2.2",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -19,7 +19,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/backend-common": "^0.3.0",
"@backstage/backend-common": "^0.3.3",
"@backstage/config": "^0.1.1",
"@types/express": "^4.17.6",
"express": "^4.17.1",
@@ -33,7 +33,7 @@
"yup": "^0.29.3"
},
"devDependencies": {
"@backstage/cli": "^0.3.0",
"@backstage/cli": "^0.4.0",
"@types/http-proxy-middleware": "^0.19.3",
"@types/supertest": "^2.0.8",
"@types/uuid": "^8.0.0",
+11
View File
@@ -1,5 +1,16 @@
# @backstage/plugin-register-component
## 0.2.3
### Patch Changes
- Updated dependencies [08835a61d]
- Updated dependencies [a9fd599f7]
- Updated dependencies [bcc211a08]
- Updated dependencies [ebf37bbae]
- @backstage/catalog-model@0.4.0
- @backstage/plugin-catalog@0.2.5
## 0.2.2
### Patch Changes
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-register-component",
"version": "0.2.2",
"version": "0.2.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,9 +21,9 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/catalog-model": "^0.3.0",
"@backstage/catalog-model": "^0.4.0",
"@backstage/core": "^0.3.2",
"@backstage/plugin-catalog": "^0.2.3",
"@backstage/plugin-catalog": "^0.2.5",
"@backstage/theme": "^0.2.1",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -36,9 +36,9 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.3.2",
"@backstage/dev-utils": "^0.1.4",
"@backstage/test-utils": "^0.1.3",
"@backstage/cli": "^0.4.0",
"@backstage/dev-utils": "^0.1.5",
"@backstage/test-utils": "^0.1.4",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+2 -2
View File
@@ -20,7 +20,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/backend-common": "^0.3.2",
"@backstage/backend-common": "^0.3.3",
"@backstage/config": "^0.1.1",
"@types/express": "^4.17.6",
"axios": "^0.20.0",
@@ -37,7 +37,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.3.2",
"@backstage/cli": "^0.4.0",
"@types/supertest": "^2.0.8",
"supertest": "^4.0.2"
},
+11
View File
@@ -1,5 +1,16 @@
# @backstage/plugin-rollbar
## 0.2.5
### Patch Changes
- Updated dependencies [08835a61d]
- Updated dependencies [a9fd599f7]
- Updated dependencies [bcc211a08]
- Updated dependencies [ebf37bbae]
- @backstage/catalog-model@0.4.0
- @backstage/plugin-catalog@0.2.5
## 0.2.4
### Patch Changes
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-rollbar",
"version": "0.2.4",
"version": "0.2.5",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,9 +21,9 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/catalog-model": "^0.3.1",
"@backstage/catalog-model": "^0.4.0",
"@backstage/core": "^0.3.2",
"@backstage/plugin-catalog": "^0.2.4",
"@backstage/plugin-catalog": "^0.2.5",
"@backstage/theme": "^0.2.1",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -37,9 +37,9 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.3.2",
"@backstage/dev-utils": "^0.1.4",
"@backstage/test-utils": "^0.1.3",
"@backstage/cli": "^0.4.0",
"@backstage/dev-utils": "^0.1.5",
"@backstage/test-utils": "^0.1.4",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/react-hooks": "^3.3.0",
+11
View File
@@ -1,5 +1,16 @@
# @backstage/plugin-scaffolder-backend
## 0.3.3
### Patch Changes
- Updated dependencies [612368274]
- Updated dependencies [08835a61d]
- Updated dependencies [a9fd599f7]
- Updated dependencies [bcc211a08]
- @backstage/backend-common@0.3.3
- @backstage/catalog-model@0.4.0
## 0.3.2
### Patch Changes
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-scaffolder-backend",
"version": "0.3.2",
"version": "0.3.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -20,8 +20,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/backend-common": "^0.3.1",
"@backstage/catalog-model": "^0.3.0",
"@backstage/backend-common": "^0.3.3",
"@backstage/catalog-model": "^0.4.0",
"@backstage/config": "^0.1.1",
"@gitbeaker/core": "^25.2.0",
"@gitbeaker/node": "^25.2.0",
@@ -48,7 +48,7 @@
"cross-fetch": "^3.0.6"
},
"devDependencies": {
"@backstage/cli": "^0.3.1",
"@backstage/cli": "^0.4.0",
"@octokit/types": "^5.4.1",
"@types/fs-extra": "^9.0.1",
"@types/git-url-parse": "^9.0.0",
+33
View File
@@ -1,5 +1,38 @@
# @backstage/plugin-scaffolder
## 0.3.2
### Patch Changes
- a9fd599f7: Add Analyze location endpoint to catalog backend. Add catalog-import plugin and replace import-component with it. To start using Analyze location endpoint, you have add it to the `createRouter` function options in the `\backstage\packages\backend\src\plugins\catalog.ts` file:
```ts
export default async function createPlugin(env: PluginEnvironment) {
const builder = new CatalogBuilder(env);
const {
entitiesCatalog,
locationsCatalog,
higherOrderOperation,
locationAnalyzer, //<--
} = await builder.build();
return await createRouter({
entitiesCatalog,
locationsCatalog,
higherOrderOperation,
locationAnalyzer, //<--
logger: env.logger,
});
}
```
- Updated dependencies [08835a61d]
- Updated dependencies [a9fd599f7]
- Updated dependencies [bcc211a08]
- Updated dependencies [ebf37bbae]
- @backstage/catalog-model@0.4.0
- @backstage/plugin-catalog@0.2.5
## 0.3.1
### Patch Changes
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-scaffolder",
"version": "0.3.1",
"version": "0.3.2",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,9 +21,9 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/catalog-model": "^0.3.0",
"@backstage/catalog-model": "^0.4.0",
"@backstage/core": "^0.3.2",
"@backstage/plugin-catalog": "^0.2.3",
"@backstage/plugin-catalog": "^0.2.5",
"@backstage/theme": "^0.2.1",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -41,9 +41,9 @@
"swr": "^0.3.0"
},
"devDependencies": {
"@backstage/cli": "^0.3.2",
"@backstage/dev-utils": "^0.1.4",
"@backstage/test-utils": "^0.1.3",
"@backstage/cli": "^0.4.0",
"@backstage/dev-utils": "^0.1.5",
"@backstage/test-utils": "^0.1.4",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+11
View File
@@ -1,5 +1,16 @@
# @backstage/plugin-search
## 0.2.2
### Patch Changes
- Updated dependencies [08835a61d]
- Updated dependencies [a9fd599f7]
- Updated dependencies [bcc211a08]
- Updated dependencies [ebf37bbae]
- @backstage/catalog-model@0.4.0
- @backstage/plugin-catalog@0.2.5
## 0.2.1
### Patch Changes
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-search",
"version": "0.2.1",
"version": "0.2.2",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,8 +21,8 @@
},
"dependencies": {
"@backstage/core": "^0.3.2",
"@backstage/plugin-catalog": "^0.2.3",
"@backstage/catalog-model": "^0.3.0",
"@backstage/plugin-catalog": "^0.2.5",
"@backstage/catalog-model": "^0.4.0",
"@backstage/theme": "^0.2.1",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -34,9 +34,9 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.3.2",
"@backstage/dev-utils": "^0.1.4",
"@backstage/test-utils": "^0.1.3",
"@backstage/cli": "^0.4.0",
"@backstage/dev-utils": "^0.1.5",
"@backstage/test-utils": "^0.1.4",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+2 -2
View File
@@ -20,7 +20,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/backend-common": "^0.3.0",
"@backstage/backend-common": "^0.3.3",
"@types/express": "^4.17.6",
"axios": "^0.20.0",
"compression": "^1.7.4",
@@ -34,7 +34,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.3.0"
"@backstage/cli": "^0.4.0"
},
"files": [
"dist"
+10
View File
@@ -1,5 +1,15 @@
# @backstage/plugin-sentry
## 0.2.4
### Patch Changes
- 303c5ea17: Refactor route registration to remove deprecating code
- Updated dependencies [08835a61d]
- Updated dependencies [a9fd599f7]
- Updated dependencies [bcc211a08]
- @backstage/catalog-model@0.4.0
## 0.2.3
### Patch Changes
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-sentry",
"version": "0.2.3",
"version": "0.2.4",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,7 +21,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/catalog-model": "^0.3.0",
"@backstage/catalog-model": "^0.4.0",
"@backstage/core": "^0.3.2",
"@backstage/theme": "^0.2.1",
"@material-ui/core": "^4.11.0",
@@ -36,9 +36,9 @@
"timeago.js": "^4.0.2"
},
"devDependencies": {
"@backstage/cli": "^0.3.2",
"@backstage/dev-utils": "^0.1.4",
"@backstage/test-utils": "^0.1.3",
"@backstage/cli": "^0.4.0",
"@backstage/dev-utils": "^0.1.5",
"@backstage/test-utils": "^0.1.4",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+9
View File
@@ -1,5 +1,14 @@
# @backstage/plugin-sonarqube
## 0.1.5
### Patch Changes
- Updated dependencies [08835a61d]
- Updated dependencies [a9fd599f7]
- Updated dependencies [bcc211a08]
- @backstage/catalog-model@0.4.0
## 0.1.4
### Patch Changes
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-sonarqube",
"version": "0.1.4",
"version": "0.1.5",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,7 +21,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/catalog-model": "^0.3.0",
"@backstage/catalog-model": "^0.4.0",
"@backstage/core": "^0.3.2",
"@backstage/theme": "^0.2.1",
"@material-ui/core": "^4.11.0",
@@ -35,9 +35,9 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.3.2",
"@backstage/dev-utils": "^0.1.4",
"@backstage/test-utils": "^0.1.3",
"@backstage/cli": "^0.4.0",
"@backstage/dev-utils": "^0.1.5",
"@backstage/test-utils": "^0.1.4",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+4 -4
View File
@@ -22,7 +22,7 @@
},
"dependencies": {
"@backstage/core": "^0.3.2",
"@backstage/test-utils": "^0.1.3",
"@backstage/test-utils": "^0.1.4",
"@backstage/theme": "^0.2.1",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -35,9 +35,9 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.3.2",
"@backstage/dev-utils": "^0.1.4",
"@backstage/test-utils": "^0.1.3",
"@backstage/cli": "^0.4.0",
"@backstage/dev-utils": "^0.1.5",
"@backstage/test-utils": "^0.1.4",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+12
View File
@@ -1,5 +1,17 @@
# @backstage/plugin-techdocs-backend
## 0.3.1
### Patch Changes
- ae95c7ff3: Update URL auth format for Gitlab clone
- Updated dependencies [612368274]
- Updated dependencies [08835a61d]
- Updated dependencies [a9fd599f7]
- Updated dependencies [bcc211a08]
- @backstage/backend-common@0.3.3
- @backstage/catalog-model@0.4.0
## 0.3.0
### Minor Changes
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-techdocs-backend",
"version": "0.3.0",
"version": "0.3.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -20,8 +20,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/backend-common": "^0.3.2",
"@backstage/catalog-model": "^0.3.1",
"@backstage/backend-common": "^0.3.3",
"@backstage/catalog-model": "^0.4.0",
"@backstage/config": "^0.1.1",
"@backstage/techdocs-common": "^0.1.1",
"@types/dockerode": "^2.5.34",
@@ -34,7 +34,7 @@
"winston": "^3.2.1"
},
"devDependencies": {
"@backstage/cli": "^0.3.2",
"@backstage/cli": "^0.4.0",
"supertest": "^4.0.2"
},
"files": [
+15
View File
@@ -1,5 +1,20 @@
# @backstage/plugin-techdocs
## 0.3.1
### Patch Changes
- da2ad65cb: Use type EntityName from catalog-model for entities
- Updated dependencies [b4488ddb0]
- Updated dependencies [08835a61d]
- Updated dependencies [a9fd599f7]
- Updated dependencies [bcc211a08]
- Updated dependencies [ebf37bbae]
- @backstage/core-api@0.2.4
- @backstage/catalog-model@0.4.0
- @backstage/plugin-catalog@0.2.5
- @backstage/test-utils@0.1.4
## 0.3.0
### Minor Changes
+8 -8
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-techdocs",
"version": "0.3.0",
"version": "0.3.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,12 +21,12 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/catalog-model": "^0.3.1",
"@backstage/catalog-model": "^0.4.0",
"@backstage/core": "^0.3.2",
"@backstage/core-api": "^0.2.3",
"@backstage/plugin-catalog": "^0.2.4",
"@backstage/core-api": "^0.2.4",
"@backstage/plugin-catalog": "^0.2.5",
"@backstage/techdocs-common": "^0.1.1",
"@backstage/test-utils": "^0.1.3",
"@backstage/test-utils": "^0.1.4",
"@backstage/theme": "^0.2.1",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -40,9 +40,9 @@
"sanitize-html": "^1.27.0"
},
"devDependencies": {
"@backstage/cli": "^0.3.2",
"@backstage/dev-utils": "^0.1.4",
"@backstage/test-utils": "^0.1.3",
"@backstage/cli": "^0.4.0",
"@backstage/dev-utils": "^0.1.5",
"@backstage/test-utils": "^0.1.4",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+3 -3
View File
@@ -32,9 +32,9 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.3.2",
"@backstage/dev-utils": "^0.1.4",
"@backstage/test-utils": "^0.1.3",
"@backstage/cli": "^0.4.0",
"@backstage/dev-utils": "^0.1.5",
"@backstage/test-utils": "^0.1.4",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+6
View File
@@ -1,5 +1,11 @@
# @backstage/plugin-welcome
## 0.2.2
### Patch Changes
- 303c5ea17: Refactor route registration to remove deprecating code
## 0.2.1
### Patch Changes
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-welcome",
"version": "0.2.1",
"version": "0.2.2",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
@@ -32,9 +32,9 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.3.2",
"@backstage/dev-utils": "^0.1.4",
"@backstage/test-utils": "^0.1.3",
"@backstage/cli": "^0.4.0",
"@backstage/dev-utils": "^0.1.5",
"@backstage/test-utils": "^0.1.4",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",