diff --git a/plugins/octopus-deploy/src/api/index.ts b/plugins/octopus-deploy/src/api/index.ts index b066f700db..f89e429f64 100644 --- a/plugins/octopus-deploy/src/api/index.ts +++ b/plugins/octopus-deploy/src/api/index.ts @@ -1,88 +1,113 @@ -import { createApiRef, DiscoveryApi, IdentityApi } from "@backstage/core-plugin-api"; +/* + * Copyright 2023 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 { + createApiRef, + DiscoveryApi, + IdentityApi, +} from '@backstage/core-plugin-api'; export type OctopusProgression = { - Environments: OctopusEnvironment[]; - Releases: OctopusReleaseProgression[]; -} + Environments: OctopusEnvironment[]; + Releases: OctopusReleaseProgression[]; +}; export type OctopusEnvironment = { - Id: string, - Name: string -} + Id: string; + Name: string; +}; export type OctopusReleaseProgression = { - Release: OctopusRelease - Deployments: { [key: string]: OctopusDeployment[] } -} + Release: OctopusRelease; + Deployments: { [key: string]: OctopusDeployment[] }; +}; export type OctopusRelease = { - Id: string - Version: string -} + Id: string; + Version: string; +}; export type OctopusDeployment = { - State: string -} + State: string; +}; export const octopusDeployApiRef = createApiRef({ - id: 'plugin.octopusdeploy.service' + id: 'plugin.octopusdeploy.service', }); const DEFAULT_PROXY_PATH_BASE = '/octopus-deploy'; type Options = { - discoveryApi: DiscoveryApi; - identityApi: IdentityApi - /** - * Path to use for requests via the proxy, defaults to /octopus-deploy - */ - proxyPathBase?: string -} + discoveryApi: DiscoveryApi; + identityApi: IdentityApi; + /** + * Path to use for requests via the proxy, defaults to /octopus-deploy + */ + proxyPathBase?: string; +}; export interface OctopusDeployApi { - getReleaseProgression(projectId: string, releaseHistoryCount: number): Promise; + getReleaseProgression( + projectId: string, + releaseHistoryCount: number, + ): Promise; } export class OctopusDeployClient implements OctopusDeployApi { - private readonly discoveryApi: DiscoveryApi; - private readonly identityApi: IdentityApi; - private readonly proxyPathBase: string; + private readonly discoveryApi: DiscoveryApi; + private readonly identityApi: IdentityApi; + private readonly proxyPathBase: string; - constructor(options: Options) { - this.discoveryApi = options.discoveryApi; - this.identityApi = options.identityApi; - this.proxyPathBase = options.proxyPathBase ?? DEFAULT_PROXY_PATH_BASE; + constructor(options: Options) { + this.discoveryApi = options.discoveryApi; + this.identityApi = options.identityApi; + this.proxyPathBase = options.proxyPathBase ?? DEFAULT_PROXY_PATH_BASE; + } + + async getReleaseProgression( + projectId: string, + releaseHistoryCount: number, + ): Promise { + const url = await this.getApiUrl(projectId, releaseHistoryCount); + + const { token: idToken } = await this.identityApi.getCredentials(); + const response = await fetch(url, { + headers: idToken ? { Authorization: `Bearer ${idToken}` } : {}, + }); + + let responseJson; + + try { + responseJson = await response.json(); + } catch (e) { + responseJson = { releases: [] }; } - async getReleaseProgression(projectId: string, releaseHistoryCount: number): Promise { - const url = await this.getApiUrl(projectId, releaseHistoryCount); - - const { token: idToken } = await this.identityApi.getCredentials(); - const response = await fetch(url, { - headers: idToken ? { Authorization: `Bearer ${idToken}` } : {}, - }); - - let responseJson; - - try { - responseJson = await response.json(); - } catch (e) { - responseJson = { releases: [] }; - } - - if (response.status !== 200) { - throw new Error( - `Error communicating with Octopus Deploy: ${ - responseJson?.error?.title || response.statusText - }`, - ); - } - - return responseJson; + if (response.status !== 200) { + throw new Error( + `Error communicating with Octopus Deploy: ${ + responseJson?.error?.title || response.statusText + }`, + ); } - private async getApiUrl(projectId: string, releaseHistoryCount: number) { - const proxyUrl = await this.discoveryApi.getBaseUrl('proxy'); - return `${proxyUrl}${this.proxyPathBase}/projects/${projectId}/progression?releaseHistoryCount=${releaseHistoryCount}`; - } -} \ No newline at end of file + return responseJson; + } + + private async getApiUrl(projectId: string, releaseHistoryCount: number) { + const proxyUrl = await this.discoveryApi.getBaseUrl('proxy'); + return `${proxyUrl}${this.proxyPathBase}/projects/${projectId}/progression?releaseHistoryCount=${releaseHistoryCount}`; + } +} diff --git a/plugins/octopus-deploy/src/components/EntityPageOctopusDeploy/EntityPageOctopusDeploy.tsx b/plugins/octopus-deploy/src/components/EntityPageOctopusDeploy/EntityPageOctopusDeploy.tsx index d9b6a001c2..de28edb9e0 100644 --- a/plugins/octopus-deploy/src/components/EntityPageOctopusDeploy/EntityPageOctopusDeploy.tsx +++ b/plugins/octopus-deploy/src/components/EntityPageOctopusDeploy/EntityPageOctopusDeploy.tsx @@ -1,3 +1,18 @@ +/* + * Copyright 2023 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 { useEntity } from '@backstage/plugin-catalog-react'; import { useReleases } from '../../hooks/useReleases'; import { getAnnotationFromEntity } from '../../utils/getAnnotationFromEntity'; @@ -5,11 +20,21 @@ import React from 'react'; import { ReleaseTable } from '../ReleaseTable'; export const EntityPageOctopusDeploy = (props: { defaultLimit?: number }) => { - const { entity } = useEntity(); + const { entity } = useEntity(); - const projectId = getAnnotationFromEntity(entity); + const projectId = getAnnotationFromEntity(entity); - const { environments, releases, loading, error } = useReleases(projectId, props.defaultLimit ?? 3); + const { environments, releases, loading, error } = useReleases( + projectId, + props.defaultLimit ?? 3, + ); - return ; -} \ No newline at end of file + return ( + + ); +}; diff --git a/plugins/octopus-deploy/src/components/EntityPageOctopusDeploy/index.ts b/plugins/octopus-deploy/src/components/EntityPageOctopusDeploy/index.ts index ceed04684b..e168735130 100644 --- a/plugins/octopus-deploy/src/components/EntityPageOctopusDeploy/index.ts +++ b/plugins/octopus-deploy/src/components/EntityPageOctopusDeploy/index.ts @@ -1 +1,16 @@ -export { EntityPageOctopusDeploy } from './EntityPageOctopusDeploy'; \ No newline at end of file +/* + * Copyright 2023 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 { EntityPageOctopusDeploy } from './EntityPageOctopusDeploy'; diff --git a/plugins/octopus-deploy/src/components/ReleaseTable/index.ts b/plugins/octopus-deploy/src/components/ReleaseTable/index.ts index bd0b5bb6b1..d0c679a48e 100644 --- a/plugins/octopus-deploy/src/components/ReleaseTable/index.ts +++ b/plugins/octopus-deploy/src/components/ReleaseTable/index.ts @@ -1 +1,16 @@ -export { ReleaseTable } from './ReleaseTable'; \ No newline at end of file +/* + * Copyright 2023 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 { ReleaseTable } from './ReleaseTable'; diff --git a/plugins/octopus-deploy/src/constants.ts b/plugins/octopus-deploy/src/constants.ts index cec3804d9d..391dacb42c 100644 --- a/plugins/octopus-deploy/src/constants.ts +++ b/plugins/octopus-deploy/src/constants.ts @@ -1 +1,16 @@ -export const OCTOPUS_DEPLOY_PROJECT_ID_ANNOTATION = 'octopus.com/project-id'; \ No newline at end of file +/* + * Copyright 2023 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 OCTOPUS_DEPLOY_PROJECT_ID_ANNOTATION = 'octopus.com/project-id'; diff --git a/plugins/octopus-deploy/src/hooks/useReleases.ts b/plugins/octopus-deploy/src/hooks/useReleases.ts index ce38bfb286..742ce78dca 100644 --- a/plugins/octopus-deploy/src/hooks/useReleases.ts +++ b/plugins/octopus-deploy/src/hooks/useReleases.ts @@ -1,26 +1,45 @@ -import { useApi } from "@backstage/core-plugin-api"; -import useAsync from "react-use/lib/useAsync"; -import { octopusDeployApiRef, OctopusEnvironment, OctopusReleaseProgression } from "../api"; +/* + * Copyright 2023 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 { useApi } from '@backstage/core-plugin-api'; +import useAsync from 'react-use/lib/useAsync'; +import { + octopusDeployApiRef, + OctopusEnvironment, + OctopusReleaseProgression, +} from '../api'; export function useReleases( - projectId: string, - releaseHistoryCount: number + projectId: string, + releaseHistoryCount: number, ): { - environments?: OctopusEnvironment[], - releases?: OctopusReleaseProgression[] - loading: boolean; - error?: Error; + environments?: OctopusEnvironment[]; + releases?: OctopusReleaseProgression[]; + loading: boolean; + error?: Error; } { - const api = useApi(octopusDeployApiRef); - - const { value, loading, error } = useAsync(() => { - return api.getReleaseProgression(projectId, releaseHistoryCount); - }, [ api, projectId, releaseHistoryCount ]); + const api = useApi(octopusDeployApiRef); - return { - environments: value?.Environments, - releases: value?.Releases, - loading, - error - }; -} \ No newline at end of file + const { value, loading, error } = useAsync(() => { + return api.getReleaseProgression(projectId, releaseHistoryCount); + }, [api, projectId, releaseHistoryCount]); + + return { + environments: value?.Environments, + releases: value?.Releases, + loading, + error, + }; +} diff --git a/plugins/octopus-deploy/src/plugin.ts b/plugins/octopus-deploy/src/plugin.ts index c73f4b3aed..1634da2a9a 100644 --- a/plugins/octopus-deploy/src/plugin.ts +++ b/plugins/octopus-deploy/src/plugin.ts @@ -1,13 +1,30 @@ -import { - OCTOPUS_DEPLOY_PROJECT_ID_ANNOTATION -} from './constants'; -import { - octopusDeployEntityContentRouteRef -} from './routes'; +/* + * Copyright 2023 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 { OCTOPUS_DEPLOY_PROJECT_ID_ANNOTATION } from './constants'; +import { octopusDeployEntityContentRouteRef } from './routes'; import { OctopusDeployClient, octopusDeployApiRef } from './api'; -import { createApiFactory, createPlugin, createRoutableExtension, discoveryApiRef, identityApiRef } from '@backstage/core-plugin-api'; +import { + createApiFactory, + createPlugin, + createRoutableExtension, + discoveryApiRef, + identityApiRef, +} from '@backstage/core-plugin-api'; import { Entity } from '@backstage/catalog-model'; @@ -21,9 +38,10 @@ export const octopusDeployPlugin = createPlugin({ createApiFactory({ api: octopusDeployApiRef, deps: { discoveryApi: discoveryApiRef, identityApi: identityApiRef }, - factory: ({ discoveryApi, identityApi }) => new OctopusDeployClient({ discoveryApi, identityApi }) - }) - ] + factory: ({ discoveryApi, identityApi }) => + new OctopusDeployClient({ discoveryApi, identityApi }), + }), + ], }); /* @@ -42,8 +60,8 @@ export const EntityOctopusDeployContent = octopusDeployPlugin.provide( name: 'EntityOctopusDeployContent', component: () => import('./components/EntityPageOctopusDeploy').then( - m => m.EntityPageOctopusDeploy + m => m.EntityPageOctopusDeploy, ), - mountPoint: octopusDeployEntityContentRouteRef - }) -) \ No newline at end of file + mountPoint: octopusDeployEntityContentRouteRef, + }), +); diff --git a/plugins/octopus-deploy/src/routes.ts b/plugins/octopus-deploy/src/routes.ts index 772db37cb6..824b6ae113 100644 --- a/plugins/octopus-deploy/src/routes.ts +++ b/plugins/octopus-deploy/src/routes.ts @@ -1,5 +1,20 @@ +/* + * Copyright 2023 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 octopusDeployEntityContentRouteRef = createRouteRef({ - id: 'octopus-deploy-entity-content' -}) + id: 'octopus-deploy-entity-content', +}); diff --git a/plugins/octopus-deploy/src/utils/getAnnotationFromEntity.ts b/plugins/octopus-deploy/src/utils/getAnnotationFromEntity.ts index b1a8984163..96ac4d19f7 100644 --- a/plugins/octopus-deploy/src/utils/getAnnotationFromEntity.ts +++ b/plugins/octopus-deploy/src/utils/getAnnotationFromEntity.ts @@ -1,14 +1,30 @@ -import { - OCTOPUS_DEPLOY_PROJECT_ID_ANNOTATION -} from '../constants'; +/* + * Copyright 2023 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 { OCTOPUS_DEPLOY_PROJECT_ID_ANNOTATION } from '../constants'; import { Entity } from '@backstage/catalog-model'; export function getAnnotationFromEntity(entity: Entity): string { - const annotation = entity.metadata.annotations?.[OCTOPUS_DEPLOY_PROJECT_ID_ANNOTATION]; - if (!annotation) { - throw new Error('Value for annotation octopus.com/project-id was not found'); - } - - return annotation; -} \ No newline at end of file + const annotation = + entity.metadata.annotations?.[OCTOPUS_DEPLOY_PROJECT_ID_ANNOTATION]; + if (!annotation) { + throw new Error( + 'Value for annotation octopus.com/project-id was not found', + ); + } + + return annotation; +}