From 7a7e0059e867d420f3d093e5302b7fe252e0c4b6 Mon Sep 17 00:00:00 2001 From: Alan Greene Date: Fri, 22 Mar 2024 18:18:33 +0000 Subject: [PATCH] Add pages for StepActions Add list and details pages for the v1alpha1 StepActions resources following the same pattern as the existing Tasks / Pipelines page. The only difference is that we don't link to associated runs or provide the ability to create a run as a StepAction must be used in a Task and cannot be run standalone. --- base/200-clusterrole-tenant.yaml | 3 +- .../read-write/clusterrole-tenant-patch.yaml | 3 +- packages/e2e/cypress/fixtures/kinds.json | 1 + packages/utils/src/utils/router.js | 10 +- src/api/index.js | 1 + src/api/stepActions.js | 72 +++++ src/api/stepActions.test.js | 87 ++++++ src/containers/App/App.jsx | 11 + .../CustomResourceDefinition.jsx | 5 +- src/containers/SideNav/SideNav.jsx | 7 +- src/containers/StepActions/StepActions.jsx | 264 ++++++++++++++++++ src/containers/StepActions/index.js | 15 + src/containers/index.js | 3 +- src/nls/messages_de.json | 1 + src/nls/messages_en.json | 1 + src/nls/messages_es.json | 1 + src/nls/messages_fr.json | 1 + src/nls/messages_it.json | 1 + src/nls/messages_ja.json | 1 + src/nls/messages_ko.json | 1 + src/nls/messages_pt.json | 1 + src/nls/messages_zh-Hans.json | 1 + src/nls/messages_zh-Hant.json | 1 + 23 files changed, 486 insertions(+), 6 deletions(-) create mode 100644 src/api/stepActions.js create mode 100644 src/api/stepActions.test.js create mode 100644 src/containers/StepActions/StepActions.jsx create mode 100644 src/containers/StepActions/index.js diff --git a/base/200-clusterrole-tenant.yaml b/base/200-clusterrole-tenant.yaml index 66d338130..98d2609b9 100644 --- a/base/200-clusterrole-tenant.yaml +++ b/base/200-clusterrole-tenant.yaml @@ -1,4 +1,4 @@ -# Copyright 2019-2023 The Tekton Authors +# Copyright 2019-2024 The Tekton Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -44,6 +44,7 @@ rules: - apiGroups: - tekton.dev resources: + - stepactions - tasks - taskruns - pipelines diff --git a/overlays/patches/read-write/clusterrole-tenant-patch.yaml b/overlays/patches/read-write/clusterrole-tenant-patch.yaml index 9cc35435c..5707dbef3 100644 --- a/overlays/patches/read-write/clusterrole-tenant-patch.yaml +++ b/overlays/patches/read-write/clusterrole-tenant-patch.yaml @@ -1,4 +1,4 @@ -# Copyright 2020-2023 The Tekton Authors +# Copyright 2020-2024 The Tekton Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ apiGroups: - tekton.dev resources: + - stepactions - tasks - taskruns - pipelines diff --git a/packages/e2e/cypress/fixtures/kinds.json b/packages/e2e/cypress/fixtures/kinds.json index d4207a1aa..4c002ec70 100644 --- a/packages/e2e/cypress/fixtures/kinds.json +++ b/packages/e2e/cypress/fixtures/kinds.json @@ -5,6 +5,7 @@ { "label": "ClusterTasks", "path": "/clustertasks" }, { "label": "TaskRuns", "path": "/taskruns" }, { "label": "CustomRuns", "path": "/customruns" }, + { "label": "StepActions", "path": "/stepactions" }, { "label": "EventListeners", "path": "/eventlisteners" }, { "label": "Triggers", "path": "/triggers" }, { "label": "TriggerBindings", "path": "/triggerbindings" }, diff --git a/packages/utils/src/utils/router.js b/packages/utils/src/utils/router.js index cafde225c..416827b3f 100644 --- a/packages/utils/src/utils/router.js +++ b/packages/utils/src/utils/router.js @@ -1,5 +1,5 @@ /* -Copyright 2019-2023 The Tekton Authors +Copyright 2019-2024 The Tekton 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 @@ -146,6 +146,14 @@ export const paths = { settings() { return '/settings'; }, + stepActions: { + all() { + return '/stepactions'; + }, + byNamespace() { + return byNamespace({ path: '/stepactions' }); + } + }, taskRuns: { all() { return '/taskruns'; diff --git a/src/api/index.js b/src/api/index.js index 3275c8303..fc52bc2b1 100644 --- a/src/api/index.js +++ b/src/api/index.js @@ -43,6 +43,7 @@ export * from './interceptors'; export * from './pipelineRuns'; export * from './pipelines'; export * from './serviceAccounts'; +export * from './stepActions'; export * from './taskRuns'; export * from './tasks'; export * from './triggerBindings'; diff --git a/src/api/stepActions.js b/src/api/stepActions.js new file mode 100644 index 000000000..22f831a92 --- /dev/null +++ b/src/api/stepActions.js @@ -0,0 +1,72 @@ +/* +Copyright 2024 The Tekton 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 { deleteRequest, get } from './comms'; +import { + getQueryParams, + getTektonAPI, + useCollection, + useResource +} from './utils'; + +function getStepActionsAPI({ filters, isWebSocket, name, namespace }) { + return getTektonAPI( + 'stepactions', + { isWebSocket, namespace, version: 'v1alpha1' }, + getQueryParams({ filters, name }) + ); +} + +export function getStepActions({ filters = [], namespace } = {}) { + const uri = getStepActionsAPI({ filters, namespace }); + return get(uri); +} + +export function getStepAction({ name, namespace }) { + const uri = getTektonAPI('stepactions', { + name, + namespace, + version: 'v1alpha1' + }); + return get(uri); +} + +export function deleteStepAction({ name, namespace }) { + const uri = getTektonAPI('stepactions', { + name, + namespace, + version: 'v1alpha1' + }); + return deleteRequest(uri); +} + +export function useStepActions(params) { + const webSocketURL = getStepActionsAPI({ ...params, isWebSocket: true }); + return useCollection({ + api: getStepActions, + kind: 'StepAction', + params, + webSocketURL + }); +} + +export function useStepAction(params, queryConfig) { + const webSocketURL = getStepActionsAPI({ ...params, isWebSocket: true }); + return useResource({ + api: getStepAction, + kind: 'StepAction', + params, + queryConfig, + webSocketURL + }); +} diff --git a/src/api/stepActions.test.js b/src/api/stepActions.test.js new file mode 100644 index 000000000..6942a0f46 --- /dev/null +++ b/src/api/stepActions.test.js @@ -0,0 +1,87 @@ +/* +Copyright 2024 The Tekton 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 { http, HttpResponse } from 'msw'; + +import * as API from './stepActions'; +import * as utils from './utils'; +import { server } from '../../config_frontend/msw'; + +it('getStepActions', () => { + const data = { + items: 'stepactions' + }; + server.use(http.get(/\/stepactions\//, () => HttpResponse.json(data))); + return API.getStepActions().then(stepActions => { + expect(stepActions).toEqual(data); + }); +}); + +it('getStepAction', () => { + const name = 'foo'; + const data = { fake: 'stepAction' }; + server.use(http.get(new RegExp(`/${name}$`), () => HttpResponse.json(data))); + return API.getStepAction({ name }).then(stepAction => { + expect(stepAction).toEqual(data); + }); +}); + +it('deleteStepAction', () => { + const name = 'foo'; + const data = { fake: 'stepAction' }; + server.use( + http.delete(new RegExp(`/${name}$`), () => HttpResponse.json(data)) + ); + return API.deleteStepAction({ name }).then(stepAction => { + expect(stepAction).toEqual(data); + }); +}); + +it('useStepActions', () => { + const query = { fake: 'query' }; + const params = { fake: 'params' }; + vi.spyOn(utils, 'useCollection').mockImplementation(() => query); + expect(API.useStepActions(params)).toEqual(query); + expect(utils.useCollection).toHaveBeenCalledWith( + expect.objectContaining({ + api: API.getStepActions, + kind: 'StepAction', + params + }) + ); +}); + +it('useStepAction', () => { + const query = { fake: 'query' }; + const params = { fake: 'params' }; + vi.spyOn(utils, 'useResource').mockImplementation(() => query); + expect(API.useStepAction(params)).toEqual(query); + expect(utils.useResource).toHaveBeenCalledWith( + expect.objectContaining({ + api: API.getStepAction, + kind: 'StepAction', + params + }) + ); + + const queryConfig = { fake: 'queryConfig' }; + API.useStepAction(params, queryConfig); + expect(utils.useResource).toHaveBeenCalledWith( + expect.objectContaining({ + api: API.getStepAction, + kind: 'StepAction', + params, + queryConfig + }) + ); +}); diff --git a/src/containers/App/App.jsx b/src/containers/App/App.jsx index e7681e33b..c54cf5d3c 100644 --- a/src/containers/App/App.jsx +++ b/src/containers/App/App.jsx @@ -65,6 +65,7 @@ import { ResourceList, Settings, SideNav, + StepActions, TaskRun, TaskRuns, Tasks, @@ -293,6 +294,16 @@ export function App({ lang }) { + + + + + + + + + + diff --git a/src/containers/CustomResourceDefinition/CustomResourceDefinition.jsx b/src/containers/CustomResourceDefinition/CustomResourceDefinition.jsx index 42f251e93..5fb939282 100644 --- a/src/containers/CustomResourceDefinition/CustomResourceDefinition.jsx +++ b/src/containers/CustomResourceDefinition/CustomResourceDefinition.jsx @@ -1,5 +1,5 @@ /* -Copyright 2019-2023 The Tekton Authors +Copyright 2019-2024 The Tekton 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 @@ -28,6 +28,7 @@ import { useCustomResource, useInterceptor, usePipeline, + useStepAction, useTask } from '../../api'; @@ -41,6 +42,8 @@ function useResource({ group, name, namespace, type, version }) { return useInterceptor({ name, namespace }); case 'pipelines': return usePipeline({ name, namespace }); + case 'stepactions': + return useStepAction({ name, namespace }); case 'tasks': return useTask({ name, namespace }); default: diff --git a/src/containers/SideNav/SideNav.jsx b/src/containers/SideNav/SideNav.jsx index 8d267588c..83bb41d30 100644 --- a/src/containers/SideNav/SideNav.jsx +++ b/src/containers/SideNav/SideNav.jsx @@ -1,5 +1,5 @@ /* -Copyright 2019-2023 The Tekton Authors +Copyright 2019-2024 The Tekton 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 @@ -124,6 +124,11 @@ function SideNav({ expanded, showKubernetesResources = false }) { > CustomRuns + + StepActions + {isTriggersInstalled && ( ({ + id: stepAction.metadata.uid, + name: ( + + {stepAction.metadata.name} + + ), + namespace: stepAction.metadata.namespace, + createdTime: ( + + ), + actions: !isReadOnly ? ( +