Repository navigation
feat(ui): show how long each promotion step took - #6807
Merged
Marvin9 merged 2 commits intoAug 19, 2026
Merged
Conversation
The promotion view showed a duration for the promotion as a whole, but individual steps showed only their status, so there was no way to tell which step accounted for a slow promotion without inspecting the Promotion resource by hand. Render an elapsed time against each step. A finished step is measured from startedAt to finishedAt; a running step counts up from startedAt on a one second tick, which distinguishes a step that is stuck from one that is merely slow. Steps that have not started show nothing. The data was already present in status.stepExecutionMetadata and already exposed on the generated StepExecutionMetadata model, so no API, CRD or codegen change is required. Durations under one second render as "<1s" rather than "0ms": API timestamps are RFC 3339 with second precision, so every sub-second step computes to exactly zero and "0ms" would imply a precision the data does not have. Signed-off-by: Utkarsh Bhatnagar <utkarsh.cmu@gmail.com>
✅ Deploy Preview for docs-kargo-io ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
2 tasks done
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6807 +/- ##
==========================================
+ Coverage 30.84% 30.90% +0.05%
==========================================
Files 826 829 +3
Lines 80666 80864 +198
==========================================
+ Hits 24885 24990 +105
- Misses 54327 54418 +91
- Partials 1454 1456 +2 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Marvin9
reviewed
Aug 18, 2026
Marvin9
left a comment
Contributor
There was a problem hiding this comment.
Pushing some refactors and bug that makes duration counter ticks continuously even though promotion is failed
Marvin9
reviewed
Aug 18, 2026
| const TICK_INTERVAL_MS = 1000; | ||
|
|
||
| export const StepDuration = ({ meta }: { meta?: StepExecutionMetadata }) => { | ||
| const running = !!meta?.startedAt && !meta?.finishedAt; |
Contributor
There was a problem hiding this comment.
this means that any terminated promotion will count as a running promotion
Refines the step duration display. StepDuration now takes the Promotion and a step index rather than a pre-extracted StepExecutionMetadata, so the component that needs a step's metadata is the one that looks it up and Step no longer relays a prop it never uses itself. Running and settled steps are separated: the settled case is straight inline logic, while a running step keeps a component of its own because mounting is what starts and stops its interval -- a hook could not be called conditionally, so every settled step would tick forever. A step that a Promotion cut short is never stamped with its own finishedAt, so the Promotion's finishedAt stands in and the step still reports how long it actually ran. Whether a step is still executing is answered by the existing getPromotionDirectiveStepStatus rather than by a new predicate. Signed-off-by: Mayursinh Sarvaiya <marvinduff97@gmail.com>
Marvin9
approved these changes
Aug 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Closes #6806
The promotion view shows a duration for the promotion as a whole, but individual steps show only their status. When a promotion is slow there is no way to tell which step accounted for it without inspecting the
Promotionresource by hand.This renders an elapsed time against each step:
startedAttofinishedAt.startedAton a one second tick, which is what distinguishes a step that is stuck from one that is merely slow.The data was already present in
status.stepExecutionMetadataand already exposed on the generatedStepExecutionMetadatamodel, so there is no API, CRD or codegen change — this is purely presentational.Completed promotion
git-clonetook 2s; the two sub-second steps read<1s.Running promotion — before / after
Before, a running promotion showed no timing at all (note the promotion-level
durationrow is absent entirely until the promotion is terminal):After, the running step reports how long it has been waiting:
Live counter
The elapsed time on a running step ticks, then settles on its final value when the step reaches a terminal state:
Notes for reviewers
<1srather than0ms. API timestamps are RFC 3339 with second precision, so every sub-second step computes to exactly0. Rendering that as0mswould imply a precision the data does not have, so a zero duration renders as<1s. Non-zero sub-second values are still formatted exactly, in case finer-grained timestamps arrive later.Clock skew. If the browser clock is behind the control plane, a running step's elapsed time would go negative;
stepDurationMsreturnsnullin that case so nothing is rendered rather than showing-3s.Timer scope. The one second interval is owned by a small
StepDurationcomponent and only runs while a step is actually running, so finished steps do not hold a timer.Out of scope. While testing this I noticed the promotion drawer does not refetch while it is open, so a step reaching a terminal state is only reflected after the view is reopened (the elapsed time itself ticks client-side regardless). That is pre-existing behaviour and untouched here — happy to open a separate issue for it.
Tested against a real promotion in a local kind cluster, including a step left running for 20+ minutes.
Checklist
Eligibility
kind/proposal,needs discussion,needs research,maintainer only,area/security,size/large,size/x-large,size/xx-large).Quality
AI Use Disclosure
This PR was written:
Sign-Off
All commits:
git commit -s) (required)git commit -S) (encouraged)🤖 Generated with Claude Code