From ce7822674788c9700ab34bf0521e6dd5c2ef33ff Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Wed, 6 Oct 2021 14:32:58 -0500 Subject: [PATCH 01/10] Adding Azure DevOps frontend plugin Signed-off-by: Andre Wanlin --- app-config.yaml | 1 + packages/app/package.json | 1 + .../app/src/components/catalog/EntityPage.tsx | 8 ++ plugins/azure-devops/.eslintrc.js | 3 + plugins/azure-devops/README.md | 135 ++++++++++++++++++ plugins/azure-devops/api-report.md | 35 +++++ plugins/azure-devops/config.d.ts | 26 ++++ plugins/azure-devops/dev/index.tsx | 20 +++ .../azure-devops/doc/azure-devops-builds.png | Bin 0 -> 177135 bytes plugins/azure-devops/package.json | 62 ++++++++ .../azure-devops/src/api/AzureDevOpsApi.ts | 32 +++++ .../azure-devops/src/api/AzureDevOpsClient.ts | 56 ++++++++ plugins/azure-devops/src/api/index.ts | 18 +++ plugins/azure-devops/src/api/types.ts | 30 ++++ .../src/components/BuildTable/BuildTable.tsx | 132 +++++++++++++++++ .../src/components/BuildTable/index.ts | 17 +++ .../EntityPageAzureDevOps.tsx | 33 +++++ .../components/EntityPageAzureDevOps/index.ts | 17 +++ .../azure-devops/src/components/Router.tsx | 48 +++++++ plugins/azure-devops/src/constants.ts | 17 +++ .../src/hooks/useProjectRepoFromEntity.ts | 25 ++++ .../azure-devops/src/hooks/useRepoBuilds.ts | 40 ++++++ plugins/azure-devops/src/index.ts | 17 +++ plugins/azure-devops/src/plugin.test.ts | 22 +++ plugins/azure-devops/src/plugin.ts | 54 +++++++ plugins/azure-devops/src/routes.ts | 20 +++ plugins/azure-devops/src/setupTests.ts | 17 +++ 27 files changed, 886 insertions(+) create mode 100644 plugins/azure-devops/.eslintrc.js create mode 100644 plugins/azure-devops/README.md create mode 100644 plugins/azure-devops/api-report.md create mode 100644 plugins/azure-devops/config.d.ts create mode 100644 plugins/azure-devops/dev/index.tsx create mode 100644 plugins/azure-devops/doc/azure-devops-builds.png create mode 100644 plugins/azure-devops/package.json create mode 100644 plugins/azure-devops/src/api/AzureDevOpsApi.ts create mode 100644 plugins/azure-devops/src/api/AzureDevOpsClient.ts create mode 100644 plugins/azure-devops/src/api/index.ts create mode 100644 plugins/azure-devops/src/api/types.ts create mode 100644 plugins/azure-devops/src/components/BuildTable/BuildTable.tsx create mode 100644 plugins/azure-devops/src/components/BuildTable/index.ts create mode 100644 plugins/azure-devops/src/components/EntityPageAzureDevOps/EntityPageAzureDevOps.tsx create mode 100644 plugins/azure-devops/src/components/EntityPageAzureDevOps/index.ts create mode 100644 plugins/azure-devops/src/components/Router.tsx create mode 100644 plugins/azure-devops/src/constants.ts create mode 100644 plugins/azure-devops/src/hooks/useProjectRepoFromEntity.ts create mode 100644 plugins/azure-devops/src/hooks/useRepoBuilds.ts create mode 100644 plugins/azure-devops/src/index.ts create mode 100644 plugins/azure-devops/src/plugin.test.ts create mode 100644 plugins/azure-devops/src/plugin.ts create mode 100644 plugins/azure-devops/src/routes.ts create mode 100644 plugins/azure-devops/src/setupTests.ts diff --git a/app-config.yaml b/app-config.yaml index c24ac1701b..b92595df7b 100644 --- a/app-config.yaml +++ b/app-config.yaml @@ -436,3 +436,4 @@ azureDevOps: host: dev.azure.com token: my-token organization: my-company + top: 25 diff --git a/packages/app/package.json b/packages/app/package.json index d1892438d8..fe86077273 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -11,6 +11,7 @@ "@backstage/core-plugin-api": "^0.1.10", "@backstage/integration-react": "^0.1.11", "@backstage/plugin-api-docs": "^0.6.11", + "@backstage/plugin-azure-devops": "^0.1.0", "@backstage/plugin-badges": "^0.2.12", "@backstage/plugin-catalog": "^0.7.0", "@backstage/plugin-catalog-graph": "^0.1.3", diff --git a/packages/app/src/components/catalog/EntityPage.tsx b/packages/app/src/components/catalog/EntityPage.tsx index 62fdcf4d3f..b79bd2c4aa 100644 --- a/packages/app/src/components/catalog/EntityPage.tsx +++ b/packages/app/src/components/catalog/EntityPage.tsx @@ -33,6 +33,10 @@ import { EntityProvidedApisCard, EntityProvidingComponentsCard, } from '@backstage/plugin-api-docs'; +import { + EntityAzureDevOpsContent, + isAzureDevOpsAvailable, +} from '@backstage/plugin-azure-devops'; import { EntityBadgesDialog } from '@backstage/plugin-badges'; import { EntityAboutCard, @@ -183,6 +187,10 @@ export const cicdContent = ( + + + + { + return await createRouter({ logger, config }); + } + ``` + +3. Next we wire this into the overall backend router, edit `packages/backend/src/index.ts`: + + ```ts + import azureDevOps from './plugins/azuredevops'; + // ... + async function main() { + // ... + const azureDevOpsEnv = useHotMemoize(module, () => createEnv('azure-devops')); + apiRouter.use('/azure-devops', await azureDevOps(azureDevOpsEnv)); + ``` + +4. Now run `yarn start-backend` from the repo root +5. Finally open `http://localhost:7000/api/azure-devops/health` in a browser and it should return `{"status":"ok"}` + +### Frontend + +To get the frontend working you'll need to do the following two steps: + +1. First we need to add the @backstage/plugin-azure-devops package to your frontend app: + + ```bash + # From your Backstage root directory + cd packages/app + yarn add @backstage/plugin-azure-devops + ``` + +2. Second we need to add the `EntityAzureDevOpsContent` extension to the entity page in your app: + +```tsx +// In packages/app/src/components/catalog/EntityPage.tsx +import { + EntityAzureDevOpsContent, + isAzureDevOpsAvailable, +} from '@backstage/plugin-azure-devops'; + +// For example in the CI/CD section +const cicdContent = ( + + // ... + + + + // ... + +``` + +### Entity Annotation + +You need to add the following annotation to any entities you want to be able to use the Azure Devops plugin with: + +```yaml +dev.azure.com/project-repo: / +``` + +Let's break this down a little: `` will be the name of your Team Project and `` will be the name of your repository which needs to be part of the Team Project you entered for ``. + +Here's what that will look like in action: + +```yaml +# Example catalog-info.yaml entity definition file +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + # ... + annotations: + dev.azure.com/project-repo: my-project/my-repo +spec: + type: service + # ... +``` + +## Features + +- Lists the top _n_ builds for a given repository where _n_ is the value configured for `top` + +## Limitations + +- Currently multiple organizations is not supported diff --git a/plugins/azure-devops/api-report.md b/plugins/azure-devops/api-report.md new file mode 100644 index 0000000000..11de164276 --- /dev/null +++ b/plugins/azure-devops/api-report.md @@ -0,0 +1,35 @@ +## API Report File for "@backstage/plugin-azure-devops" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +/// + +import { BackstagePlugin } from '@backstage/core-plugin-api'; +import { Entity } from '@backstage/catalog-model'; +import { RouteRef } from '@backstage/core-plugin-api'; + +// Warning: (ae-missing-release-tag) "azureDevOpsPlugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const azureDevOpsPlugin: BackstagePlugin< + { + entityContent: RouteRef; + }, + {} +>; + +// Warning: (ae-missing-release-tag) "EntityAzureDevOpsContent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const EntityAzureDevOpsContent: (_props: { + entity?: Entity | undefined; +}) => JSX.Element; + +// Warning: (ae-missing-release-tag) "isAzureDevOpsAvailable" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const isAzureDevOpsAvailable: (entity: Entity) => boolean; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/azure-devops/config.d.ts b/plugins/azure-devops/config.d.ts new file mode 100644 index 0000000000..827e64d5bd --- /dev/null +++ b/plugins/azure-devops/config.d.ts @@ -0,0 +1,26 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * 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. + */ + +export interface Config { + /** Configuration options for the azure-devops-backend plugin */ + azureDevOps: { + /** + * The max number of items to return - applies to builds + * @visibility frontend + */ + top: number; + }; +} diff --git a/plugins/azure-devops/dev/index.tsx b/plugins/azure-devops/dev/index.tsx new file mode 100644 index 0000000000..8d1c3ef6ea --- /dev/null +++ b/plugins/azure-devops/dev/index.tsx @@ -0,0 +1,20 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createDevApp } from '@backstage/dev-utils'; +import { azureDevOpsPlugin } from '../src/plugin'; + +createDevApp().registerPlugin(azureDevOpsPlugin).render(); diff --git a/plugins/azure-devops/doc/azure-devops-builds.png b/plugins/azure-devops/doc/azure-devops-builds.png new file mode 100644 index 0000000000000000000000000000000000000000..89a777059f67b448c961bdcd829d38ddd9eea0d5 GIT binary patch literal 177135 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'OLF;}K1r?yk4 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 literal 0 HcmV?d00001 diff --git a/plugins/azure-devops/package.json b/plugins/azure-devops/package.json new file mode 100644 index 0000000000..fb59d5eb38 --- /dev/null +++ b/plugins/azure-devops/package.json @@ -0,0 +1,62 @@ +{ + "name": "@backstage/plugin-azure-devops", + "version": "0.1.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.esm.js", + "types": "dist/index.d.ts" + }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/azure-devops" + }, + "scripts": { + "build": "backstage-cli plugin:build", + "start": "backstage-cli plugin:serve", + "lint": "backstage-cli lint", + "test": "backstage-cli test", + "diff": "backstage-cli plugin:diff", + "prepack": "backstage-cli prepack", + "postpack": "backstage-cli postpack", + "clean": "backstage-cli clean" + }, + "dependencies": { + "@backstage/catalog-model": "^0.9.3", + "@backstage/core-components": "^0.6.0", + "@backstage/core-plugin-api": "^0.1.9", + "@backstage/plugin-catalog-react": "^0.5.1", + "@backstage/theme": "^0.2.10", + "@material-ui/core": "^4.12.2", + "@material-ui/icons": "^4.9.1", + "@material-ui/lab": "4.0.0-alpha.57", + "azure-devops-node-api": "^11.0.1", + "moment": "^2.29.1", + "react": "^16.13.1", + "react-dom": "^16.13.1", + "react-router": "6.0.0-beta.0", + "react-use": "^17.2.4" + }, + "devDependencies": { + "@backstage/cli": "^0.7.13", + "@backstage/core-app-api": "^0.1.14", + "@backstage/dev-utils": "^0.2.10", + "@backstage/test-utils": "^0.1.17", + "@testing-library/jest-dom": "^5.10.1", + "@testing-library/react": "^11.2.5", + "@testing-library/user-event": "^13.1.8", + "@types/jest": "*", + "@types/node": "*", + "msw": "^0.29.0", + "cross-fetch": "^3.0.6" + }, + "files": [ + "dist", + "config.d.ts" + ], + "configSchema": "config.d.ts" +} diff --git a/plugins/azure-devops/src/api/AzureDevOpsApi.ts b/plugins/azure-devops/src/api/AzureDevOpsApi.ts new file mode 100644 index 0000000000..424999441d --- /dev/null +++ b/plugins/azure-devops/src/api/AzureDevOpsApi.ts @@ -0,0 +1,32 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { RepoBuild } from './types'; +import { createApiRef } from '@backstage/core-plugin-api'; + +export const azureDevOpsApiRef = createApiRef({ + id: 'plugin.azure-devops.service', + description: + 'Used by the Azure DevOps plugin to make requests to accompanying backend', +}); + +export interface AzureDevOpsApi { + getRepoBuilds( + projectName: string, + repoName: string, + top: number, + ): Promise; +} diff --git a/plugins/azure-devops/src/api/AzureDevOpsClient.ts b/plugins/azure-devops/src/api/AzureDevOpsClient.ts new file mode 100644 index 0000000000..c9e44109aa --- /dev/null +++ b/plugins/azure-devops/src/api/AzureDevOpsClient.ts @@ -0,0 +1,56 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { AzureDevOpsApi } from './AzureDevOpsApi'; +import { RepoBuild } from './types'; +import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api'; + +export class AzureDevOpsClient implements AzureDevOpsApi { + private readonly discoveryApi: DiscoveryApi; + private readonly identityApi: IdentityApi; + + constructor(options: { + discoveryApi: DiscoveryApi; + identityApi: IdentityApi; + }) { + this.discoveryApi = options.discoveryApi; + this.identityApi = options.identityApi; + } + + async getRepoBuilds( + projectName: string, + repoName: string, + top: number, + ): Promise { + return await this.get(`/repo-builds/${projectName}/${repoName}?top=${top}`); + } + + private async get(path: string): Promise { + const url = `${await this.discoveryApi.getBaseUrl('azure-devops')}${path}`; + const idToken = await this.identityApi.getIdToken(); + const response = await fetch(url, { + headers: idToken ? { Authorization: `Bearer ${idToken}` } : {}, + }); + + if (!response.ok) { + const payload = await response.text(); + const message = `Request failed with ${response.status} ${response.statusText}, ${payload}`; + throw new Error(message); + } + + return await response.json(); + } +} diff --git a/plugins/azure-devops/src/api/index.ts b/plugins/azure-devops/src/api/index.ts new file mode 100644 index 0000000000..c69636222f --- /dev/null +++ b/plugins/azure-devops/src/api/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './AzureDevOpsApi'; +export * from './AzureDevOpsClient'; diff --git a/plugins/azure-devops/src/api/types.ts b/plugins/azure-devops/src/api/types.ts new file mode 100644 index 0000000000..35d4e38ae1 --- /dev/null +++ b/plugins/azure-devops/src/api/types.ts @@ -0,0 +1,30 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + BuildResult, + BuildStatus, +} from 'azure-devops-node-api/interfaces/BuildInterfaces'; + +export type RepoBuild = { + id?: number; + title: string; + link: string; + status?: BuildStatus; + result?: BuildResult; + queueTime?: Date; + source: string; +}; diff --git a/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx b/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx new file mode 100644 index 0000000000..26f365c5e9 --- /dev/null +++ b/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx @@ -0,0 +1,132 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import moment from 'moment'; +import { + Table, + TableColumn, + StatusError, + StatusOK, + StatusWarning, + StatusAborted, +} from '@backstage/core-components'; +import { Link, Box, Typography } from '@material-ui/core'; +import Alert from '@material-ui/lab/Alert'; +import { RepoBuild } from '../../api/types'; +import { + BuildResult, + BuildStatus, +} from 'azure-devops-node-api/interfaces/BuildInterfaces'; + +const getBuildResultComponent = (result: number | undefined = 0) => { + switch (result) { + case 0: // None + return ; + case 2: // Succeeded + return ; + case 4: // PartiallySucceeded + return ; + case 8: // Failed + return ; + case 32: // Canceled + return ; + default: + return ; + } +}; + +const columns: TableColumn[] = [ + { + title: 'ID', + field: 'id', + highlight: false, + width: '80px', + }, + { + title: 'Build', + field: 'title', + render: (row: Partial) => ( + + {row.title} + + ), + }, + { + title: 'Source', + field: 'source', + }, + { + title: 'Status', + field: 'status', + render: (row: Partial) => ( + + + {BuildStatus[row.status || 0]} + + ), + }, + { + title: 'Result', + field: 'result', + render: (row: Partial) => ( + + {getBuildResultComponent(row.result)} + + {BuildResult[row.result || 0]} + + ), + }, + { + title: 'Date', + field: 'queueTime', + render: (row: Partial) => moment(row.queueTime).fromNow(), + }, +]; + +type Props = { + items: RepoBuild[]; + loading: boolean; + error?: any; +}; + +export const BuildTable = ({ items, loading, error }: Props) => { + if (error) { + return ( +
+ + Error encountered while fetching Azure DevOps builds.{' '} + {error.toString()} + +
+ ); + } + + return ( + + ); +}; diff --git a/plugins/azure-devops/src/components/BuildTable/index.ts b/plugins/azure-devops/src/components/BuildTable/index.ts new file mode 100644 index 0000000000..acf20eb523 --- /dev/null +++ b/plugins/azure-devops/src/components/BuildTable/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { BuildTable } from './BuildTable'; diff --git a/plugins/azure-devops/src/components/EntityPageAzureDevOps/EntityPageAzureDevOps.tsx b/plugins/azure-devops/src/components/EntityPageAzureDevOps/EntityPageAzureDevOps.tsx new file mode 100644 index 0000000000..fbeac53569 --- /dev/null +++ b/plugins/azure-devops/src/components/EntityPageAzureDevOps/EntityPageAzureDevOps.tsx @@ -0,0 +1,33 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entity } from '@backstage/catalog-model'; +import { useEntity } from '@backstage/plugin-catalog-react'; +import React from 'react'; +import { useRepoBuilds } from '../../hooks/useRepoBuilds'; +import { BuildTable } from '../BuildTable/BuildTable'; + +type Props = { + /** @deprecated The entity is now grabbed from context instead */ + entity?: Entity; +}; + +export const EntityPageAzureDevOps = (_props: Props) => { + const { entity } = useEntity(); + const { items, loading, error } = useRepoBuilds(entity); + + return ; +}; diff --git a/plugins/azure-devops/src/components/EntityPageAzureDevOps/index.ts b/plugins/azure-devops/src/components/EntityPageAzureDevOps/index.ts new file mode 100644 index 0000000000..89ee4f199b --- /dev/null +++ b/plugins/azure-devops/src/components/EntityPageAzureDevOps/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { EntityPageAzureDevOps } from './EntityPageAzureDevOps'; diff --git a/plugins/azure-devops/src/components/Router.tsx b/plugins/azure-devops/src/components/Router.tsx new file mode 100644 index 0000000000..74cf0439f8 --- /dev/null +++ b/plugins/azure-devops/src/components/Router.tsx @@ -0,0 +1,48 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { Routes, Route } from 'react-router'; +import { azureDevOpsRouteRef } from '../routes'; +import { EntityPageAzureDevOps } from './EntityPageAzureDevOps'; +import { AZURE_DEVOPS_ANNOTATION } from '../constants'; +import { Entity } from '@backstage/catalog-model'; +import { useEntity } from '@backstage/plugin-catalog-react'; +import { MissingAnnotationEmptyState } from '@backstage/core-components'; + +export const isAzureDevOpsAvailable = (entity: Entity) => + Boolean(entity.metadata.annotations?.[AZURE_DEVOPS_ANNOTATION]); + +type Props = { + /** @deprecated The entity is now grabbed from context instead */ + entity?: Entity; +}; + +export const Router = (_props: Props) => { + const { entity } = useEntity(); + + if (!isAzureDevOpsAvailable(entity)) { + return ; + } + + return ( + + } + /> + + ); +}; diff --git a/plugins/azure-devops/src/constants.ts b/plugins/azure-devops/src/constants.ts new file mode 100644 index 0000000000..6abc6449e9 --- /dev/null +++ b/plugins/azure-devops/src/constants.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export const AZURE_DEVOPS_ANNOTATION = 'dev.azure.com/project-repo'; diff --git a/plugins/azure-devops/src/hooks/useProjectRepoFromEntity.ts b/plugins/azure-devops/src/hooks/useProjectRepoFromEntity.ts new file mode 100644 index 0000000000..721fa52781 --- /dev/null +++ b/plugins/azure-devops/src/hooks/useProjectRepoFromEntity.ts @@ -0,0 +1,25 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entity } from '@backstage/catalog-model'; +import { AZURE_DEVOPS_ANNOTATION } from '../constants'; + +export function useProjectRepoFromEntity(entity: Entity) { + const [project, repo] = ( + entity.metadata.annotations?.[AZURE_DEVOPS_ANNOTATION] ?? '' + ).split('/'); + return { project, repo }; +} diff --git a/plugins/azure-devops/src/hooks/useRepoBuilds.ts b/plugins/azure-devops/src/hooks/useRepoBuilds.ts new file mode 100644 index 0000000000..e6d2964770 --- /dev/null +++ b/plugins/azure-devops/src/hooks/useRepoBuilds.ts @@ -0,0 +1,40 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { useAsync } from 'react-use'; +import { Entity } from '@backstage/catalog-model'; +import { useApi, configApiRef } from '@backstage/core-plugin-api'; +import { azureDevOpsApiRef } from '../api'; +import { RepoBuild } from '../api/types'; +import { useProjectRepoFromEntity } from './useProjectRepoFromEntity'; + +const DEFAULT_TOP: number = 10; + +export function useRepoBuilds(entity: Entity) { + const config = useApi(configApiRef); + const top = config.getOptionalNumber('azureDevOps.top') ?? DEFAULT_TOP; + const api = useApi(azureDevOpsApiRef); + const { project, repo } = useProjectRepoFromEntity(entity); + const { value, loading, error } = useAsync(() => { + return api.getRepoBuilds(project, repo, top); + }, [api, project, repo, entity]); + + return { + items: value as RepoBuild[], + loading, + error, + }; +} diff --git a/plugins/azure-devops/src/index.ts b/plugins/azure-devops/src/index.ts new file mode 100644 index 0000000000..b654aebab7 --- /dev/null +++ b/plugins/azure-devops/src/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { azureDevOpsPlugin, EntityAzureDevOpsContent } from './plugin'; +export { isAzureDevOpsAvailable } from './components/Router'; diff --git a/plugins/azure-devops/src/plugin.test.ts b/plugins/azure-devops/src/plugin.test.ts new file mode 100644 index 0000000000..f23639798f --- /dev/null +++ b/plugins/azure-devops/src/plugin.test.ts @@ -0,0 +1,22 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { azureDevOpsPlugin } from './plugin'; + +describe('azure-devops', () => { + it('should export plugin', () => { + expect(azureDevOpsPlugin).toBeDefined(); + }); +}); diff --git a/plugins/azure-devops/src/plugin.ts b/plugins/azure-devops/src/plugin.ts new file mode 100644 index 0000000000..f37fab6d62 --- /dev/null +++ b/plugins/azure-devops/src/plugin.ts @@ -0,0 +1,54 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { azureDevOpsApiRef } from './api/AzureDevOpsApi'; +import { AzureDevOpsClient } from './api/AzureDevOpsClient'; +import { + createApiFactory, + createPlugin, + createRoutableExtension, + createRouteRef, + discoveryApiRef, + identityApiRef, +} from '@backstage/core-plugin-api'; + +export const rootRouteRef = createRouteRef({ + path: '', + title: 'AzureDevOps', +}); + +export const azureDevOpsPlugin = createPlugin({ + id: 'azureDevOps', + apis: [ + createApiFactory({ + api: azureDevOpsApiRef, + deps: { discoveryApi: discoveryApiRef, identityApi: identityApiRef }, + factory: ({ discoveryApi, identityApi }) => + new AzureDevOpsClient({ discoveryApi, identityApi }), + }), + ], + routes: { + entityContent: rootRouteRef, + }, +}); + +export const EntityAzureDevOpsContent = azureDevOpsPlugin.provide( + createRoutableExtension({ + name: 'EntityAzureDevOpsContent', + component: () => import('./components/Router').then(m => m.Router), + mountPoint: rootRouteRef, + }), +); diff --git a/plugins/azure-devops/src/routes.ts b/plugins/azure-devops/src/routes.ts new file mode 100644 index 0000000000..81f4b48fda --- /dev/null +++ b/plugins/azure-devops/src/routes.ts @@ -0,0 +1,20 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { createRouteRef } from '@backstage/core-plugin-api'; + +export const azureDevOpsRouteRef = createRouteRef({ + title: 'azure-devops', +}); diff --git a/plugins/azure-devops/src/setupTests.ts b/plugins/azure-devops/src/setupTests.ts new file mode 100644 index 0000000000..fc6dbd98f8 --- /dev/null +++ b/plugins/azure-devops/src/setupTests.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import '@testing-library/jest-dom'; +import 'cross-fetch/polyfill'; From 02ef33e4e89ed02e5e0e00dfc52c5407ed3790b1 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Thu, 7 Oct 2021 06:59:24 -0500 Subject: [PATCH 02/10] Updated devDependencies causing CI to fail Signed-off-by: Andre Wanlin --- plugins/azure-devops/package.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/azure-devops/package.json b/plugins/azure-devops/package.json index fb59d5eb38..c823924c9d 100644 --- a/plugins/azure-devops/package.json +++ b/plugins/azure-devops/package.json @@ -42,15 +42,15 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.13", - "@backstage/core-app-api": "^0.1.14", - "@backstage/dev-utils": "^0.2.10", + "@backstage/cli": "^0.7.14", + "@backstage/core-app-api": "^0.1.15", + "@backstage/dev-utils": "^0.2.11", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", "@testing-library/user-event": "^13.1.8", - "@types/jest": "*", - "@types/node": "*", + "@types/jest": "^26.0.7", + "@types/node": "^14.14.32", "msw": "^0.29.0", "cross-fetch": "^3.0.6" }, From cba0352000e541473675bca099678795b076f5ab Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Thu, 7 Oct 2021 08:57:16 -0500 Subject: [PATCH 03/10] Fixed formatting of README Signed-off-by: Andre Wanlin --- plugins/azure-devops/README.md | 60 +++++++++++++++++----------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/plugins/azure-devops/README.md b/plugins/azure-devops/README.md index a596863bad..376a630873 100644 --- a/plugins/azure-devops/README.md +++ b/plugins/azure-devops/README.md @@ -31,43 +31,43 @@ Configuration Details: Here's how to get the backend up and running: -1. First we need to add the @backstage/plugin-azure-devops-backend package to your backend: +1. First we need to add the @backstage/plugin-azure-devops-backend package to your backend: - ```sh - # From the Backstage root directory - cd packages/backend - yarn add @backstage/plugin-azure-devops-backend - ``` + ```sh + # From the Backstage root directory + cd packages/backend + yarn add @backstage/plugin-azure-devops-backend + ``` -2. Then we will create a new file named `packages/backend/src/plugins/azuredevops.ts`, and add the - following to it: +2. Then we will create a new file named `packages/backend/src/plugins/azuredevops.ts`, and add the + following to it: - ```ts - import { createRouter } from '@backstage/plugin-azure-devops-backend'; - import { Router } from 'express'; - import type { PluginEnvironment } from '../types'; + ```ts + import { createRouter } from '@backstage/plugin-azure-devops-backend'; + import { Router } from 'express'; + import type { PluginEnvironment } from '../types'; - export default async function createPlugin({ - logger, - config, - }: PluginEnvironment): Promise { - return await createRouter({ logger, config }); - } - ``` + export default async function createPlugin({ + logger, + config, + }: PluginEnvironment): Promise { + return await createRouter({ logger, config }); + } + ``` -3. Next we wire this into the overall backend router, edit `packages/backend/src/index.ts`: +3. Next we wire this into the overall backend router, edit `packages/backend/src/index.ts`: - ```ts - import azureDevOps from './plugins/azuredevops'; - // ... - async function main() { - // ... - const azureDevOpsEnv = useHotMemoize(module, () => createEnv('azure-devops')); - apiRouter.use('/azure-devops', await azureDevOps(azureDevOpsEnv)); - ``` + ```ts + import azureDevOps from './plugins/azuredevops'; + // ... + async function main() { + // ... + const azureDevOpsEnv = useHotMemoize(module, () => createEnv('azure-devops')); + apiRouter.use('/azure-devops', await azureDevOps(azureDevOpsEnv)); + ``` -4. Now run `yarn start-backend` from the repo root -5. Finally open `http://localhost:7000/api/azure-devops/health` in a browser and it should return `{"status":"ok"}` +4. Now run `yarn start-backend` from the repo root +5. Finally open `http://localhost:7000/api/azure-devops/health` in a browser and it should return `{"status":"ok"}` ### Frontend From 48232f8507d07d3d6944f00cb47b3229527c514f Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Thu, 7 Oct 2021 19:55:26 -0500 Subject: [PATCH 04/10] Start of refactoring based on feedback Signed-off-by: Andre Wanlin --- .../app/src/components/catalog/EntityPage.tsx | 4 +-- plugins/azure-devops/README.md | 2 +- plugins/azure-devops/config.d.ts | 2 +- .../{doc => docs}/azure-devops-builds.png | Bin plugins/azure-devops/package.json | 10 +++---- .../azure-devops/src/api/AzureDevOpsClient.ts | 8 +++-- .../src/api/AzureDevOpsClientError.ts | 21 +++++++++++++ plugins/azure-devops/src/api/types.ts | 2 +- .../src/components/BuildTable/BuildTable.tsx | 28 +++++++++++------- .../EntityPageAzureDevOps.tsx | 2 +- plugins/azure-devops/src/constants.ts | 1 + .../src/hooks/useProjectRepoFromEntity.ts | 5 +++- .../azure-devops/src/hooks/useRepoBuilds.ts | 12 +++++--- plugins/azure-devops/src/index.ts | 2 +- plugins/azure-devops/src/plugin.ts | 13 +++----- 15 files changed, 72 insertions(+), 40 deletions(-) rename plugins/azure-devops/{doc => docs}/azure-devops-builds.png (100%) create mode 100644 plugins/azure-devops/src/api/AzureDevOpsClientError.ts diff --git a/packages/app/src/components/catalog/EntityPage.tsx b/packages/app/src/components/catalog/EntityPage.tsx index b79bd2c4aa..4147874e65 100644 --- a/packages/app/src/components/catalog/EntityPage.tsx +++ b/packages/app/src/components/catalog/EntityPage.tsx @@ -34,7 +34,7 @@ import { EntityProvidingComponentsCard, } from '@backstage/plugin-api-docs'; import { - EntityAzureDevOpsContent, + EntityAzurePipelinesContent, isAzureDevOpsAvailable, } from '@backstage/plugin-azure-devops'; import { EntityBadgesDialog } from '@backstage/plugin-badges'; @@ -188,7 +188,7 @@ export const cicdContent = ( - + diff --git a/plugins/azure-devops/README.md b/plugins/azure-devops/README.md index 376a630873..97a415d8d0 100644 --- a/plugins/azure-devops/README.md +++ b/plugins/azure-devops/README.md @@ -2,7 +2,7 @@ Website: [https://dev.azure.com/](https://dev.azure.com/) -![Azure DevOps Builds Example](./doc/azure-devops-builds.png) +![Azure DevOps Builds Example](./docs/azure-devops-builds.png) ## Setup diff --git a/plugins/azure-devops/config.d.ts b/plugins/azure-devops/config.d.ts index 827e64d5bd..62b1488e49 100644 --- a/plugins/azure-devops/config.d.ts +++ b/plugins/azure-devops/config.d.ts @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Backstage Authors + * Copyright 2021 The Backstage Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/plugins/azure-devops/doc/azure-devops-builds.png b/plugins/azure-devops/docs/azure-devops-builds.png similarity index 100% rename from plugins/azure-devops/doc/azure-devops-builds.png rename to plugins/azure-devops/docs/azure-devops-builds.png diff --git a/plugins/azure-devops/package.json b/plugins/azure-devops/package.json index c823924c9d..16e8f35991 100644 --- a/plugins/azure-devops/package.json +++ b/plugins/azure-devops/package.json @@ -27,8 +27,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.3", - "@backstage/core-components": "^0.6.0", - "@backstage/core-plugin-api": "^0.1.9", + "@backstage/core-components": "^0.6.1", + "@backstage/core-plugin-api": "^0.1.10", "@backstage/plugin-catalog-react": "^0.5.1", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", @@ -42,10 +42,10 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.14", - "@backstage/core-app-api": "^0.1.15", + "@backstage/cli": "^0.7.15", + "@backstage/core-app-api": "^0.1.16", "@backstage/dev-utils": "^0.2.11", - "@backstage/test-utils": "^0.1.17", + "@backstage/test-utils": "^0.1.18", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", "@testing-library/user-event": "^13.1.8", diff --git a/plugins/azure-devops/src/api/AzureDevOpsClient.ts b/plugins/azure-devops/src/api/AzureDevOpsClient.ts index c9e44109aa..32a563f429 100644 --- a/plugins/azure-devops/src/api/AzureDevOpsClient.ts +++ b/plugins/azure-devops/src/api/AzureDevOpsClient.ts @@ -17,6 +17,7 @@ import { AzureDevOpsApi } from './AzureDevOpsApi'; import { RepoBuild } from './types'; import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api'; +import { AzureDevOpsClientError } from './AzureDevOpsClientError'; export class AzureDevOpsClient implements AzureDevOpsApi { private readonly discoveryApi: DiscoveryApi; @@ -39,7 +40,9 @@ export class AzureDevOpsClient implements AzureDevOpsApi { } private async get(path: string): Promise { - const url = `${await this.discoveryApi.getBaseUrl('azure-devops')}${path}`; + const baseUrl = await this.discoveryApi.getBaseUrl('azure-devops'); + const url = `${baseUrl}/${path}`; + const idToken = await this.identityApi.getIdToken(); const response = await fetch(url, { headers: idToken ? { Authorization: `Bearer ${idToken}` } : {}, @@ -47,8 +50,7 @@ export class AzureDevOpsClient implements AzureDevOpsApi { if (!response.ok) { const payload = await response.text(); - const message = `Request failed with ${response.status} ${response.statusText}, ${payload}`; - throw new Error(message); + throw new AzureDevOpsClientError(response, payload); } return await response.json(); diff --git a/plugins/azure-devops/src/api/AzureDevOpsClientError.ts b/plugins/azure-devops/src/api/AzureDevOpsClientError.ts new file mode 100644 index 0000000000..f9a2f37b41 --- /dev/null +++ b/plugins/azure-devops/src/api/AzureDevOpsClientError.ts @@ -0,0 +1,21 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export class AzureDevOpsClientError extends Error { + public constructor({ status, statusText }: Response, payload: string) { + super(`Request failed with ${status} ${statusText}, ${payload}`); + } +} diff --git a/plugins/azure-devops/src/api/types.ts b/plugins/azure-devops/src/api/types.ts index 35d4e38ae1..b3562f76c6 100644 --- a/plugins/azure-devops/src/api/types.ts +++ b/plugins/azure-devops/src/api/types.ts @@ -22,7 +22,7 @@ import { export type RepoBuild = { id?: number; title: string; - link: string; + link?: string; status?: BuildStatus; result?: BuildResult; queueTime?: Date; diff --git a/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx b/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx index 26f365c5e9..e853662fbf 100644 --- a/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx +++ b/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx @@ -32,17 +32,19 @@ import { BuildStatus, } from 'azure-devops-node-api/interfaces/BuildInterfaces'; -const getBuildResultComponent = (result: number | undefined = 0) => { +const getBuildResultComponent = ( + result: number | undefined = BuildResult.None, +) => { switch (result) { - case 0: // None + case BuildResult.None: return ; - case 2: // Succeeded + case BuildResult.Succeeded: return ; - case 4: // PartiallySucceeded + case BuildResult.PartiallySucceeded: return ; - case 8: // Failed + case BuildResult.Failed: return ; - case 32: // Canceled + case BuildResult.Canceled: return ; default: return ; @@ -75,7 +77,9 @@ const columns: TableColumn[] = [ render: (row: Partial) => ( - {BuildStatus[row.status || 0]} + + {BuildStatus[row.status || BuildStatus.None]} + ), }, @@ -86,7 +90,9 @@ const columns: TableColumn[] = [ {getBuildResultComponent(row.result)} - {BuildResult[row.result || 0]} + + {BuildResult[row.result || BuildResult.None]} + ), }, @@ -98,7 +104,7 @@ const columns: TableColumn[] = [ ]; type Props = { - items: RepoBuild[]; + items?: RepoBuild[]; loading: boolean; error?: any; }; @@ -125,8 +131,8 @@ export const BuildTable = ({ items, loading, error }: Props) => { pageSize: 5, showEmptyDataSourceMessage: !loading, }} - title={`Builds (${(items && items.length) || 0})`} - data={items} + title={`Builds (${items ? items.length : 0})`} + data={items || []} /> ); }; diff --git a/plugins/azure-devops/src/components/EntityPageAzureDevOps/EntityPageAzureDevOps.tsx b/plugins/azure-devops/src/components/EntityPageAzureDevOps/EntityPageAzureDevOps.tsx index fbeac53569..8e102e647d 100644 --- a/plugins/azure-devops/src/components/EntityPageAzureDevOps/EntityPageAzureDevOps.tsx +++ b/plugins/azure-devops/src/components/EntityPageAzureDevOps/EntityPageAzureDevOps.tsx @@ -29,5 +29,5 @@ export const EntityPageAzureDevOps = (_props: Props) => { const { entity } = useEntity(); const { items, loading, error } = useRepoBuilds(entity); - return ; + return ; }; diff --git a/plugins/azure-devops/src/constants.ts b/plugins/azure-devops/src/constants.ts index 6abc6449e9..d6e67ff7ed 100644 --- a/plugins/azure-devops/src/constants.ts +++ b/plugins/azure-devops/src/constants.ts @@ -15,3 +15,4 @@ */ export const AZURE_DEVOPS_ANNOTATION = 'dev.azure.com/project-repo'; +export const AZURE_DEVOPS_DEFAULT_TOP: number = 10; diff --git a/plugins/azure-devops/src/hooks/useProjectRepoFromEntity.ts b/plugins/azure-devops/src/hooks/useProjectRepoFromEntity.ts index 721fa52781..dfbee81d62 100644 --- a/plugins/azure-devops/src/hooks/useProjectRepoFromEntity.ts +++ b/plugins/azure-devops/src/hooks/useProjectRepoFromEntity.ts @@ -17,7 +17,10 @@ import { Entity } from '@backstage/catalog-model'; import { AZURE_DEVOPS_ANNOTATION } from '../constants'; -export function useProjectRepoFromEntity(entity: Entity) { +export function useProjectRepoFromEntity(entity: Entity): { + project: string; + repo: string; +} { const [project, repo] = ( entity.metadata.annotations?.[AZURE_DEVOPS_ANNOTATION] ?? '' ).split('/'); diff --git a/plugins/azure-devops/src/hooks/useRepoBuilds.ts b/plugins/azure-devops/src/hooks/useRepoBuilds.ts index e6d2964770..1e68490ea6 100644 --- a/plugins/azure-devops/src/hooks/useRepoBuilds.ts +++ b/plugins/azure-devops/src/hooks/useRepoBuilds.ts @@ -20,12 +20,16 @@ import { useApi, configApiRef } from '@backstage/core-plugin-api'; import { azureDevOpsApiRef } from '../api'; import { RepoBuild } from '../api/types'; import { useProjectRepoFromEntity } from './useProjectRepoFromEntity'; +import { AZURE_DEVOPS_DEFAULT_TOP } from '../constants'; -const DEFAULT_TOP: number = 10; - -export function useRepoBuilds(entity: Entity) { +export function useRepoBuilds(entity: Entity): { + items: RepoBuild[]; + loading: boolean; + error: any; +} { const config = useApi(configApiRef); - const top = config.getOptionalNumber('azureDevOps.top') ?? DEFAULT_TOP; + const top = + config.getOptionalNumber('azureDevOps.top') ?? AZURE_DEVOPS_DEFAULT_TOP; const api = useApi(azureDevOpsApiRef); const { project, repo } = useProjectRepoFromEntity(entity); const { value, loading, error } = useAsync(() => { diff --git a/plugins/azure-devops/src/index.ts b/plugins/azure-devops/src/index.ts index b654aebab7..9a90d6ed6a 100644 --- a/plugins/azure-devops/src/index.ts +++ b/plugins/azure-devops/src/index.ts @@ -13,5 +13,5 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { azureDevOpsPlugin, EntityAzureDevOpsContent } from './plugin'; +export { azureDevOpsPlugin, EntityAzurePipelinesContent } from './plugin'; export { isAzureDevOpsAvailable } from './components/Router'; diff --git a/plugins/azure-devops/src/plugin.ts b/plugins/azure-devops/src/plugin.ts index f37fab6d62..9ec5ebbb09 100644 --- a/plugins/azure-devops/src/plugin.ts +++ b/plugins/azure-devops/src/plugin.ts @@ -20,15 +20,10 @@ import { createApiFactory, createPlugin, createRoutableExtension, - createRouteRef, discoveryApiRef, identityApiRef, } from '@backstage/core-plugin-api'; - -export const rootRouteRef = createRouteRef({ - path: '', - title: 'AzureDevOps', -}); +import { azureDevOpsRouteRef } from './routes'; export const azureDevOpsPlugin = createPlugin({ id: 'azureDevOps', @@ -41,14 +36,14 @@ export const azureDevOpsPlugin = createPlugin({ }), ], routes: { - entityContent: rootRouteRef, + entityContent: azureDevOpsRouteRef, }, }); -export const EntityAzureDevOpsContent = azureDevOpsPlugin.provide( +export const EntityAzurePipelinesContent = azureDevOpsPlugin.provide( createRoutableExtension({ name: 'EntityAzureDevOpsContent', component: () => import('./components/Router').then(m => m.Router), - mountPoint: rootRouteRef, + mountPoint: azureDevOpsRouteRef, }), ); From e5070b3f2ba649e536c73bd2cc3cf445dbad8946 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Thu, 7 Oct 2021 20:31:31 -0500 Subject: [PATCH 05/10] Regenerated API Report Signed-off-by: Andre Wanlin --- plugins/azure-devops/api-report.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/azure-devops/api-report.md b/plugins/azure-devops/api-report.md index 11de164276..bc39fd0ce4 100644 --- a/plugins/azure-devops/api-report.md +++ b/plugins/azure-devops/api-report.md @@ -19,10 +19,10 @@ export const azureDevOpsPlugin: BackstagePlugin< {} >; -// Warning: (ae-missing-release-tag) "EntityAzureDevOpsContent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "EntityAzurePipelinesContent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const EntityAzureDevOpsContent: (_props: { +export const EntityAzurePipelinesContent: (_props: { entity?: Entity | undefined; }) => JSX.Element; From e67321d20d4eb0b04c6ee602a070da671bb43c7c Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Fri, 8 Oct 2021 08:20:49 -0500 Subject: [PATCH 06/10] Further refactoring based on feedback Signed-off-by: Andre Wanlin --- plugins/azure-devops/README.md | 6 +++--- plugins/azure-devops/package.json | 2 +- plugins/azure-devops/src/api/AzureDevOpsClient.ts | 8 ++++---- .../src/components/BuildTable/BuildTable.tsx | 9 ++++++--- .../EntityPageAzurePipelines.tsx} | 2 +- .../index.ts | 2 +- plugins/azure-devops/src/components/Router.tsx | 4 ++-- plugins/azure-devops/src/plugin.ts | 2 +- 8 files changed, 19 insertions(+), 16 deletions(-) rename plugins/azure-devops/src/components/{EntityPageAzureDevOps/EntityPageAzureDevOps.tsx => EntityPageAzurePipelines/EntityPageAzurePipelines.tsx} (94%) rename plugins/azure-devops/src/components/{EntityPageAzureDevOps => EntityPageAzurePipelines}/index.ts (89%) diff --git a/plugins/azure-devops/README.md b/plugins/azure-devops/README.md index 97a415d8d0..55d5ea5f91 100644 --- a/plugins/azure-devops/README.md +++ b/plugins/azure-devops/README.md @@ -81,12 +81,12 @@ To get the frontend working you'll need to do the following two steps: yarn add @backstage/plugin-azure-devops ``` -2. Second we need to add the `EntityAzureDevOpsContent` extension to the entity page in your app: +2. Second we need to add the `EntityAzurePipelinesContent` extension to the entity page in your app: ```tsx // In packages/app/src/components/catalog/EntityPage.tsx import { - EntityAzureDevOpsContent, + EntityAzurePipelinesContent, isAzureDevOpsAvailable, } from '@backstage/plugin-azure-devops'; @@ -95,7 +95,7 @@ const cicdContent = ( // ... - + // ... diff --git a/plugins/azure-devops/package.json b/plugins/azure-devops/package.json index 16e8f35991..16008090b7 100644 --- a/plugins/azure-devops/package.json +++ b/plugins/azure-devops/package.json @@ -35,7 +35,7 @@ "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", "azure-devops-node-api": "^11.0.1", - "moment": "^2.29.1", + "luxon": "^2.0.2", "react": "^16.13.1", "react-dom": "^16.13.1", "react-router": "6.0.0-beta.0", diff --git a/plugins/azure-devops/src/api/AzureDevOpsClient.ts b/plugins/azure-devops/src/api/AzureDevOpsClient.ts index 32a563f429..d82dfbe09e 100644 --- a/plugins/azure-devops/src/api/AzureDevOpsClient.ts +++ b/plugins/azure-devops/src/api/AzureDevOpsClient.ts @@ -36,15 +36,15 @@ export class AzureDevOpsClient implements AzureDevOpsApi { repoName: string, top: number, ): Promise { - return await this.get(`/repo-builds/${projectName}/${repoName}?top=${top}`); + return await this.get(`repo-builds/${projectName}/${repoName}?top=${top}`); } private async get(path: string): Promise { - const baseUrl = await this.discoveryApi.getBaseUrl('azure-devops'); - const url = `${baseUrl}/${path}`; + const baseUrl = `${await this.discoveryApi.getBaseUrl('azure-devops')}/`; + const url = new URL(path, baseUrl); const idToken = await this.identityApi.getIdToken(); - const response = await fetch(url, { + const response = await fetch(url.toString(), { headers: idToken ? { Authorization: `Bearer ${idToken}` } : {}, }); diff --git a/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx b/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx index e853662fbf..7c3e09c66c 100644 --- a/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx +++ b/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx @@ -15,7 +15,7 @@ */ import React from 'react'; -import moment from 'moment'; +import { DateTime } from 'luxon'; import { Table, TableColumn, @@ -56,7 +56,7 @@ const columns: TableColumn[] = [ title: 'ID', field: 'id', highlight: false, - width: '80px', + width: '100px', }, { title: 'Build', @@ -99,7 +99,10 @@ const columns: TableColumn[] = [ { title: 'Date', field: 'queueTime', - render: (row: Partial) => moment(row.queueTime).fromNow(), + render: (row: Partial) => + DateTime.fromISO( + row.queueTime ? row.queueTime.toString() : new Date().toString(), + ).toRelative(), }, ]; diff --git a/plugins/azure-devops/src/components/EntityPageAzureDevOps/EntityPageAzureDevOps.tsx b/plugins/azure-devops/src/components/EntityPageAzurePipelines/EntityPageAzurePipelines.tsx similarity index 94% rename from plugins/azure-devops/src/components/EntityPageAzureDevOps/EntityPageAzureDevOps.tsx rename to plugins/azure-devops/src/components/EntityPageAzurePipelines/EntityPageAzurePipelines.tsx index 8e102e647d..5d53df928c 100644 --- a/plugins/azure-devops/src/components/EntityPageAzureDevOps/EntityPageAzureDevOps.tsx +++ b/plugins/azure-devops/src/components/EntityPageAzurePipelines/EntityPageAzurePipelines.tsx @@ -25,7 +25,7 @@ type Props = { entity?: Entity; }; -export const EntityPageAzureDevOps = (_props: Props) => { +export const EntityPageAzurePipelines = (_props: Props) => { const { entity } = useEntity(); const { items, loading, error } = useRepoBuilds(entity); diff --git a/plugins/azure-devops/src/components/EntityPageAzureDevOps/index.ts b/plugins/azure-devops/src/components/EntityPageAzurePipelines/index.ts similarity index 89% rename from plugins/azure-devops/src/components/EntityPageAzureDevOps/index.ts rename to plugins/azure-devops/src/components/EntityPageAzurePipelines/index.ts index 89ee4f199b..c907c61b2c 100644 --- a/plugins/azure-devops/src/components/EntityPageAzureDevOps/index.ts +++ b/plugins/azure-devops/src/components/EntityPageAzurePipelines/index.ts @@ -14,4 +14,4 @@ * limitations under the License. */ -export { EntityPageAzureDevOps } from './EntityPageAzureDevOps'; +export { EntityPageAzurePipelines } from './EntityPageAzurePipelines'; diff --git a/plugins/azure-devops/src/components/Router.tsx b/plugins/azure-devops/src/components/Router.tsx index 74cf0439f8..81b6d89a25 100644 --- a/plugins/azure-devops/src/components/Router.tsx +++ b/plugins/azure-devops/src/components/Router.tsx @@ -16,7 +16,7 @@ import React from 'react'; import { Routes, Route } from 'react-router'; import { azureDevOpsRouteRef } from '../routes'; -import { EntityPageAzureDevOps } from './EntityPageAzureDevOps'; +import { EntityPageAzurePipelines } from './EntityPageAzurePipelines'; import { AZURE_DEVOPS_ANNOTATION } from '../constants'; import { Entity } from '@backstage/catalog-model'; import { useEntity } from '@backstage/plugin-catalog-react'; @@ -41,7 +41,7 @@ export const Router = (_props: Props) => { } + element={} /> ); diff --git a/plugins/azure-devops/src/plugin.ts b/plugins/azure-devops/src/plugin.ts index 9ec5ebbb09..1cf6e680d0 100644 --- a/plugins/azure-devops/src/plugin.ts +++ b/plugins/azure-devops/src/plugin.ts @@ -42,7 +42,7 @@ export const azureDevOpsPlugin = createPlugin({ export const EntityAzurePipelinesContent = azureDevOpsPlugin.provide( createRoutableExtension({ - name: 'EntityAzureDevOpsContent', + name: 'EntityAzurePipelinesContent', component: () => import('./components/Router').then(m => m.Router), mountPoint: azureDevOpsRouteRef, }), From 94acc6211641f92da6963d89dbfd1fac71973083 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Fri, 8 Oct 2021 10:06:05 -0500 Subject: [PATCH 07/10] Another set of feedback improvements Signed-off-by: Andre Wanlin --- app-config.yaml | 3 +- packages/backend/src/index.ts | 2 +- .../{azuredevops.ts => azure-devops.ts} | 0 plugins/azure-devops/README.md | 39 ++++++++++--------- plugins/azure-devops/config.d.ts | 12 +++--- .../src/components/BuildTable/BuildTable.tsx | 9 ++++- .../src/hooks/useProjectRepoFromEntity.ts | 19 +++++++++ .../azure-devops/src/hooks/useRepoBuilds.ts | 3 +- 8 files changed, 58 insertions(+), 29 deletions(-) rename packages/backend/src/plugins/{azuredevops.ts => azure-devops.ts} (100%) diff --git a/app-config.yaml b/app-config.yaml index b92595df7b..645221538b 100644 --- a/app-config.yaml +++ b/app-config.yaml @@ -436,4 +436,5 @@ azureDevOps: host: dev.azure.com token: my-token organization: my-company - top: 25 + azurePipelines: + top: 25 diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index f25ec5a14e..b6c148dfba 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -38,7 +38,7 @@ import { Config } from '@backstage/config'; import healthcheck from './plugins/healthcheck'; import { metricsInit, metricsHandler } from './metrics'; import auth from './plugins/auth'; -import azureDevOps from './plugins/azuredevops'; +import azureDevOps from './plugins/azure-devops'; import catalog from './plugins/catalog'; import codeCoverage from './plugins/codecoverage'; import kubernetes from './plugins/kubernetes'; diff --git a/packages/backend/src/plugins/azuredevops.ts b/packages/backend/src/plugins/azure-devops.ts similarity index 100% rename from packages/backend/src/plugins/azuredevops.ts rename to packages/backend/src/plugins/azure-devops.ts diff --git a/plugins/azure-devops/README.md b/plugins/azure-devops/README.md index 55d5ea5f91..d2ab1b6c6f 100644 --- a/plugins/azure-devops/README.md +++ b/plugins/azure-devops/README.md @@ -17,7 +17,8 @@ azureDevOps: host: dev.azure.com token: ${AZURE_TOKEN} organization: my-company - top: 50 + azurePipelines: + top: 50 ``` Configuration Details: @@ -25,7 +26,7 @@ Configuration Details: - `host` and `token` can be the same as the ones used for the `integration` section - `AZURE_TOKEN` environment variable must be set to a [Personal Access Token](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=preview-page) with read access to both Code and Build - `organization` is your Azure DevOps Organization name or for Azure DevOps Server (on-premise) this will be your Collection name -- `top` is strictly used by the frontend to limit the number of items returned, currently only used for Builds +- `top` is strictly used by the frontend to limit the number of items returned, if not provided it defaults to 10. Currently only used for Builds ### Backend @@ -39,7 +40,7 @@ Here's how to get the backend up and running: yarn add @backstage/plugin-azure-devops-backend ``` -2. Then we will create a new file named `packages/backend/src/plugins/azuredevops.ts`, and add the +2. Then we will create a new file named `packages/backend/src/plugins/azure-devops.ts`, and add the following to it: ```ts @@ -83,23 +84,23 @@ To get the frontend working you'll need to do the following two steps: 2. Second we need to add the `EntityAzurePipelinesContent` extension to the entity page in your app: -```tsx -// In packages/app/src/components/catalog/EntityPage.tsx -import { - EntityAzurePipelinesContent, - isAzureDevOpsAvailable, -} from '@backstage/plugin-azure-devops'; + ```tsx + // In packages/app/src/components/catalog/EntityPage.tsx + import { + EntityAzurePipelinesContent, + isAzureDevOpsAvailable, + } from '@backstage/plugin-azure-devops'; -// For example in the CI/CD section -const cicdContent = ( - - // ... - - - - // ... - -``` + // For example in the CI/CD section + const cicdContent = ( + + // ... + + + + // ... + + ``` ### Entity Annotation diff --git a/plugins/azure-devops/config.d.ts b/plugins/azure-devops/config.d.ts index 62b1488e49..bbd42c55a1 100644 --- a/plugins/azure-devops/config.d.ts +++ b/plugins/azure-devops/config.d.ts @@ -17,10 +17,12 @@ export interface Config { /** Configuration options for the azure-devops-backend plugin */ azureDevOps: { - /** - * The max number of items to return - applies to builds - * @visibility frontend - */ - top: number; + azurePipelines: { + /** + * The max number of items to return - applies to builds + * @visibility frontend + */ + top: number; + }; }; } diff --git a/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx b/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx index 7c3e09c66c..b3d239d914 100644 --- a/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx +++ b/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx @@ -56,11 +56,12 @@ const columns: TableColumn[] = [ title: 'ID', field: 'id', highlight: false, - width: '100px', + width: 'auto', }, { title: 'Build', field: 'title', + width: 'auto', render: (row: Partial) => ( {row.title} @@ -70,10 +71,12 @@ const columns: TableColumn[] = [ { title: 'Source', field: 'source', + width: 'auto', }, { title: 'Status', field: 'status', + width: 'auto', render: (row: Partial) => ( @@ -86,6 +89,7 @@ const columns: TableColumn[] = [ { title: 'Result', field: 'result', + width: 'auto', render: (row: Partial) => ( {getBuildResultComponent(row.result)} @@ -97,8 +101,9 @@ const columns: TableColumn[] = [ ), }, { - title: 'Date', + title: 'Age', field: 'queueTime', + width: 'auto', render: (row: Partial) => DateTime.fromISO( row.queueTime ? row.queueTime.toString() : new Date().toString(), diff --git a/plugins/azure-devops/src/hooks/useProjectRepoFromEntity.ts b/plugins/azure-devops/src/hooks/useProjectRepoFromEntity.ts index dfbee81d62..418badc630 100644 --- a/plugins/azure-devops/src/hooks/useProjectRepoFromEntity.ts +++ b/plugins/azure-devops/src/hooks/useProjectRepoFromEntity.ts @@ -24,5 +24,24 @@ export function useProjectRepoFromEntity(entity: Entity): { const [project, repo] = ( entity.metadata.annotations?.[AZURE_DEVOPS_ANNOTATION] ?? '' ).split('/'); + + if (!project && !repo) { + throw new Error( + 'Value for annotation dev.azure.com/project-repo was not in the correct format: /', + ); + } + + if (!project) { + throw new Error( + 'Project Name for annotation dev.azure.com/project-repo was not found; expected format is: /', + ); + } + + if (!repo) { + throw new Error( + 'Repo Name for annotation dev.azure.com/project-repo was not found; expected format is: /', + ); + } + return { project, repo }; } diff --git a/plugins/azure-devops/src/hooks/useRepoBuilds.ts b/plugins/azure-devops/src/hooks/useRepoBuilds.ts index 1e68490ea6..0bae4b334b 100644 --- a/plugins/azure-devops/src/hooks/useRepoBuilds.ts +++ b/plugins/azure-devops/src/hooks/useRepoBuilds.ts @@ -29,7 +29,8 @@ export function useRepoBuilds(entity: Entity): { } { const config = useApi(configApiRef); const top = - config.getOptionalNumber('azureDevOps.top') ?? AZURE_DEVOPS_DEFAULT_TOP; + config.getOptionalNumber('azureDevOps.azurePipelines.top') ?? + AZURE_DEVOPS_DEFAULT_TOP; const api = useApi(azureDevOpsApiRef); const { project, repo } = useProjectRepoFromEntity(entity); const { value, loading, error } = useAsync(() => { From 619257ff83f33ec6caf7ce71e44cfd0a3ca65790 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Fri, 8 Oct 2021 11:11:10 -0500 Subject: [PATCH 08/10] Applied suggested async and await changes Signed-off-by: Andre Wanlin --- packages/backend/src/plugins/azure-devops.ts | 4 ++-- plugins/azure-devops/README.md | 4 ++-- plugins/azure-devops/src/api/AzureDevOpsClient.ts | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/backend/src/plugins/azure-devops.ts b/packages/backend/src/plugins/azure-devops.ts index e11a21ba2e..4120e655ed 100644 --- a/packages/backend/src/plugins/azure-devops.ts +++ b/packages/backend/src/plugins/azure-devops.ts @@ -18,9 +18,9 @@ import { createRouter } from '@backstage/plugin-azure-devops-backend'; import { Router } from 'express'; import type { PluginEnvironment } from '../types'; -export default async function createPlugin({ +export default function createPlugin({ logger, config, }: PluginEnvironment): Promise { - return await createRouter({ logger, config }); + return createRouter({ logger, config }); } diff --git a/plugins/azure-devops/README.md b/plugins/azure-devops/README.md index d2ab1b6c6f..8b25800bb7 100644 --- a/plugins/azure-devops/README.md +++ b/plugins/azure-devops/README.md @@ -48,11 +48,11 @@ Here's how to get the backend up and running: import { Router } from 'express'; import type { PluginEnvironment } from '../types'; - export default async function createPlugin({ + export default function createPlugin({ logger, config, }: PluginEnvironment): Promise { - return await createRouter({ logger, config }); + return createRouter({ logger, config }); } ``` diff --git a/plugins/azure-devops/src/api/AzureDevOpsClient.ts b/plugins/azure-devops/src/api/AzureDevOpsClient.ts index d82dfbe09e..02cac3b9de 100644 --- a/plugins/azure-devops/src/api/AzureDevOpsClient.ts +++ b/plugins/azure-devops/src/api/AzureDevOpsClient.ts @@ -31,12 +31,12 @@ export class AzureDevOpsClient implements AzureDevOpsApi { this.identityApi = options.identityApi; } - async getRepoBuilds( + getRepoBuilds( projectName: string, repoName: string, top: number, ): Promise { - return await this.get(`repo-builds/${projectName}/${repoName}?top=${top}`); + return this.get(`repo-builds/${projectName}/${repoName}?top=${top}`); } private async get(path: string): Promise { @@ -53,6 +53,6 @@ export class AzureDevOpsClient implements AzureDevOpsApi { throw new AzureDevOpsClientError(response, payload); } - return await response.json(); + return response.json() as Promise; } } From ff09af35cea4593c8d361ea2d53f36d9f4aed22e Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Fri, 8 Oct 2021 14:03:16 -0500 Subject: [PATCH 09/10] Combined the Status and Result columns into a single State Signed-off-by: Andre Wanlin --- .../src/components/BuildTable/BuildTable.tsx | 100 +++++++++++++----- 1 file changed, 72 insertions(+), 28 deletions(-) diff --git a/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx b/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx index b3d239d914..a6cfb9bf81 100644 --- a/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx +++ b/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx @@ -23,6 +23,8 @@ import { StatusOK, StatusWarning, StatusAborted, + StatusRunning, + StatusPending, } from '@backstage/core-components'; import { Link, Box, Typography } from '@material-ui/core'; import Alert from '@material-ui/lab/Alert'; @@ -32,22 +34,80 @@ import { BuildStatus, } from 'azure-devops-node-api/interfaces/BuildInterfaces'; -const getBuildResultComponent = ( - result: number | undefined = BuildResult.None, -) => { +const getBuildResultComponent = (result: number | undefined) => { switch (result) { - case BuildResult.None: - return ; case BuildResult.Succeeded: - return ; + return ( + + Succeeded{' '} + + ); case BuildResult.PartiallySucceeded: - return ; + return ( + + Partially Succeeded{' '} + + ); case BuildResult.Failed: - return ; + return ( + + Failed{' '} + + ); case BuildResult.Canceled: - return ; + return ( + + Canceled{' '} + + ); + case BuildResult.None: default: - return ; + return ( + + Unknown + + ); + } +}; + +const getBuildStateComponent = ( + status: number | undefined, + result: number | undefined, +) => { + switch (status) { + case BuildStatus.InProgress: + return ( + + In Progress + + ); + case BuildStatus.Completed: + return getBuildResultComponent(result); + case BuildStatus.Cancelling: + return ( + + Cancelling + + ); + case BuildStatus.Postponed: + return ( + + Postponed + + ); + case BuildStatus.NotStarted: + return ( + + Not Started + + ); + case BuildStatus.None: + default: + return ( + + Unknown + + ); } }; @@ -74,28 +134,12 @@ const columns: TableColumn[] = [ width: 'auto', }, { - title: 'Status', - field: 'status', + title: 'State', width: 'auto', render: (row: Partial) => ( - - {BuildStatus[row.status || BuildStatus.None]} - - - ), - }, - { - title: 'Result', - field: 'result', - width: 'auto', - render: (row: Partial) => ( - - {getBuildResultComponent(row.result)} - - - {BuildResult[row.result || BuildResult.None]} + {getBuildStateComponent(row.status, row.result)} ), From 56bd5372563a863c824e25b3515475edeb7bcdc5 Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Mon, 11 Oct 2021 21:55:42 +0200 Subject: [PATCH 10/10] [Search] add search api how to guide + search bar custom placeholder (#7535) --- .changeset/search-gentle-chairs-grab.md | 5 ++ docs/features/search/how-to-guides.md | 46 +++++++++++++++++++ microsite/sidebars.json | 3 +- mkdocs.yml | 1 + plugins/search/api-report.md | 8 +++- .../SearchBar/SearchBar.stories.tsx | 17 +++++++ .../components/SearchBar/SearchBar.test.tsx | 20 ++++++++ .../src/components/SearchBar/SearchBar.tsx | 8 +++- 8 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 .changeset/search-gentle-chairs-grab.md create mode 100644 docs/features/search/how-to-guides.md diff --git a/.changeset/search-gentle-chairs-grab.md b/.changeset/search-gentle-chairs-grab.md new file mode 100644 index 0000000000..f3e2cf3cec --- /dev/null +++ b/.changeset/search-gentle-chairs-grab.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-search': patch +--- + +SearchBar component to accept optional placeholder prop diff --git a/docs/features/search/how-to-guides.md b/docs/features/search/how-to-guides.md new file mode 100644 index 0000000000..b6ea6ae364 --- /dev/null +++ b/docs/features/search/how-to-guides.md @@ -0,0 +1,46 @@ +--- +id: how-to-guides +title: Search "HOW TO" guides +sidebar_label: "HOW TO" guides +description: Search "HOW TO" guides +--- + +## How to implement your own Search API + +The Search plugin provides implementation of one primary API by default: the +[SearchApi](https://github.com/backstage/backstage/blob/db2666b980853c281b8fe77905d7639c5d255f13/plugins/search/src/apis.ts#L35), +which is responsible for talking to the search-backend to query search results. + +There may be occasions where you need to implement this API yourself, to +customize it to your own needs - for example if you have your own search backend +that you want to talk to. The purpose of this guide is to walk you through how +to do that in two steps. + +1. Implement the `SearchApi` + [interface](https://github.com/backstage/backstage/blob/db2666b980853c281b8fe77905d7639c5d255f13/plugins/search/src/apis.ts#L31) + according to your needs. + +```typescript +export class SearchClient implements SearchApi { + // your implementation +} +``` + +2. Override the API ref `searchApiRef` with your new implemented API in the + `App.tsx` using `ApiFactories`. + [Read more about App APIs](https://backstage.io/docs/api/utility-apis#app-apis). + +```typescript +const app = createApp({ + apis: [ + // SearchApi + createApiFactory({ + api: searchApiRef, + deps: { discovery: discoveryApiRef }, + factory({ discovery }) { + return new SearchClient({ discoveryApi: discovery }); + }, + }), + ], +}); +``` diff --git a/microsite/sidebars.json b/microsite/sidebars.json index 8b8b359fdc..bb9fd5783a 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -90,7 +90,8 @@ "features/search/getting-started", "features/search/concepts", "features/search/architecture", - "features/search/search-engines" + "features/search/search-engines", + "features/search/how-to-guides" ] }, { diff --git a/mkdocs.yml b/mkdocs.yml index b668ffdb15..7376893586 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -68,6 +68,7 @@ nav: - Concepts: 'features/search/concepts.md' - Search Architecture: 'features/search/architecture.md' - Search Engines: 'features/search/search-engines.md' + - HOW TO guides: 'features/search/how-to-guides.md' - TechDocs: - Overview: 'features/techdocs/README.md' - Getting Started: 'features/techdocs/getting-started.md' diff --git a/plugins/search/api-report.md b/plugins/search/api-report.md index 169972d02d..b29149805c 100644 --- a/plugins/search/api-report.md +++ b/plugins/search/api-report.md @@ -79,7 +79,11 @@ export const searchApiRef: ApiRef; // Warning: (ae-missing-release-tag) "SearchBar" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const SearchBar: ({ className, debounceTime }: Props) => JSX.Element; +export const SearchBar: ({ + className, + debounceTime, + placeholder, +}: Props) => JSX.Element; // Warning: (ae-missing-release-tag) "SearchBarNext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -87,9 +91,11 @@ export const SearchBar: ({ className, debounceTime }: Props) => JSX.Element; export const SearchBarNext: ({ className, debounceTime, + placeholder, }: { className?: string | undefined; debounceTime?: number | undefined; + placeholder?: string | undefined; }) => JSX.Element; // Warning: (ae-missing-release-tag) "SearchContextProvider" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) diff --git a/plugins/search/src/components/SearchBar/SearchBar.stories.tsx b/plugins/search/src/components/SearchBar/SearchBar.stories.tsx index fa2ba0d94e..2c990e512c 100644 --- a/plugins/search/src/components/SearchBar/SearchBar.stories.tsx +++ b/plugins/search/src/components/SearchBar/SearchBar.stories.tsx @@ -45,3 +45,20 @@ export const Default = () => { ); }; + +export const CustomPlaceholder = () => { + return ( + + {/* @ts-ignore (defaultValue requires more than what is used here) */} + + + + + + + + + + + ); +}; diff --git a/plugins/search/src/components/SearchBar/SearchBar.test.tsx b/plugins/search/src/components/SearchBar/SearchBar.test.tsx index de8ea9a5a7..3a11daa9fa 100644 --- a/plugins/search/src/components/SearchBar/SearchBar.test.tsx +++ b/plugins/search/src/components/SearchBar/SearchBar.test.tsx @@ -65,6 +65,26 @@ describe('SearchBar', () => { await waitFor(() => { expect(screen.getByRole('textbox', { name })).toBeInTheDocument(); + expect( + screen.getByPlaceholderText('Search in Mock title'), + ).toBeInTheDocument(); + }); + }); + + it('Renders with custom placeholder', async () => { + render( + + + + + , + , + ); + + await waitFor(() => { + expect( + screen.getByPlaceholderText('This is a custom placeholder'), + ).toBeInTheDocument(); }); }); diff --git a/plugins/search/src/components/SearchBar/SearchBar.tsx b/plugins/search/src/components/SearchBar/SearchBar.tsx index 214e22520c..53802899eb 100644 --- a/plugins/search/src/components/SearchBar/SearchBar.tsx +++ b/plugins/search/src/components/SearchBar/SearchBar.tsx @@ -89,9 +89,14 @@ export const SearchBarBase = ({ type Props = { className?: string; debounceTime?: number; + placeholder?: string; }; -export const SearchBar = ({ className, debounceTime = 0 }: Props) => { +export const SearchBar = ({ + className, + debounceTime = 0, + placeholder, +}: Props) => { const { term, setTerm } = useSearch(); const [value, setValue] = useState(term); @@ -113,6 +118,7 @@ export const SearchBar = ({ className, debounceTime = 0 }: Props) => { value={value} onChange={handleQuery} onClear={handleClear} + placeholder={placeholder} /> ); };