From e6a9b2dead06c3486eabc93d826f54f4beab571b Mon Sep 17 00:00:00 2001 From: PurseChicken Date: Fri, 17 Nov 2023 12:07:40 -0800 Subject: [PATCH 1/7] Cloud build plugin list results by entity metatadata name or annotations Signed-off-by: PurseChicken --- plugins/cloudbuild/api-report.md | 2 + plugins/cloudbuild/src/api/CloudbuildApi.ts | 1 + .../cloudbuild/src/api/CloudbuildClient.ts | 3 +- .../cloudbuild/src/components/Cards/Cards.tsx | 3 ++ .../WorkflowRunsTable/WorkflowRunsTable.tsx | 3 ++ .../src/components/useCloudBuildFilter.ts | 43 +++++++++++++++++++ .../src/components/useWorkflowRuns.ts | 8 +++- 7 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 plugins/cloudbuild/src/components/useCloudBuildFilter.ts diff --git a/plugins/cloudbuild/api-report.md b/plugins/cloudbuild/api-report.md index 3fbb15000d..f8fbd9ee92 100644 --- a/plugins/cloudbuild/api-report.md +++ b/plugins/cloudbuild/api-report.md @@ -58,6 +58,7 @@ export const CLOUDBUILD_ANNOTATION = 'google.com/cloudbuild-project-slug'; export type CloudbuildApi = { listWorkflowRuns: (options: { projectId: string; + cloudBuildFilter: string; }) => Promise; getWorkflow: (options: { projectId: string; @@ -94,6 +95,7 @@ export class CloudbuildClient implements CloudbuildApi { // (undocumented) listWorkflowRuns(options: { projectId: string; + cloudBuildFilter: string; }): Promise; // (undocumented) reRunWorkflow(options: { projectId: string; runId: string }): Promise; diff --git a/plugins/cloudbuild/src/api/CloudbuildApi.ts b/plugins/cloudbuild/src/api/CloudbuildApi.ts index cb29b49fbf..cdcfbab88d 100644 --- a/plugins/cloudbuild/src/api/CloudbuildApi.ts +++ b/plugins/cloudbuild/src/api/CloudbuildApi.ts @@ -29,6 +29,7 @@ export const cloudbuildApiRef = createApiRef({ export type CloudbuildApi = { listWorkflowRuns: (options: { projectId: string; + cloudBuildFilter: string; }) => Promise; getWorkflow: (options: { projectId: string; diff --git a/plugins/cloudbuild/src/api/CloudbuildClient.ts b/plugins/cloudbuild/src/api/CloudbuildClient.ts index cb6747e803..b41506f852 100644 --- a/plugins/cloudbuild/src/api/CloudbuildClient.ts +++ b/plugins/cloudbuild/src/api/CloudbuildClient.ts @@ -45,11 +45,12 @@ export class CloudbuildClient implements CloudbuildApi { async listWorkflowRuns(options: { projectId: string; + cloudBuildFilter: string; }): Promise { const workflowRuns = await fetch( `https://cloudbuild.googleapis.com/v1/projects/${encodeURIComponent( options.projectId, - )}/builds`, + )}/builds?filter=${encodeURIComponent(options.cloudBuildFilter)}`, { headers: new Headers({ Accept: '*/*', diff --git a/plugins/cloudbuild/src/components/Cards/Cards.tsx b/plugins/cloudbuild/src/components/Cards/Cards.tsx index 2b7a8607b7..cd15bae6b9 100644 --- a/plugins/cloudbuild/src/components/Cards/Cards.tsx +++ b/plugins/cloudbuild/src/components/Cards/Cards.tsx @@ -22,6 +22,7 @@ import { WorkflowRunStatus } from '../WorkflowRunStatus'; import { Theme, makeStyles, LinearProgress } from '@material-ui/core'; import ExternalLinkIcon from '@material-ui/icons/Launch'; import { CLOUDBUILD_ANNOTATION } from '../useProjectName'; +import { getCloudbuildFilter } from '../useCloudBuildFilter'; import { InfoCard, @@ -79,9 +80,11 @@ export const LatestWorkflowRunCard = (props: { branch: string }) => { const { entity } = useEntity(); const errorApi = useApi(errorApiRef); const projectId = entity?.metadata.annotations?.[CLOUDBUILD_ANNOTATION] || ''; + const cloudBuildFilter = getCloudbuildFilter(entity); const [{ runs, loading, error }] = useWorkflowRuns({ projectId, + cloudBuildFilter, }); const lastRun = runs?.[0] ?? ({} as WorkflowRun); useEffect(() => { diff --git a/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx b/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx index 294847a700..210a67d0dc 100644 --- a/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx +++ b/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx @@ -26,6 +26,7 @@ import { buildRouteRef } from '../../routes'; import { DateTime } from 'luxon'; import { Table, TableColumn, Link } from '@backstage/core-components'; import { useRouteRef } from '@backstage/core-plugin-api'; +import { getCloudbuildFilter } from '../useCloudBuildFilter'; const generatedColumns: TableColumn[] = [ { @@ -162,9 +163,11 @@ export const WorkflowRunsTableView = ({ export const WorkflowRunsTable = (props: { entity: Entity }) => { const { value: projectName, loading } = useProjectName(props.entity); const [projectId] = (projectName ?? '/').split('/'); + const cloudBuildFilter = getCloudbuildFilter(props.entity); const [tableProps, { retry, setPage, setPageSize }] = useWorkflowRuns({ projectId, + cloudBuildFilter, }); return ( diff --git a/plugins/cloudbuild/src/components/useCloudBuildFilter.ts b/plugins/cloudbuild/src/components/useCloudBuildFilter.ts new file mode 100644 index 0000000000..a71cc1e9b6 --- /dev/null +++ b/plugins/cloudbuild/src/components/useCloudBuildFilter.ts @@ -0,0 +1,43 @@ +/* + * 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. + */ + +import { Entity } from '@backstage/catalog-model'; + +const CLOUDBUILD_FILTER_REPO_STRING = 'substitutions.REPO_NAME='; +const CLOUDBUILD_FILTER_REPO_ANNOTATION = 'google.com/cloudbuild-repo-name'; +const CLOUDBUILD_FILTER_TRIGGER_STRING = 'substitutions.TRIGGER_NAME='; +const CLOUDBUILD_FILTER_TRIGGER_ANNOTATION = + 'google.com/cloudbuild-trigger-name'; + +/** @public */ + +export const getCloudbuildFilter = (entity: Entity) => { + const repoAnnotation = + entity?.metadata.annotations?.[CLOUDBUILD_FILTER_REPO_ANNOTATION] ?? ''; + const triggerAnnotation = + entity?.metadata.annotations?.[CLOUDBUILD_FILTER_TRIGGER_ANNOTATION] ?? ''; + if (repoAnnotation) { + const cloudbuildFilter = CLOUDBUILD_FILTER_REPO_STRING + repoAnnotation; + return cloudbuildFilter; + } else if (triggerAnnotation) { + const cloudbuildFilter = + CLOUDBUILD_FILTER_TRIGGER_STRING + triggerAnnotation; + return cloudbuildFilter; + } + const entityName = entity?.metadata.name ?? ''; + const cloudbuildFilter = CLOUDBUILD_FILTER_REPO_STRING + entityName; + return cloudbuildFilter; +}; diff --git a/plugins/cloudbuild/src/components/useWorkflowRuns.ts b/plugins/cloudbuild/src/components/useWorkflowRuns.ts index 424f08e38d..86168018d4 100644 --- a/plugins/cloudbuild/src/components/useWorkflowRuns.ts +++ b/plugins/cloudbuild/src/components/useWorkflowRuns.ts @@ -33,8 +33,11 @@ export type WorkflowRun = { rerun: () => void; }; -export function useWorkflowRuns(options: { projectId: string }) { - const { projectId } = options; +export function useWorkflowRuns(options: { + projectId: string; + cloudBuildFilter: string; +}) { + const { projectId, cloudBuildFilter } = options; const api = useApi(cloudbuildApiRef); const errorApi = useApi(errorApiRef); @@ -51,6 +54,7 @@ export function useWorkflowRuns(options: { projectId: string }) { return api .listWorkflowRuns({ projectId, + cloudBuildFilter, }) .then( ( From 31474decad26c08499a72915ea4ec74cbae9c013 Mon Sep 17 00:00:00 2001 From: PurseChicken Date: Fri, 17 Nov 2023 12:41:14 -0800 Subject: [PATCH 2/7] Update ReadMe Signed-off-by: PurseChicken --- plugins/cloudbuild/README.md | 48 +++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/plugins/cloudbuild/README.md b/plugins/cloudbuild/README.md index 07999c85a1..edb0d69e5d 100644 --- a/plugins/cloudbuild/README.md +++ b/plugins/cloudbuild/README.md @@ -1,4 +1,4 @@ -# Google Cloud Build +# Google Cloud Build Plugin ### Welcome to the Google Cloud Build plugin! @@ -47,7 +47,7 @@ const cicdContent = ( ##### OPTIONAL -If you don't use GitHub Actions, or don't want to show it on your CI/CD page, then you can remove the switch case for it +If you don't use GitHub Actions, or don't want to show it on your CI/CD page, then you can remove the switch case for it: ```diff // packages/app/src/components/catalog/EntityPage.tsx @@ -62,9 +62,9 @@ const cicdContent = ( - ``` -### Add annotation to your component-info.yaml file. +### Add annotation(s) to your component-info.yaml file -Any component, that you would like the Cloud Build Plugin to populate for, should include the following annotation: +Any component, that you would like the Cloud Build Plugin to populate for, should include the following `cloudbuild-project-slug` annotation. This annotation sets the GCP project name to be used for pulling the cloud build details from. ```diff // component-info.yaml @@ -79,3 +79,43 @@ spec: type: website lifecycle: development ``` + +By default, the cloud build results list is filtered by repository name equal to the name you have set in your component-info.yaml file. This is `metadata.name`. So if your metadata.name is `backstage` then it will only show builds matching the backstage repo name. + +#### Change Filtering + +If you need the page to be filtered on a different repository name, then you can use the following annotation: + +```diff +// component-info.yaml +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage + description: Backstage application. + annotations: + google.com/cloudbuild-project-slug: your-project-name ++ google.com/cloudbuild-repo-name: my-backstage +spec: + type: website + lifecycle: development +``` + +You can also automatically filter the results based on trigger name instead of repository name. To so so, use the following annotation: + +```diff +// component-info.yaml +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage + description: Backstage application. + annotations: + google.com/cloudbuild-project-slug: your-project-name ++ google.com/cloudbuild-trigger-name: my-trigger-name +spec: + type: website + lifecycle: development +``` + +`Note:` The `cloudbuild-repo-name` annotation takes precedence over the `cloudbuild-trigger-name` annotation. So if you happen to use both annotations, cloudbuild-repo-name will be used. It is recommended to use one or the other if required. From c55d501b564ee5ce369629a6e60206cccc26720e Mon Sep 17 00:00:00 2001 From: PurseChicken Date: Fri, 17 Nov 2023 12:47:55 -0800 Subject: [PATCH 3/7] Use REF_NAME instead of BRANCH_NAME Signed-off-by: PurseChicken --- plugins/cloudbuild/api-report.md | 2 +- plugins/cloudbuild/src/api/types.ts | 2 +- .../src/components/WorkflowRunDetails/WorkflowRunDetails.tsx | 4 ++-- .../components/WorkflowRunsTable/WorkflowRunsTable.test.tsx | 2 +- .../src/components/WorkflowRunsTable/WorkflowRunsTable.tsx | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/cloudbuild/api-report.md b/plugins/cloudbuild/api-report.md index f8fbd9ee92..0e152baa0f 100644 --- a/plugins/cloudbuild/api-report.md +++ b/plugins/cloudbuild/api-report.md @@ -237,7 +237,7 @@ export interface StorageSource { // @public (undocumented) export interface Substitutions { // (undocumented) - BRANCH_NAME: string; + REF_NAME: string; // (undocumented) COMMIT_SHA: string; // (undocumented) diff --git a/plugins/cloudbuild/src/api/types.ts b/plugins/cloudbuild/src/api/types.ts index 1dd03265bc..b721e8dca1 100644 --- a/plugins/cloudbuild/src/api/types.ts +++ b/plugins/cloudbuild/src/api/types.ts @@ -81,7 +81,7 @@ export interface Options { export interface Substitutions { COMMIT_SHA: string; SHORT_SHA: string; - BRANCH_NAME: string; + REF_NAME: string; REPO_NAME: string; REVISION_ID: string; } diff --git a/plugins/cloudbuild/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx b/plugins/cloudbuild/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx index a35d9b6f6c..ee282848bc 100644 --- a/plugins/cloudbuild/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx +++ b/plugins/cloudbuild/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx @@ -97,9 +97,9 @@ export const WorkflowRunDetails = (props: { entity: Entity }) => { - Branch + Ref - {details.value?.substitutions.BRANCH_NAME} + {details.value?.substitutions.REF_NAME} diff --git a/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.test.tsx b/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.test.tsx index 0152f9d964..92a806bee7 100644 --- a/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.test.tsx +++ b/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.test.tsx @@ -35,7 +35,7 @@ describe('', () => { substitutions: { COMMIT_SHA: 'e3adasd2e3adasd2e3adasd2', SHORT_SHA: 'f12j1231', - BRANCH_NAME: 'main', + REF_NAME: 'main', REPO_NAME: 'backstage', REVISION_ID: 'g123123', }, diff --git a/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx b/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx index 210a67d0dc..dbefffc617 100644 --- a/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx +++ b/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx @@ -72,7 +72,7 @@ const generatedColumns: TableColumn[] = [ title: 'Ref', render: (row: Partial) => ( - {row.substitutions?.BRANCH_NAME} + {row.substitutions?.REF_NAME} ), }, From 0328d1b6b921d870f2676ea899b541eb97e606b0 Mon Sep 17 00:00:00 2001 From: PurseChicken Date: Fri, 17 Nov 2023 13:04:23 -0800 Subject: [PATCH 4/7] Write Changeset Signed-off-by: PurseChicken --- .changeset/tough-drinks-scream.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .changeset/tough-drinks-scream.md diff --git a/.changeset/tough-drinks-scream.md b/.changeset/tough-drinks-scream.md new file mode 100644 index 0000000000..fc174f3158 --- /dev/null +++ b/.changeset/tough-drinks-scream.md @@ -0,0 +1,9 @@ +--- +'@backstage/plugin-cloudbuild': minor +--- + +Changed build list view to automatically filter repositories based on component-info's metadata.name. +Added `google.com/cloudbuild-repo-name` annotation which allows you to specify a different repository to filter on. +Added `google.com/cloudbuild-trigger-name` annotation which allows you to filter based on a trigger name instead of a repo name. +Updated the ReadMe with information about the filtering and some other minor verbiage updates. +Changed `substitutions.BRANCH_NAME` to `substitutions.REF_NAME` so that the Ref field is populated properly. From fcaa2ce61f6ade93443c52af88006a77c4ab4d83 Mon Sep 17 00:00:00 2001 From: PurseChicken Date: Fri, 17 Nov 2023 13:18:08 -0800 Subject: [PATCH 5/7] Fix type in ReadMe Signed-off-by: PurseChicken --- plugins/cloudbuild/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/cloudbuild/README.md b/plugins/cloudbuild/README.md index edb0d69e5d..cde383b8c4 100644 --- a/plugins/cloudbuild/README.md +++ b/plugins/cloudbuild/README.md @@ -101,7 +101,7 @@ spec: lifecycle: development ``` -You can also automatically filter the results based on trigger name instead of repository name. To so so, use the following annotation: +You can also automatically filter the results based on trigger name instead of repository name. To do so, use the following annotation: ```diff // component-info.yaml From 568121143a10db1a54ca6a394be49522de3fd206 Mon Sep 17 00:00:00 2001 From: PurseChicken Date: Fri, 17 Nov 2023 13:25:37 -0800 Subject: [PATCH 6/7] Run build:api-reports Signed-off-by: PurseChicken --- plugins/cloudbuild/api-report.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/cloudbuild/api-report.md b/plugins/cloudbuild/api-report.md index 0e152baa0f..5a8f2ed1db 100644 --- a/plugins/cloudbuild/api-report.md +++ b/plugins/cloudbuild/api-report.md @@ -236,11 +236,11 @@ export interface StorageSource { // @public (undocumented) export interface Substitutions { - // (undocumented) - REF_NAME: string; // (undocumented) COMMIT_SHA: string; // (undocumented) + REF_NAME: string; + // (undocumented) REPO_NAME: string; // (undocumented) REVISION_ID: string; From 8745a6fa8a908f451902492c064247bcc7879f71 Mon Sep 17 00:00:00 2001 From: PurseChicken Date: Mon, 27 Nov 2023 11:36:48 -0800 Subject: [PATCH 7/7] Update plugin to support different Build locations. Update changeset and ReadMe. Signed-off-by: PurseChicken --- .changeset/tough-drinks-scream.md | 9 ++++-- plugins/cloudbuild/README.md | 21 ++++++++++++- plugins/cloudbuild/api-report.md | 13 +++++++- plugins/cloudbuild/src/api/CloudbuildApi.ts | 4 +++ .../cloudbuild/src/api/CloudbuildClient.ts | 12 ++++++++ .../cloudbuild/src/components/Cards/Cards.tsx | 3 ++ .../WorkflowRunDetails/WorkflowRunDetails.tsx | 4 ++- .../useWorkflowRunsDetails.ts | 3 +- .../WorkflowRunsTable/WorkflowRunsTable.tsx | 4 ++- .../cloudbuild/src/components/useLocation.ts | 30 +++++++++++++++++++ .../src/components/useWorkflowRuns.ts | 5 +++- 11 files changed, 99 insertions(+), 9 deletions(-) create mode 100644 plugins/cloudbuild/src/components/useLocation.ts diff --git a/.changeset/tough-drinks-scream.md b/.changeset/tough-drinks-scream.md index fc174f3158..3d2f154016 100644 --- a/.changeset/tough-drinks-scream.md +++ b/.changeset/tough-drinks-scream.md @@ -2,8 +2,11 @@ '@backstage/plugin-cloudbuild': minor --- -Changed build list view to automatically filter repositories based on component-info's metadata.name. -Added `google.com/cloudbuild-repo-name` annotation which allows you to specify a different repository to filter on. -Added `google.com/cloudbuild-trigger-name` annotation which allows you to filter based on a trigger name instead of a repo name. +Changed build list view to automatically filter builds based on repository name matching component-info's metadata.name. +Added optional `google.com/cloudbuild-repo-name` annotation which allows you to specify a different repository to filter on. +Added optional `google.com/cloudbuild-trigger-name` annotation which allows you to filter based on a trigger name instead of a repo name. Updated the ReadMe with information about the filtering and some other minor verbiage updates. Changed `substitutions.BRANCH_NAME` to `substitutions.REF_NAME` so that the Ref field is populated properly. +Added optional `google.com/cloudbuild-location` annotation which allows you to specify the Cloud Build location of your builds. Default is global scope. +Changed build list view to show builds in a specific location if the location annotation is used. +Updated ReadMe with information about the use of the location filtering. diff --git a/plugins/cloudbuild/README.md b/plugins/cloudbuild/README.md index cde383b8c4..2677d02b13 100644 --- a/plugins/cloudbuild/README.md +++ b/plugins/cloudbuild/README.md @@ -64,7 +64,7 @@ const cicdContent = ( ### Add annotation(s) to your component-info.yaml file -Any component, that you would like the Cloud Build Plugin to populate for, should include the following `cloudbuild-project-slug` annotation. This annotation sets the GCP project name to be used for pulling the cloud build details from. +Any component, that you would like the Cloud Build Plugin to populate for, should include the following `cloudbuild-project-slug` annotation. This annotation sets the GCP project name to be used for pulling the Cloud Build details from. ```diff // component-info.yaml @@ -82,6 +82,8 @@ spec: By default, the cloud build results list is filtered by repository name equal to the name you have set in your component-info.yaml file. This is `metadata.name`. So if your metadata.name is `backstage` then it will only show builds matching the backstage repo name. +Additionally, build results are pulled from the `global` region by default. + #### Change Filtering If you need the page to be filtered on a different repository name, then you can use the following annotation: @@ -119,3 +121,20 @@ spec: ``` `Note:` The `cloudbuild-repo-name` annotation takes precedence over the `cloudbuild-trigger-name` annotation. So if you happen to use both annotations, cloudbuild-repo-name will be used. It is recommended to use one or the other if required. + +If you need to pull Cloud Build results from a location or region other than the global scope, then use the following annotation: + +```diff +// component-info.yaml +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage + description: Backstage application. + annotations: + google.com/cloudbuild-project-slug: your-project-name ++ google.com/cloudbuild-location: us-central1 +spec: + type: website + lifecycle: development +``` diff --git a/plugins/cloudbuild/api-report.md b/plugins/cloudbuild/api-report.md index 5a8f2ed1db..2ce42d5e34 100644 --- a/plugins/cloudbuild/api-report.md +++ b/plugins/cloudbuild/api-report.md @@ -58,18 +58,22 @@ export const CLOUDBUILD_ANNOTATION = 'google.com/cloudbuild-project-slug'; export type CloudbuildApi = { listWorkflowRuns: (options: { projectId: string; + location: string; cloudBuildFilter: string; }) => Promise; getWorkflow: (options: { projectId: string; + location: string; id: string; }) => Promise; getWorkflowRun: (options: { projectId: string; + location: string; id: string; }) => Promise; reRunWorkflow: (options: { projectId: string; + location: string; runId: string; }) => Promise; }; @@ -85,20 +89,27 @@ export class CloudbuildClient implements CloudbuildApi { // (undocumented) getWorkflow(options: { projectId: string; + location: string; id: string; }): Promise; // (undocumented) getWorkflowRun(options: { projectId: string; + location: string; id: string; }): Promise; // (undocumented) listWorkflowRuns(options: { projectId: string; + location: string; cloudBuildFilter: string; }): Promise; // (undocumented) - reRunWorkflow(options: { projectId: string; runId: string }): Promise; + reRunWorkflow(options: { + projectId: string; + location: string; + runId: string; + }): Promise; } // @public (undocumented) diff --git a/plugins/cloudbuild/src/api/CloudbuildApi.ts b/plugins/cloudbuild/src/api/CloudbuildApi.ts index cdcfbab88d..9e2d63fc01 100644 --- a/plugins/cloudbuild/src/api/CloudbuildApi.ts +++ b/plugins/cloudbuild/src/api/CloudbuildApi.ts @@ -29,18 +29,22 @@ export const cloudbuildApiRef = createApiRef({ export type CloudbuildApi = { listWorkflowRuns: (options: { projectId: string; + location: string; cloudBuildFilter: string; }) => Promise; getWorkflow: (options: { projectId: string; + location: string; id: string; }) => Promise; getWorkflowRun: (options: { projectId: string; + location: string; id: string; }) => Promise; reRunWorkflow: (options: { projectId: string; + location: string; runId: string; }) => Promise; }; diff --git a/plugins/cloudbuild/src/api/CloudbuildClient.ts b/plugins/cloudbuild/src/api/CloudbuildClient.ts index b41506f852..3717e3d1db 100644 --- a/plugins/cloudbuild/src/api/CloudbuildClient.ts +++ b/plugins/cloudbuild/src/api/CloudbuildClient.ts @@ -27,11 +27,14 @@ export class CloudbuildClient implements CloudbuildApi { async reRunWorkflow(options: { projectId: string; + location: string; runId: string; }): Promise { await fetch( `https://cloudbuild.googleapis.com/v1/projects/${encodeURIComponent( options.projectId, + )}/locations/${encodeURIComponent( + options.location, )}/builds/${encodeURIComponent(options.runId)}:retry`, { method: 'POST', @@ -45,11 +48,14 @@ export class CloudbuildClient implements CloudbuildApi { async listWorkflowRuns(options: { projectId: string; + location: string; cloudBuildFilter: string; }): Promise { const workflowRuns = await fetch( `https://cloudbuild.googleapis.com/v1/projects/${encodeURIComponent( options.projectId, + )}/locations/${encodeURIComponent( + options.location, )}/builds?filter=${encodeURIComponent(options.cloudBuildFilter)}`, { headers: new Headers({ @@ -67,11 +73,14 @@ export class CloudbuildClient implements CloudbuildApi { async getWorkflow(options: { projectId: string; + location: string; id: string; }): Promise { const workflow = await fetch( `https://cloudbuild.googleapis.com/v1/projects/${encodeURIComponent( options.projectId, + )}/locations/${encodeURIComponent( + options.location, )}/builds/${encodeURIComponent(options.id)}`, { headers: new Headers({ @@ -88,11 +97,14 @@ export class CloudbuildClient implements CloudbuildApi { async getWorkflowRun(options: { projectId: string; + location: string; id: string; }): Promise { const workflow = await fetch( `https://cloudbuild.googleapis.com/v1/projects/${encodeURIComponent( options.projectId, + )}/locations/${encodeURIComponent( + options.location, )}/builds/${encodeURIComponent(options.id)}`, { headers: new Headers({ diff --git a/plugins/cloudbuild/src/components/Cards/Cards.tsx b/plugins/cloudbuild/src/components/Cards/Cards.tsx index cd15bae6b9..e1d9199b7e 100644 --- a/plugins/cloudbuild/src/components/Cards/Cards.tsx +++ b/plugins/cloudbuild/src/components/Cards/Cards.tsx @@ -22,6 +22,7 @@ import { WorkflowRunStatus } from '../WorkflowRunStatus'; import { Theme, makeStyles, LinearProgress } from '@material-ui/core'; import ExternalLinkIcon from '@material-ui/icons/Launch'; import { CLOUDBUILD_ANNOTATION } from '../useProjectName'; +import { getLocation } from '../useLocation'; import { getCloudbuildFilter } from '../useCloudBuildFilter'; import { @@ -80,10 +81,12 @@ export const LatestWorkflowRunCard = (props: { branch: string }) => { const { entity } = useEntity(); const errorApi = useApi(errorApiRef); const projectId = entity?.metadata.annotations?.[CLOUDBUILD_ANNOTATION] || ''; + const location = getLocation(entity); const cloudBuildFilter = getCloudbuildFilter(entity); const [{ runs, loading, error }] = useWorkflowRuns({ projectId, + location, cloudBuildFilter, }); const lastRun = runs?.[0] ?? ({} as WorkflowRun); diff --git a/plugins/cloudbuild/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx b/plugins/cloudbuild/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx index ee282848bc..5be2401ae4 100644 --- a/plugins/cloudbuild/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx +++ b/plugins/cloudbuild/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx @@ -35,6 +35,7 @@ import { useProjectName } from '../useProjectName'; import { WorkflowRunStatus } from '../WorkflowRunStatus'; import { useWorkflowRunsDetails } from './useWorkflowRunsDetails'; import { Breadcrumbs, Link, WarningPanel } from '@backstage/core-components'; +import { getLocation } from '../useLocation'; const useStyles = makeStyles(theme => ({ root: { @@ -64,8 +65,9 @@ const useStyles = makeStyles(theme => ({ export const WorkflowRunDetails = (props: { entity: Entity }) => { const { value: projectName, loading, error } = useProjectName(props.entity); const [projectId] = (projectName ?? '/').split('/'); + const location = getLocation(props.entity); - const details = useWorkflowRunsDetails(projectId); + const details = useWorkflowRunsDetails(projectId, location); const classes = useStyles(); if (error) { diff --git a/plugins/cloudbuild/src/components/WorkflowRunDetails/useWorkflowRunsDetails.ts b/plugins/cloudbuild/src/components/WorkflowRunDetails/useWorkflowRunsDetails.ts index 549ab1eaf2..abc146fb6c 100644 --- a/plugins/cloudbuild/src/components/WorkflowRunDetails/useWorkflowRunsDetails.ts +++ b/plugins/cloudbuild/src/components/WorkflowRunDetails/useWorkflowRunsDetails.ts @@ -18,13 +18,14 @@ import { cloudbuildApiRef } from '../../api'; import { useApi, useRouteRefParams } from '@backstage/core-plugin-api'; import { buildRouteRef } from '../../routes'; -export const useWorkflowRunsDetails = (projectId: string) => { +export const useWorkflowRunsDetails = (projectId: string, location: string) => { const api = useApi(cloudbuildApiRef); const { id } = useRouteRefParams(buildRouteRef); const details = useAsync(async () => { return projectId ? api.getWorkflowRun({ projectId, + location, id: id, }) : Promise.reject('No projectId provided'); diff --git a/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx b/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx index dbefffc617..65b5ca149f 100644 --- a/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx +++ b/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx @@ -26,6 +26,7 @@ import { buildRouteRef } from '../../routes'; import { DateTime } from 'luxon'; import { Table, TableColumn, Link } from '@backstage/core-components'; import { useRouteRef } from '@backstage/core-plugin-api'; +import { getLocation } from '../useLocation'; import { getCloudbuildFilter } from '../useCloudBuildFilter'; const generatedColumns: TableColumn[] = [ @@ -163,10 +164,11 @@ export const WorkflowRunsTableView = ({ export const WorkflowRunsTable = (props: { entity: Entity }) => { const { value: projectName, loading } = useProjectName(props.entity); const [projectId] = (projectName ?? '/').split('/'); + const location = getLocation(props.entity); const cloudBuildFilter = getCloudbuildFilter(props.entity); - const [tableProps, { retry, setPage, setPageSize }] = useWorkflowRuns({ projectId, + location, cloudBuildFilter, }); diff --git a/plugins/cloudbuild/src/components/useLocation.ts b/plugins/cloudbuild/src/components/useLocation.ts new file mode 100644 index 0000000000..54a3c8f776 --- /dev/null +++ b/plugins/cloudbuild/src/components/useLocation.ts @@ -0,0 +1,30 @@ +/* + * 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. + */ + +import { Entity } from '@backstage/catalog-model'; + +const CLOUDBUILD_LOCATION_ANNOTATION = 'google.com/cloudbuild-location'; + +/** @public */ + +export const getLocation = (entity: Entity) => { + const locationAnnotation = + entity?.metadata.annotations?.[CLOUDBUILD_LOCATION_ANNOTATION] ?? ''; + if (locationAnnotation) { + return locationAnnotation; + } + return 'global'; +}; diff --git a/plugins/cloudbuild/src/components/useWorkflowRuns.ts b/plugins/cloudbuild/src/components/useWorkflowRuns.ts index 86168018d4..7e3e148dd1 100644 --- a/plugins/cloudbuild/src/components/useWorkflowRuns.ts +++ b/plugins/cloudbuild/src/components/useWorkflowRuns.ts @@ -35,9 +35,10 @@ export type WorkflowRun = { export function useWorkflowRuns(options: { projectId: string; + location: string; cloudBuildFilter: string; }) { - const { projectId, cloudBuildFilter } = options; + const { projectId, location, cloudBuildFilter } = options; const api = useApi(cloudbuildApiRef); const errorApi = useApi(errorApiRef); @@ -54,6 +55,7 @@ export function useWorkflowRuns(options: { return api .listWorkflowRuns({ projectId, + location, cloudBuildFilter, }) .then( @@ -69,6 +71,7 @@ export function useWorkflowRuns(options: { try { await api.reRunWorkflow({ projectId, + location, runId: run.id, }); } catch (e) {