fix: workflowruns view, trigger, logs view when using clusterworkflows#392
fix: workflowruns view, trigger, logs view when using clusterworkflows#392akila-i wants to merge 5 commits intoopenchoreo:mainfrom
Conversation
- Added a description field to the WorkflowOption interface for improved clarity. - Updated the BuildWorkflowPicker component to render workflow descriptions below their names, enhancing user experience. - Utilized Material-UI's Box and Typography components for better layout and styling of workflow options. Signed-off-by: Akila-I <akila.99g@gmail.com>
- Introduced a new route for displaying workflow runs specific to cluster-scoped workflows. - Implemented a namespace selector for ClusterWorkflow entities, allowing users to choose the appropriate OpenChoreo namespace for querying WorkflowRun CRs. - Added hooks to fetch OpenChoreo namespaces and updated existing hooks to support namespace selection for workflow runs. - Enhanced the WorkflowRunsContent component to handle both namespace-scoped and cluster-scoped workflows, improving user experience and functionality. Signed-off-by: Akila-I <akila.99g@gmail.com>
- Added `isClusterScoped` parameter to the workflow run creation API, allowing users to specify if the workflow is a cluster-scoped `ClusterWorkflow`. - Updated the `GenericWorkflowsClient` and backend router to handle the new parameter, ensuring correct workflow type resolution. - Enhanced the `TriggerForm` component to set the workflow kind based on the `isClusterScoped` flag, improving user experience and functionality. Signed-off-by: Akila-I <akila.99g@gmail.com>
- Added `namespaceName` prop to `WorkflowRunStepLogs`, `WorkflowRunEvents`, and `RunDetailView` components, allowing explicit namespace overrides for better handling of cluster-scoped workflows. - Updated hooks and components to utilize the resolved namespace, improving the fetching of workflow run details and logs. - Enhanced tests to ensure proper functionality with the new namespace handling. This update improves user experience by providing clearer context for workflow runs across different namespaces. Signed-off-by: Akila-I <akila.99g@gmail.com>
- Replaced `isClusterScoped` with `workflowKind` in the API and components to better differentiate between `Workflow` and `ClusterWorkflow`. - Updated `GenericWorkflowsClient`, `GenericWorkflowsClientApi`, and related components to utilize the new `workflowKind` parameter for improved clarity and functionality. - Enhanced the `TriggerForm` and `useWorkflowSchema` hooks to accommodate the new parameter, ensuring correct schema fetching based on workflow type. - Adjusted backend service logic to handle the `workflowKind` parameter for creating workflow runs. This change streamlines the workflow handling process and improves the overall codebase consistency. Signed-off-by: Akila-I <akila.99g@gmail.com>
📝 WalkthroughWalkthroughThis pull request introduces cluster-scoped workflow support (ClusterWorkflow) throughout the OpenChoreo plugin stack. Changes include new backend API endpoints for fetching cluster workflow schemas and listing namespaces, frontend components that display a namespace selector for ClusterWorkflow entities, updated hooks that accept explicit namespace parameters with fallback to context, and modifications to thread workflowKind and namespace information through the workflow runs UI pipeline. Changes
Sequence Diagram(s)sequenceDiagram
participant User as User
participant Frontend as Frontend (WorkflowRunsContent)
participant Hook as useWorkflowSchema Hook
participant Client as GenericWorkflowsClient
participant API as Backend API
participant Service as GenericWorkflowService
User->>Frontend: Select ClusterWorkflow entity
Frontend->>Frontend: Initialize workflowKind = 'ClusterWorkflow'
Frontend->>Hook: Call useWorkflowSchema(workflowName, 'ClusterWorkflow')
activate Hook
Hook->>Hook: Branch: workflowKind === 'ClusterWorkflow'
Hook->>Client: Call getClusterWorkflowSchema(workflowName)
deactivate Hook
activate Client
Client->>API: GET /cluster-workflows/{name}/schema
deactivate Client
activate API
API->>Service: Call getClusterWorkflowSchema(name, userToken)
deactivate API
activate Service
Service->>Service: Fetch cluster workflow schema via OpenChoreo API
Service-->>API: Return schema JSON
deactivate Service
API-->>Client: Return 200 with schema
Client-->>Hook: Return schema object
Hook-->>Frontend: Update schema state
Frontend->>Frontend: Render form with cluster workflow schema
User->>Frontend: Submit workflow parameters
Frontend->>Client: Call createWorkflowRun(namespace, name, params, 'ClusterWorkflow')
Client->>API: POST /runs with workflowKind
API->>Service: Create run with kind parameter
Service-->>API: Return created WorkflowRun
API-->>Client: Return 201
Client-->>Frontend: Return run object
Frontend->>Frontend: Display run in list
sequenceDiagram
participant User as User
participant Frontend as Frontend (WorkflowRunsContent)
participant NamespaceHook as useNamespaces Hook
participant RunDetailsHook as useWorkflowRunDetails Hook
participant Client as GenericWorkflowsClient
participant API as Backend API
participant Service as GenericWorkflowService
User->>Frontend: View ClusterWorkflow runs
Frontend->>NamespaceHook: Call useNamespaces()
activate NamespaceHook
NamespaceHook->>Client: Call listNamespaces()
deactivate NamespaceHook
activate Client
Client->>API: GET /namespaces
deactivate Client
activate API
API->>Service: Call listNamespaces(userToken)
deactivate API
activate Service
Service->>Service: Fetch available namespaces from OpenChoreo
Service-->>API: Return namespace list
deactivate Service
API-->>Client: Return 200 with namespaces
Client-->>NamespaceHook: Return string[]
NamespaceHook-->>Frontend: Update namespaces state
Frontend->>Frontend: Render namespace selector dropdown
User->>Frontend: Select namespace from dropdown
Frontend->>Frontend: Update runsNamespace = selectedNamespace
Frontend->>RunDetailsHook: Call useWorkflowRunDetails(runName, runsNamespace)
activate RunDetailsHook
RunDetailsHook->>RunDetailsHook: Resolve namespace: runsNamespace ?? contextNamespace
RunDetailsHook->>Client: Fetch run details with namespace
Note over RunDetailsHook: Retry up to 5 times on NotFoundError (2s interval)
deactivate RunDetailsHook
Client-->>Frontend: Return run details
Frontend->>Frontend: Display run details scoped to selected namespace
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
packages/app/src/scaffolder/BuildWorkflowPicker/BuildWorkflowPickerExtension.tsx (1)
290-300: Consider truncating long descriptions to prevent dropdown overflow.The description display works correctly, but very long descriptions could cause the dropdown menu to overflow horizontally. Consider applying text truncation for better UX.
💡 Optional: Add text truncation with ellipsis
{workflow.description && ( - <Typography variant="body2" color="textSecondary"> + <Typography + variant="body2" + color="textSecondary" + style={{ + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + maxWidth: 300, + }} + title={workflow.description} + > {workflow.description} </Typography> )}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/app/src/scaffolder/BuildWorkflowPicker/BuildWorkflowPickerExtension.tsx` around lines 290 - 300, The workflow description can grow very long and cause the dropdown to overflow; update the rendering inside BuildWorkflowPickerExtension.tsx by applying CSS truncation to the description Typography (the element that renders workflow.description) — add styles like overflow: hidden, textOverflow: ellipsis, whiteSpace: nowrap and a sensible maxWidth or allow flexShrink so long descriptions are truncated with an ellipsis instead of expanding the MenuItem; keep getWorkflowDisplayName and the title Typography unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@plugins/openchoreo-workflows-backend/src/services/GenericWorkflowService.ts`:
- Around line 223-230: The client.GET call for the
'/api/v1/clusterworkflows/{clusterWorkflowName}/schema' endpoint in
GenericWorkflowService contains unnecessary "as any" casts that weaken type
safety; remove the "as any" casts around the path string and the options object
so the generated client types are used (locate the client.GET invocation in
GenericWorkflowService, referencing the
'/api/v1/clusterworkflows/{clusterWorkflowName}/schema' call and its params
object) and ensure the call matches the pattern used by other endpoints like
'/api/v1/namespaces/{namespaceName}/workflows/{workflowName}/schema'.
In
`@plugins/openchoreo-workflows/src/components/WorkflowRunsContent/WorkflowRunsContent.tsx`:
- Around line 748-759: The component currently calls setSelectedNamespace and
setNamespaceInitialised directly in the render body when workflowKind ===
'ClusterWorkflow' and namespaces are ready; move this logic into a useEffect to
avoid state updates during render. Create a useEffect that depends on
workflowKind, namespacesLoading, namespaces, and namespaceInitialised, and
inside the effect check the same conditions (workflowKind === 'ClusterWorkflow'
&& !namespacesLoading && namespaces.length > 0 && !namespaceInitialised),
compute the preferred namespace (prefer 'default' or namespaces[0]) and call
setSelectedNamespace(preferred) and setNamespaceInitialised(true) from within
the effect.
---
Nitpick comments:
In
`@packages/app/src/scaffolder/BuildWorkflowPicker/BuildWorkflowPickerExtension.tsx`:
- Around line 290-300: The workflow description can grow very long and cause the
dropdown to overflow; update the rendering inside
BuildWorkflowPickerExtension.tsx by applying CSS truncation to the description
Typography (the element that renders workflow.description) — add styles like
overflow: hidden, textOverflow: ellipsis, whiteSpace: nowrap and a sensible
maxWidth or allow flexShrink so long descriptions are truncated with an ellipsis
instead of expanding the MenuItem; keep getWorkflowDisplayName and the title
Typography unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: c5f3ccc0-d3c7-485a-894f-3c4d30ac77a5
📒 Files selected for processing (17)
packages/app/src/components/catalog/EntityPage.tsxpackages/app/src/scaffolder/BuildWorkflowPicker/BuildWorkflowPickerExtension.tsxplugins/openchoreo-workflows-backend/src/router.tsplugins/openchoreo-workflows-backend/src/services/GenericWorkflowService.tsplugins/openchoreo-workflows/src/api/GenericWorkflowsClient.tsplugins/openchoreo-workflows/src/api/GenericWorkflowsClientApi.tsplugins/openchoreo-workflows/src/components/EntityNamespaceProvider/EntityNamespaceProvider.tsxplugins/openchoreo-workflows/src/components/WorkflowRunDetailsPage/WorkflowRunDetailsPage.tsxplugins/openchoreo-workflows/src/components/WorkflowRunEvents/WorkflowRunEvents.tsxplugins/openchoreo-workflows/src/components/WorkflowRunStepLogs/WorkflowRunStepLogs.tsxplugins/openchoreo-workflows/src/components/WorkflowRunsContent/WorkflowRunsContent.tsxplugins/openchoreo-workflows/src/hooks/index.tsplugins/openchoreo-workflows/src/hooks/useNamespaces.tsplugins/openchoreo-workflows/src/hooks/useWorkflowRunDetails.tsplugins/openchoreo-workflows/src/hooks/useWorkflowRunLogs.tsplugins/openchoreo-workflows/src/hooks/useWorkflowRuns.tsplugins/openchoreo-workflows/src/hooks/useWorkflowSchema.ts
| const { data, error, response } = await client.GET( | ||
| '/api/v1/clusterworkflows/{clusterWorkflowName}/schema' as any, | ||
| { | ||
| params: { | ||
| path: { clusterWorkflowName }, | ||
| }, | ||
| } as any, | ||
| ); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if the clusterworkflows endpoint is defined in the OpenAPI spec
fd -e yaml -e json 'openchoreo-api' --exec grep -l 'clusterworkflows' {} \;Repository: openchoreo/backstage-plugins
Length of output: 133
🏁 Script executed:
cat -n packages/openchoreo-client-node/openapi/openchoreo-api.yaml | grep -A 20 "clusterworkflows.*schema"Repository: openchoreo/backstage-plugins
Length of output: 985
🏁 Script executed:
# Check the structure of the endpoint definition
grep -B 5 -A 15 "/clusterworkflows/{clusterWorkflowName}/schema" packages/openchoreo-client-node/openapi/openchoreo-api.yamlRepository: openchoreo/backstage-plugins
Length of output: 789
🏁 Script executed:
# Also check if there are other similar as any casts in the same file
rg "as any" plugins/openchoreo-workflows-backend/src/services/GenericWorkflowService.ts -B 2 -A 2Repository: openchoreo/backstage-plugins
Length of output: 1927
🏁 Script executed:
# Check if there's a generated types file for the client
find packages/openchoreo-client-node -name "*.ts" -o -name "*.d.ts" | grep -E "(types|client|schema)" | head -20Repository: openchoreo/backstage-plugins
Length of output: 1287
🏁 Script executed:
# Look for generated index or types that would export the operations
rg "getClusterWorkflowSchema" packages/openchoreo-client-node --type typescript --type jsonRepository: openchoreo/backstage-plugins
Length of output: 106
🏁 Script executed:
# Search for getClusterWorkflowSchema in the generated client files
rg "getClusterWorkflowSchema" packages/openchoreo-client-node/src/generated/Repository: openchoreo/backstage-plugins
Length of output: 282
🏁 Script executed:
# Check the structure of the generated openchoreo client index
head -100 packages/openchoreo-client-node/src/generated/openchoreo/index.tsRepository: openchoreo/backstage-plugins
Length of output: 204
🏁 Script executed:
# Check if ClusterWorkflowNameParam is properly typed in the generated types
rg "ClusterWorkflowNameParam" packages/openchoreo-client-node/src/generated/Repository: openchoreo/backstage-plugins
Length of output: 771
🏁 Script executed:
# Check the full definition of getClusterWorkflowSchema in the generated types
rg "getClusterWorkflowSchema" -A 20 packages/openchoreo-client-node/src/generated/openchoreo/types.tsRepository: openchoreo/backstage-plugins
Length of output: 1137
🏁 Script executed:
# Check the client.GET method signature to understand what it expects
rg "GET\(" packages/openchoreo-client-node/src/generated/openchoreo/index.ts -B 2 -A 5Repository: openchoreo/backstage-plugins
Length of output: 54
🏁 Script executed:
# Look at how other similar endpoints are called in GenericWorkflowService to compare
rg "client.GET" plugins/openchoreo-workflows-backend/src/services/GenericWorkflowService.ts -B 1 -A 5 | head -50Repository: openchoreo/backstage-plugins
Length of output: 1471
Remove unnecessary as any type assertions—the endpoint is properly typed in the generated client.
The /api/v1/clusterworkflows/{clusterWorkflowName}/schema endpoint is defined in the OpenAPI spec and fully generated in the client types. The as any casts on lines 224 and 229 are unnecessary and bypass type safety. Other similar endpoints in this file (e.g., /api/v1/namespaces/{namespaceName}/workflows/{workflowName}/schema) call client.GET without these casts. Remove the as any assertions and rely on the proper types.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@plugins/openchoreo-workflows-backend/src/services/GenericWorkflowService.ts`
around lines 223 - 230, The client.GET call for the
'/api/v1/clusterworkflows/{clusterWorkflowName}/schema' endpoint in
GenericWorkflowService contains unnecessary "as any" casts that weaken type
safety; remove the "as any" casts around the path string and the options object
so the generated client types are used (locate the client.GET invocation in
GenericWorkflowService, referencing the
'/api/v1/clusterworkflows/{clusterWorkflowName}/schema' call and its params
object) and ensure the call matches the pattern used by other endpoints like
'/api/v1/namespaces/{namespaceName}/workflows/{workflowName}/schema'.
| if ( | ||
| workflowKind === 'ClusterWorkflow' && | ||
| !namespacesLoading && | ||
| namespaces.length > 0 && | ||
| !namespaceInitialised | ||
| ) { | ||
| const preferred = namespaces.includes('default') | ||
| ? 'default' | ||
| : namespaces[0]; | ||
| setSelectedNamespace(preferred); | ||
| setNamespaceInitialised(true); | ||
| } |
There was a problem hiding this comment.
Avoid setting state directly in the render body; use useEffect instead.
Setting setSelectedNamespace and setNamespaceInitialised inside the component body (outside hooks/handlers) can cause unexpected behavior and violates React's rendering model. While the namespaceInitialised flag prevents infinite loops, this pattern is fragile and harder to reason about.
♻️ Proposed refactor to useEffect
- const [namespaceInitialised, setNamespaceInitialised] = useState(false);
- if (
- workflowKind === 'ClusterWorkflow' &&
- !namespacesLoading &&
- namespaces.length > 0 &&
- !namespaceInitialised
- ) {
- const preferred = namespaces.includes('default')
- ? 'default'
- : namespaces[0];
- setSelectedNamespace(preferred);
- setNamespaceInitialised(true);
- }
+ useEffect(() => {
+ if (
+ workflowKind === 'ClusterWorkflow' &&
+ !namespacesLoading &&
+ namespaces.length > 0
+ ) {
+ const preferred = namespaces.includes('default')
+ ? 'default'
+ : namespaces[0];
+ setSelectedNamespace(preferred);
+ }
+ }, [workflowKind, namespacesLoading, namespaces]);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@plugins/openchoreo-workflows/src/components/WorkflowRunsContent/WorkflowRunsContent.tsx`
around lines 748 - 759, The component currently calls setSelectedNamespace and
setNamespaceInitialised directly in the render body when workflowKind ===
'ClusterWorkflow' and namespaces are ready; move this logic into a useEffect to
avoid state updates during render. Create a useEffect that depends on
workflowKind, namespacesLoading, namespaces, and namespaceInitialised, and
inside the effect check the same conditions (workflowKind === 'ClusterWorkflow'
&& !namespacesLoading && namespaces.length > 0 && !namespaceInitialised),
compute the preferred namespace (prefer 'default' or namespaces[0]) and call
setSelectedNamespace(preferred) and setNamespaceInitialised(true) from within
the effect.
Purpose
Related: openchoreo/openchoreo#2562
This pull request introduces significant enhancements to support cluster-scoped workflows (ClusterWorkflows) in the OpenChoreo workflows UI and backend. The changes enable users to view, trigger, and manage runs for both namespace-scoped and cluster-scoped workflows, add support for selecting namespaces, and improve the display and handling of workflow metadata throughout the stack.
Backend API and Service Enhancements:
GenericWorkflowServiceto distinguish between cluster and namespace-scoped workflows when creating runs. [1] [2] [3]Client API Updates:
UI/UX Improvements for ClusterWorkflows:
EntityNamespaceProviderto correctly resolve the namespace for cluster-scoped entities, defaulting to "default" if not specified. [1] [2]Workflow Metadata Display:
Workflow Run Details Consistency:
These changes collectively enable robust support for both namespace and cluster-scoped workflows, improve user experience, and lay the groundwork for further extensibility in workflow management.
Goals
Approach
User stories
Release note
Documentation
Training
Certification
Marketing
Automation tests
Security checks
Samples
Related PRs
Migrations (if applicable)
Test environment
Learning
Summary by CodeRabbit
Release Notes