From 3a8080dbcb3dfcacdc6afae15660a1c0be9c3e68 Mon Sep 17 00:00:00 2001 From: Vikram Raj Date: Fri, 24 Nov 2023 12:45:29 +0530 Subject: [PATCH 1/2] Add Vulnerabilities column and signed icon in PAC repository PLR list --- .../repository/RepositoryPipelineRunHeader.tsx | 6 ++++++ .../repository/RepositoryPipelineRunRow.tsx | 13 +++++++++++++ 2 files changed, 19 insertions(+) diff --git a/frontend/packages/pipelines-plugin/src/components/repository/RepositoryPipelineRunHeader.tsx b/frontend/packages/pipelines-plugin/src/components/repository/RepositoryPipelineRunHeader.tsx index 019bb604fa8..2d0a026a371 100644 --- a/frontend/packages/pipelines-plugin/src/components/repository/RepositoryPipelineRunHeader.tsx +++ b/frontend/packages/pipelines-plugin/src/components/repository/RepositoryPipelineRunHeader.tsx @@ -36,6 +36,12 @@ const RepositoryPipelineRunHeader = () => { props: { className: tableColumnClasses[2] }, id: 'namespace', }, + { + title: i18n.t('pipelines-plugin~Vulnerabilities'), + sortFunc: 'vulnerabilities', + transforms: [sortable], + props: { className: tableColumnClasses[3] }, + }, { title: i18n.t('pipelines-plugin~Status'), sortField: 'status.conditions[0].reason', diff --git a/frontend/packages/pipelines-plugin/src/components/repository/RepositoryPipelineRunRow.tsx b/frontend/packages/pipelines-plugin/src/components/repository/RepositoryPipelineRunRow.tsx index 644e9c3ce17..e1fe186040c 100644 --- a/frontend/packages/pipelines-plugin/src/components/repository/RepositoryPipelineRunRow.tsx +++ b/frontend/packages/pipelines-plugin/src/components/repository/RepositoryPipelineRunRow.tsx @@ -10,6 +10,7 @@ import { ExternalLink, } from '@console/internal/components/utils'; import { referenceForModel } from '@console/internal/module/k8s'; +import * as SignedPipelinerunIcon from '../../images/signed-badge.svg'; import { PipelineRunModel } from '../../models'; import { PipelineRunKind, TaskRunKind } from '../../types'; import { getPipelineRunKebabActions } from '../../utils/pipeline-actions'; @@ -20,7 +21,9 @@ import { import { pipelineRunDuration } from '../../utils/pipeline-utils'; import LinkedPipelineRunTaskStatus from '../pipelineruns/status/LinkedPipelineRunTaskStatus'; import PipelineRunStatus from '../pipelineruns/status/PipelineRunStatus'; +import PipelineRunVulnerabilities from '../pipelineruns/status/PipelineRunVulnerabilities'; import { ResourceKebabWithUserLabel } from '../pipelineruns/triggered-by'; +import { chainsSignedAnnotation } from '../pipelines/const'; import { getTaskRunsOfPipelineRun } from '../taskruns/useTaskRuns'; import { RepositoryLabels, @@ -68,6 +71,13 @@ const RepositoryPipelineRunRow: React.FC> = ({ data-test-id={obj.metadata.name} nameSuffix={ <> + {obj?.metadata?.annotations?.[chainsSignedAnnotation] === 'true' ? ( + +
+ {t('pipelines-plugin~Signed')} +
+
+ ) : null} {obj?.metadata?.annotations?.['resource.deleted.in.k8s'] === 'true' ? (
@@ -103,6 +113,9 @@ const RepositoryPipelineRunRow: React.FC> = ({ + + + From 22d83637701f961717b386559c1b5252f6933b8a Mon Sep 17 00:00:00 2001 From: Vikram Raj Date: Fri, 24 Nov 2023 15:24:46 +0530 Subject: [PATCH 2/2] fix infinite call tekton-results API on Repository list and details page --- .../hooks/usePipelineRunVulnerabilities.ts | 3 +- .../pipelineruns/hooks/usePipelineRuns.ts | 16 ++++-- .../repository/RepositoryPipelineRunList.tsx | 2 +- .../RepositoryPipelineRunListPage.tsx | 13 +++-- .../repository/list-page/RepositoryRow.tsx | 52 ++++++++----------- .../repository/list-page/ReppositoryList.tsx | 12 +++-- .../src/utils/pipeline-utils.ts | 4 +- 7 files changed, 58 insertions(+), 44 deletions(-) diff --git a/frontend/packages/pipelines-plugin/src/components/pipelineruns/hooks/usePipelineRunVulnerabilities.ts b/frontend/packages/pipelines-plugin/src/components/pipelineruns/hooks/usePipelineRunVulnerabilities.ts index 33da809326e..bf32317565e 100644 --- a/frontend/packages/pipelines-plugin/src/components/pipelineruns/hooks/usePipelineRunVulnerabilities.ts +++ b/frontend/packages/pipelines-plugin/src/components/pipelineruns/hooks/usePipelineRunVulnerabilities.ts @@ -13,7 +13,8 @@ export type ScanResults = { }; export const getPipelineRunVulnerabilities = (pipelineRun: PipelineRunKind): ScanResults => { - return pipelineRun.status?.results?.reduce((acc, result) => { + const results = pipelineRun.status?.results || pipelineRun.status?.pipelineResults; + return results?.reduce((acc, result) => { if (result.name?.endsWith(SCAN_OUTPUT_SUFFIX)) { if (!acc.vulnerabilities) { acc.vulnerabilities = { critical: 0, high: 0, medium: 0, low: 0 }; diff --git a/frontend/packages/pipelines-plugin/src/components/pipelineruns/hooks/usePipelineRuns.ts b/frontend/packages/pipelines-plugin/src/components/pipelineruns/hooks/usePipelineRuns.ts index a5c606af6a3..4089b740b57 100644 --- a/frontend/packages/pipelines-plugin/src/components/pipelineruns/hooks/usePipelineRuns.ts +++ b/frontend/packages/pipelines-plugin/src/components/pipelineruns/hooks/usePipelineRuns.ts @@ -105,10 +105,9 @@ const useRuns = ( runs && trResources ? uniqBy([...runs, ...trResources], (r) => r.metadata.name) : runs || trResources; - return [ rResources, - namespace ? !!rResources?.[0] : false, + loaded || trLoaded, namespace ? queryTr ? isList @@ -119,7 +118,18 @@ const useRuns = ( : undefined, trGetNextPage, ]; - }, [error, trResources, trLoaded, trError, trGetNextPage, namespace, isList, queryTr, runs]); + }, [ + runs, + trResources, + loaded, + trLoaded, + namespace, + queryTr, + isList, + trError, + error, + trGetNextPage, + ]); }; export const usePipelineRuns = ( diff --git a/frontend/packages/pipelines-plugin/src/components/repository/RepositoryPipelineRunList.tsx b/frontend/packages/pipelines-plugin/src/components/repository/RepositoryPipelineRunList.tsx index 8e66d5c8569..3f0b256fecd 100644 --- a/frontend/packages/pipelines-plugin/src/components/repository/RepositoryPipelineRunList.tsx +++ b/frontend/packages/pipelines-plugin/src/components/repository/RepositoryPipelineRunList.tsx @@ -3,8 +3,8 @@ import { SortByDirection } from '@patternfly/react-table'; import { useTranslation } from 'react-i18next'; import { Table } from '@console/internal/components/factory'; import { PipelineRunModel } from '../../models'; +import { useTaskRuns } from '../pipelineruns/hooks/useTaskRuns'; import { usePipelineOperatorVersion } from '../pipelines/utils/pipeline-operator'; -import { useTaskRuns } from '../taskruns/useTaskRuns'; import RepositoryPipelineRunHeader from './RepositoryPipelineRunHeader'; import RepositoryPipelineRunRow from './RepositoryPipelineRunRow'; diff --git a/frontend/packages/pipelines-plugin/src/components/repository/RepositoryPipelineRunListPage.tsx b/frontend/packages/pipelines-plugin/src/components/repository/RepositoryPipelineRunListPage.tsx index 12225266676..dafcd3e139c 100644 --- a/frontend/packages/pipelines-plugin/src/components/repository/RepositoryPipelineRunListPage.tsx +++ b/frontend/packages/pipelines-plugin/src/components/repository/RepositoryPipelineRunListPage.tsx @@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next'; import { referenceForModel } from '@console/internal/module/k8s'; import { PipelineRunModel } from '../../models'; import { ListPage } from '../ListPage'; -import { useGetPipelineRuns } from '../pipelineruns/hooks/useTektonResults'; +import { usePipelineRuns } from '../pipelineruns/hooks/usePipelineRuns'; import { runFilters } from '../pipelines/detail-page-tabs/PipelineRuns'; import { RepositoryFields, RepositoryLabels } from './consts'; import RunList from './RepositoryPipelineRunList'; @@ -16,9 +16,16 @@ export interface RepositoryPipelineRunListPageProps { const RepositoryPipelineRunListPage: React.FC = (props) => { const { t } = useTranslation(); const { obj } = props; - const [pipelineRuns, pipelineRunsLoaded, pipelineRunsLoadError] = useGetPipelineRuns( + const selector = React.useMemo(() => { + return { + matchLabels: { [RepositoryLabels[RepositoryFields.REPOSITORY]]: obj.metadata.name }, + }; + }, [obj.metadata.name]); + const [pipelineRuns, pipelineRunsLoaded, pipelineRunsLoadError] = usePipelineRuns( obj.metadata.namespace, - { name: obj.metadata.name, kind: obj.kind }, + { + selector, + }, ); const resources = { [referenceForModel(PipelineRunModel)]: { diff --git a/frontend/packages/pipelines-plugin/src/components/repository/list-page/RepositoryRow.tsx b/frontend/packages/pipelines-plugin/src/components/repository/list-page/RepositoryRow.tsx index e37fc571e3f..daac7957c64 100644 --- a/frontend/packages/pipelines-plugin/src/components/repository/list-page/RepositoryRow.tsx +++ b/frontend/packages/pipelines-plugin/src/components/repository/list-page/RepositoryRow.tsx @@ -3,7 +3,6 @@ import { Link } from 'react-router-dom'; import { TableData, RowFunctionArgs } from '@console/internal/components/factory'; import { Kebab, - LoadingInline, ResourceIcon, ResourceKebab, ResourceLink, @@ -18,7 +17,6 @@ import { pipelineRunTitleFilterReducer, } from '../../../utils/pipeline-filter-reducer'; import { pipelineRunDuration } from '../../../utils/pipeline-utils'; -import { useGetPipelineRuns } from '../../pipelineruns/hooks/useTektonResults'; import LinkedPipelineRunTaskStatus from '../../pipelineruns/status/LinkedPipelineRunTaskStatus'; import PipelineRunStatus from '../../pipelineruns/status/PipelineRunStatus'; import { getTaskRunsOfPipelineRun } from '../../taskruns/useTaskRuns'; @@ -30,11 +28,13 @@ const RepositoryRow: React.FC> = ({ obj, customD const { metadata: { name, namespace }, } = obj; - const { taskRuns } = customData; - - const [pipelineRuns, loaded] = useGetPipelineRuns(namespace, { name, kind: obj.kind }); - - const latestRun = loaded && getLatestRun(pipelineRuns, 'creationTimestamp'); + const { taskRuns, pipelineRuns } = customData; + const plrs = pipelineRuns.filter((plr) => { + return ( + plr.metadata?.labels[RepositoryLabels[RepositoryFields.REPOSITORY]] === obj.metadata.name + ); + }); + const latestRun = getLatestRun(plrs, 'creationTimestamp'); const latestPLREventType = latestRun && latestRun?.metadata?.labels[RepositoryLabels[RepositoryFields.EVENT_TYPE]]; @@ -59,49 +59,39 @@ const RepositoryRow: React.FC> = ({ obj, customD {latestPLREventType || '-'} - {loaded ? ( - latestRun ? ( - - ) : ( - '-' - ) + {latestRun ? ( + ) : ( - + '-' )} {} - {loaded ? ( - latestRun ? ( - - ) : ( - '-' - ) + {latestRun ? ( + ) : ( - + '-' )} - {loaded ? ( + { - ) : ( - - )} + } - {loaded ? : } + {} - {loaded ? pipelineRunDuration(latestRun) : } + {pipelineRunDuration(latestRun)} diff --git a/frontend/packages/pipelines-plugin/src/components/repository/list-page/ReppositoryList.tsx b/frontend/packages/pipelines-plugin/src/components/repository/list-page/ReppositoryList.tsx index bdff0ee10ef..563a2134229 100644 --- a/frontend/packages/pipelines-plugin/src/components/repository/list-page/ReppositoryList.tsx +++ b/frontend/packages/pipelines-plugin/src/components/repository/list-page/ReppositoryList.tsx @@ -1,7 +1,8 @@ import * as React from 'react'; import { Table } from '@console/internal/components/factory'; import { RepositoryModel } from '../../../models'; -import { useGetTaskRuns } from '../../pipelineruns/hooks/useTektonResults'; +import { usePipelineRuns } from '../../pipelineruns/hooks/usePipelineRuns'; +import { useTaskRuns } from '../../pipelineruns/hooks/useTaskRuns'; import { RepositoryKind } from '../types'; import RepositoryHeader from './RepositoryHeader'; import RepositoryRow from './RepositoryRow'; @@ -12,15 +13,18 @@ export interface RepositoryListProps { } const RepositoryList: React.FC = (props) => { - const [taskRuns, taskRunsLoaded] = useGetTaskRuns(props.namespace); - + const [taskRuns, taskRunsLoaded] = useTaskRuns(props.namespace); + const [pipelineRuns, pipelineRunsLoaded] = usePipelineRuns(props.namespace); return ( ); diff --git a/frontend/packages/pipelines-plugin/src/utils/pipeline-utils.ts b/frontend/packages/pipelines-plugin/src/utils/pipeline-utils.ts index 0f173a807ca..31b4dd8c428 100644 --- a/frontend/packages/pipelines-plugin/src/utils/pipeline-utils.ts +++ b/frontend/packages/pipelines-plugin/src/utils/pipeline-utils.ts @@ -546,7 +546,9 @@ export const getSbomTaskRun = (taskruns: TaskRunKind[]): TaskRunKind => ); export const getSbomLink = (sbomTaskRun: TaskRunKind): string | undefined => - sbomTaskRun?.status?.results?.find((r) => r.name === 'LINK_TO_SBOM')?.value; + (sbomTaskRun?.status?.results || sbomTaskRun?.status?.taskResults)?.find( + (r) => r.name === 'LINK_TO_SBOM', + )?.value; export const taskRunStatus = (taskRun: TaskRunKind | PLRTaskRunData): ComputedStatus => { if (!taskRun?.status?.conditions?.length) { return ComputedStatus.Pending;