diff --git a/.changeset/red-cheetahs-invite.md b/.changeset/red-cheetahs-invite.md
new file mode 100644
index 0000000000..ef1711c761
--- /dev/null
+++ b/.changeset/red-cheetahs-invite.md
@@ -0,0 +1,6 @@
+---
+'@backstage/plugin-octopus-deploy': minor
+---
+
+Added support for Octopus Deploy spaces. The octopus.com/project-id annotation can now (optionally) be prefixed by a space identifier, for example. Spaces-1/Projects-102.
+Also note that some of this plugins exported API's have changed to accommodate this change, changing from separate arguments to a single object.
diff --git a/packages/app/package.json b/packages/app/package.json
index 74a41993d3..df626c16ba 100644
--- a/packages/app/package.json
+++ b/packages/app/package.json
@@ -47,6 +47,7 @@
"@backstage/plugin-microsoft-calendar": "workspace:^",
"@backstage/plugin-newrelic": "workspace:^",
"@backstage/plugin-newrelic-dashboard": "workspace:^",
+ "@backstage/plugin-octopus-deploy": "workspace:^",
"@backstage/plugin-org": "workspace:^",
"@backstage/plugin-pagerduty": "workspace:^",
"@backstage/plugin-permission-react": "workspace:^",
diff --git a/packages/app/src/components/catalog/EntityPage.tsx b/packages/app/src/components/catalog/EntityPage.tsx
index d2f6fbe109..026544ab26 100644
--- a/packages/app/src/components/catalog/EntityPage.tsx
+++ b/packages/app/src/components/catalog/EntityPage.tsx
@@ -41,6 +41,10 @@ import {
isAzureDevOpsAvailable,
isAzurePipelinesAvailable,
} from '@backstage/plugin-azure-devops';
+import {
+ isOctopusDeployAvailable,
+ EntityOctopusDeployContent,
+} from '@backstage/plugin-octopus-deploy';
import { EntityBadgesDialog } from '@backstage/plugin-badges';
import {
EntityAboutCard,
@@ -262,6 +266,10 @@ export const cicdContent = (
+
+
+
+
;
+ getReleaseProgression(opts: {
+ projectReference: ProjectReference;
+ releaseHistoryCount: number;
+ }): Promise;
}
// @public (undocumented)
@@ -42,10 +42,10 @@ export class OctopusDeployClient implements OctopusDeployApi {
proxyPathBase?: string;
});
// (undocumented)
- getReleaseProgression(
- projectId: string,
- releaseHistoryCount: number,
- ): Promise;
+ getReleaseProgression(opts: {
+ projectReference: ProjectReference;
+ releaseHistoryCount: number;
+ }): Promise;
}
// @public (undocumented)
@@ -82,5 +82,11 @@ export type OctopusReleaseProgression = {
};
};
+// @public (undocumented)
+export type ProjectReference = {
+ projectId: string;
+ spaceId?: string;
+};
+
// (No @packageDocumentation comment for this package)
```
diff --git a/plugins/octopus-deploy/src/api/index.ts b/plugins/octopus-deploy/src/api/index.ts
index 9cba49d6c0..0364bed269 100644
--- a/plugins/octopus-deploy/src/api/index.ts
+++ b/plugins/octopus-deploy/src/api/index.ts
@@ -18,6 +18,7 @@ import {
DiscoveryApi,
FetchApi,
} from '@backstage/core-plugin-api';
+import { ProjectReference } from '../utils/getAnnotationFromEntity';
/** @public */
export type OctopusProgression = {
@@ -57,10 +58,10 @@ const DEFAULT_PROXY_PATH_BASE = '/octopus-deploy';
/** @public */
export interface OctopusDeployApi {
- getReleaseProgression(
- projectId: string,
- releaseHistoryCount: number,
- ): Promise;
+ getReleaseProgression(opts: {
+ projectReference: ProjectReference;
+ releaseHistoryCount: number;
+ }): Promise;
}
/** @public */
@@ -79,11 +80,11 @@ export class OctopusDeployClient implements OctopusDeployApi {
this.proxyPathBase = options.proxyPathBase ?? DEFAULT_PROXY_PATH_BASE;
}
- async getReleaseProgression(
- projectId: string,
- releaseHistoryCount: number,
- ): Promise {
- const url = await this.getApiUrl(projectId, releaseHistoryCount);
+ async getReleaseProgression(opts: {
+ projectReference: ProjectReference;
+ releaseHistoryCount: number;
+ }): Promise {
+ const url = await this.getApiUrl(opts);
const response = await this.fetchApi.fetch(url);
@@ -106,13 +107,24 @@ export class OctopusDeployClient implements OctopusDeployApi {
return responseJson;
}
- private async getApiUrl(projectId: string, releaseHistoryCount: number) {
+ private async getApiUrl(opts: {
+ projectReference: ProjectReference;
+ releaseHistoryCount: number;
+ }) {
const proxyUrl = await this.discoveryApi.getBaseUrl('proxy');
const queryParameters = new URLSearchParams({
- releaseHistoryCount: releaseHistoryCount.toString(),
+ releaseHistoryCount: opts.releaseHistoryCount.toString(),
});
+ if (opts.projectReference.spaceId !== undefined) {
+ return `${proxyUrl}${this.proxyPathBase}/${encodeURIComponent(
+ opts.projectReference.spaceId,
+ )}/projects/${encodeURIComponent(
+ opts.projectReference.projectId,
+ )}/progression?${queryParameters}`;
+ }
+
return `${proxyUrl}${this.proxyPathBase}/projects/${encodeURIComponent(
- projectId,
+ opts.projectReference.projectId,
)}/progression?${queryParameters}`;
}
}
diff --git a/plugins/octopus-deploy/src/components/EntityPageOctopusDeploy/EntityPageOctopusDeploy.tsx b/plugins/octopus-deploy/src/components/EntityPageOctopusDeploy/EntityPageOctopusDeploy.tsx
index de28edb9e0..21080cb408 100644
--- a/plugins/octopus-deploy/src/components/EntityPageOctopusDeploy/EntityPageOctopusDeploy.tsx
+++ b/plugins/octopus-deploy/src/components/EntityPageOctopusDeploy/EntityPageOctopusDeploy.tsx
@@ -15,18 +15,19 @@
*/
import { useEntity } from '@backstage/plugin-catalog-react';
import { useReleases } from '../../hooks/useReleases';
-import { getAnnotationFromEntity } from '../../utils/getAnnotationFromEntity';
+import { getProjectReferenceAnnotationFromEntity } from '../../utils/getAnnotationFromEntity';
import React from 'react';
import { ReleaseTable } from '../ReleaseTable';
export const EntityPageOctopusDeploy = (props: { defaultLimit?: number }) => {
const { entity } = useEntity();
- const projectId = getAnnotationFromEntity(entity);
+ const projectReference = getProjectReferenceAnnotationFromEntity(entity);
const { environments, releases, loading, error } = useReleases(
- projectId,
+ projectReference.projectId,
props.defaultLimit ?? 3,
+ projectReference.spaceId,
);
return (
diff --git a/plugins/octopus-deploy/src/hooks/useReleases.ts b/plugins/octopus-deploy/src/hooks/useReleases.ts
index 742ce78dca..671a0a7e7f 100644
--- a/plugins/octopus-deploy/src/hooks/useReleases.ts
+++ b/plugins/octopus-deploy/src/hooks/useReleases.ts
@@ -24,6 +24,7 @@ import {
export function useReleases(
projectId: string,
releaseHistoryCount: number,
+ spaceId?: string,
): {
environments?: OctopusEnvironment[];
releases?: OctopusReleaseProgression[];
@@ -33,8 +34,11 @@ export function useReleases(
const api = useApi(octopusDeployApiRef);
const { value, loading, error } = useAsync(() => {
- return api.getReleaseProgression(projectId, releaseHistoryCount);
- }, [api, projectId, releaseHistoryCount]);
+ return api.getReleaseProgression({
+ projectReference: { projectId, spaceId },
+ releaseHistoryCount,
+ });
+ }, [api, projectId, spaceId, releaseHistoryCount]);
return {
environments: value?.Environments,
diff --git a/plugins/octopus-deploy/src/index.ts b/plugins/octopus-deploy/src/index.ts
index e3264efaf0..2b39431606 100644
--- a/plugins/octopus-deploy/src/index.ts
+++ b/plugins/octopus-deploy/src/index.ts
@@ -21,4 +21,6 @@ export {
export * from './api';
+export type { ProjectReference } from './utils/getAnnotationFromEntity';
+
export { OCTOPUS_DEPLOY_PROJECT_ID_ANNOTATION } from './constants';
diff --git a/plugins/octopus-deploy/src/utils/getAnnotationFromEntity.ts b/plugins/octopus-deploy/src/utils/getAnnotationFromEntity.ts
index e59a32235f..80ebaab76a 100644
--- a/plugins/octopus-deploy/src/utils/getAnnotationFromEntity.ts
+++ b/plugins/octopus-deploy/src/utils/getAnnotationFromEntity.ts
@@ -17,7 +17,12 @@ import { OCTOPUS_DEPLOY_PROJECT_ID_ANNOTATION } from '../constants';
import { Entity } from '@backstage/catalog-model';
-export function getAnnotationFromEntity(entity: Entity): string {
+/** @public */
+export type ProjectReference = { projectId: string; spaceId?: string };
+
+export function getProjectReferenceAnnotationFromEntity(
+ entity: Entity,
+): ProjectReference {
const annotation =
entity.metadata.annotations?.[OCTOPUS_DEPLOY_PROJECT_ID_ANNOTATION];
if (!annotation) {
@@ -26,5 +31,9 @@ export function getAnnotationFromEntity(entity: Entity): string {
);
}
- return annotation;
+ const referencedProject = annotation.split('/', 2);
+ if (referencedProject.length === 2) {
+ return { projectId: referencedProject[1], spaceId: referencedProject[0] };
+ }
+ return { projectId: referencedProject[0] };
}
diff --git a/yarn.lock b/yarn.lock
index 0cd30db248..b27a6f4274 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7508,7 +7508,7 @@ __metadata:
languageName: unknown
linkType: soft
-"@backstage/plugin-octopus-deploy@workspace:plugins/octopus-deploy":
+"@backstage/plugin-octopus-deploy@workspace:^, @backstage/plugin-octopus-deploy@workspace:plugins/octopus-deploy":
version: 0.0.0-use.local
resolution: "@backstage/plugin-octopus-deploy@workspace:plugins/octopus-deploy"
dependencies:
@@ -23583,6 +23583,7 @@ __metadata:
"@backstage/plugin-microsoft-calendar": "workspace:^"
"@backstage/plugin-newrelic": "workspace:^"
"@backstage/plugin-newrelic-dashboard": "workspace:^"
+ "@backstage/plugin-octopus-deploy": "workspace:^"
"@backstage/plugin-org": "workspace:^"
"@backstage/plugin-pagerduty": "workspace:^"
"@backstage/plugin-permission-react": "workspace:^"