Skip to content

fix(services): deployment timer - #2903

Open
rmnbrd wants to merge 6 commits into
stagingfrom
fix-deploy-build-timer
Open

fix(services): deployment timer#2903
rmnbrd wants to merge 6 commits into
stagingfrom
fix-deploy-build-timer

Conversation

@rmnbrd

@rmnbrd rmnbrd commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Goal

Keep deployment duration displays accurate and consistent while a deployment is progressing and after it completes.

Previously, ongoing timers could remain frozen at the last backend duration or measure from the wrong timestamp. The deployment logs header also displayed computing time after completion, while the deployment history displayed the full duration.

Changes

  • Derive an ongoing step's duration from its backend started_at timestamp and refresh it locally every second.
  • Sum recorded durations from completed steps with the live elapsed duration of the ongoing step.
  • Use the same shared step-duration helpers in the deployment log header and the Build, Deploy, and Executing filters.
  • Display total_duration_sec in the completed deployment header, with computing duration as a compatibility fallback.
  • Use the shared useIntervalTick hook to make the live-refresh behavior explicit and ensure interval cleanup.
  • Add component regression tests and direct unit tests for completed, ongoing, missing, invalid, future, aggregate, and empty step-duration cases.

@nx-cloud

nx-cloud Bot commented Aug 25, 2026

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit 192fd55

Command Status Duration Result
nx run console:build --parallel=3 --configurati... ✅ Succeeded 3s View ↗
nx affected --target=test --parallel=3 --config... ✅ Succeeded 30s View ↗
nx affected --target=lint --parallel=3 ✅ Succeeded 2m 28s View ↗
nx-cloud record -- yarn nx format:check ✅ Succeeded 6s View ↗

💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗


☁️ Nx Cloud last updated this comment at 2026-08-28 14:27:29 UTC

@codecov

codecov Bot commented Aug 25, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 78.26087% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 48.52%. Comparing base (1feda76) to head (192fd55).
⚠️ Report is 1 commits behind head on staging.

Files with missing lines Patch % Lines
...ent-logs/filters-stage-step/filters-stage-step.tsx 81.25% 0 Missing and 3 partials ⚠️
...e-logs/feature/src/lib/header-logs/header-logs.tsx 33.33% 0 Missing and 2 partials ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           staging    #2903      +/-   ##
===========================================
+ Coverage    48.49%   48.52%   +0.03%     
===========================================
  Files         1303     1304       +1     
  Lines        28117    28128      +11     
  Branches      8215     8220       +5     
===========================================
+ Hits         13634    13648      +14     
+ Misses       12187    12186       -1     
+ Partials      2296     2294       -2     
Flag Coverage Δ
unittests 48.52% <78.26%> (+0.03%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@rmnbrd
rmnbrd force-pushed the fix-deploy-build-timer branch from b11a3b2 to 0e3772e Compare August 26, 2026 14:23
rmnbrd added 2 commits August 28, 2026 13:51
- Use generated service step metrics for ongoing duration tracking
- Bump qovery-typescript-axios to 1.1.961
@rmnbrd
rmnbrd force-pushed the fix-deploy-build-timer branch from 78d9fab to 6045774 Compare August 28, 2026 11:54
@rmnbrd
rmnbrd marked this pull request as ready for review August 28, 2026 14:26
Copilot AI lite review requested due to automatic review settings August 28, 2026 14:26
@rmnbrd

rmnbrd commented Aug 28, 2026

Copy link
Copy Markdown
Contributor Author

@cubic-dev-ai Review this PR please

@cubic-dev-ai

cubic-dev-ai Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai Review this PR please

@rmnbrd I have started the AI code review. It will take a few minutes to complete.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR standardizes how deployment step durations are computed and displayed in the Service Logs UI, ensuring ongoing deployments tick locally based on backend started_at data and completed deployments show consistent totals.

Changes:

  • Introduces shared helpers to compute per-step and aggregate durations (including live elapsed time for ongoing steps).
  • Updates the deployment log header and the Build/Deploy/Executing stage filters to use these shared duration helpers and a 1s tick via useIntervalTick.
  • Adds unit and component tests covering completed, ongoing, invalid/missing timestamps, future starts, and aggregation behavior.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
libs/domains/service-logs/feature/src/lib/service-step-metrics.ts Adds shared helper functions for step-level and aggregate duration calculation.
libs/domains/service-logs/feature/src/lib/service-step-metrics.spec.ts Adds unit tests for duration helpers across edge cases.
libs/domains/service-logs/feature/src/lib/list-deployment-logs/filters-stage-step/filters-stage-step.tsx Uses shared duration helpers + useIntervalTick to keep stage durations live and consistent.
libs/domains/service-logs/feature/src/lib/list-deployment-logs/filters-stage-step/filters-stage-step.spec.tsx Adds regression tests validating live ticking from started_at and completed duration behavior.
libs/domains/service-logs/feature/src/lib/header-logs/header-logs.tsx Switches header duration computation to shared helpers and prefers total_duration_sec when completed.
libs/domains/service-logs/feature/src/lib/header-logs/header-logs.spec.tsx Adds tests for completed deployment totals and live ongoing aggregation/ticking.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines 56 to +60
useIntervalTick(isOngoing)

const totalDurationSec =
isOngoing && serviceStatus?.last_deployment_date
? Math.floor((Date.now() - new Date(serviceStatus.last_deployment_date).getTime()) / 1000)
: serviceStatus?.steps?.total_computing_duration_sec ?? 0
const totalDurationSec = isOngoing
? getServiceStepsDurationSec(serviceStatus.steps?.details ?? [], Date.now())
: serviceStatus.steps?.total_duration_sec ?? serviceStatus.steps?.total_computing_duration_sec ?? 0

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 6 files

Confidence score: 3/5

  • In libs/domains/service-logs/feature/src/lib/header-logs/header-logs.tsx, the ongoing-deployment timer depends entirely on populated steps.details; missing or incomplete timing fields can make the header show an incorrect near-zero duration. Add a reliable fallback for ongoing deployments.
  • In libs/domains/service-logs/feature/src/lib/service-step-metrics.ts, an ONGOING step with a valid duration_sec but malformed started_at is reduced to 0, underreporting metrics; preserve the recorded duration when the start timestamp is invalid.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="libs/domains/service-logs/feature/src/lib/header-logs/header-logs.tsx">

<violation number="1" location="libs/domains/service-logs/feature/src/lib/header-logs/header-logs.tsx:59">
P2: For an ongoing deployment, the new timer derives entirely from `steps.details`. If those details are empty or lack a populated ongoing `started_at`/`duration_sec`, `getServiceStepsDurationSec` returns ~0 and the header freezes there, whereas the previous logic measured from `last_deployment_date` and always showed real elapsed time. Consider falling back to the `last_deployment_date`-based elapsed time when the step aggregation yields no live/recorded duration.</violation>
</file>

<file name="libs/domains/service-logs/feature/src/lib/service-step-metrics.ts">

<violation number="1" location="libs/domains/service-logs/feature/src/lib/service-step-metrics.ts:7">
P3: An ONGOING step with a valid backend `duration_sec` but a malformed `started_at` returns `0` instead of the recorded duration, because the `Number.isFinite` branch hardcodes `0`. This is inconsistent with the `!step.started_at` branch, which falls back to `duration_sec`, and can regress the 'frozen at last backend duration' symptom this PR fixes. Fall back to `step.duration_sec || 0` when the parse fails.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

? Math.floor((Date.now() - new Date(serviceStatus.last_deployment_date).getTime()) / 1000)
: serviceStatus?.steps?.total_computing_duration_sec ?? 0
const totalDurationSec = isOngoing
? getServiceStepsDurationSec(serviceStatus.steps?.details ?? [], Date.now())

@cubic-dev-ai cubic-dev-ai Bot Aug 28, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: For an ongoing deployment, the new timer derives entirely from steps.details. If those details are empty or lack a populated ongoing started_at/duration_sec, getServiceStepsDurationSec returns ~0 and the header freezes there, whereas the previous logic measured from last_deployment_date and always showed real elapsed time. Consider falling back to the last_deployment_date-based elapsed time when the step aggregation yields no live/recorded duration.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At libs/domains/service-logs/feature/src/lib/header-logs/header-logs.tsx, line 59:

<comment>For an ongoing deployment, the new timer derives entirely from `steps.details`. If those details are empty or lack a populated ongoing `started_at`/`duration_sec`, `getServiceStepsDurationSec` returns ~0 and the header freezes there, whereas the previous logic measured from `last_deployment_date` and always showed real elapsed time. Consider falling back to the `last_deployment_date`-based elapsed time when the step aggregation yields no live/recorded duration.</comment>

<file context>
@@ -54,10 +55,9 @@ export function HeaderLogs({
-      ? Math.floor((Date.now() - new Date(serviceStatus.last_deployment_date).getTime()) / 1000)
-      : serviceStatus?.steps?.total_computing_duration_sec ?? 0
+  const totalDurationSec = isOngoing
+    ? getServiceStepsDurationSec(serviceStatus.steps?.details ?? [], Date.now())
+    : serviceStatus.steps?.total_duration_sec ?? serviceStatus.steps?.total_computing_duration_sec ?? 0
 
</file context>
Fix with cubic

if (step.status !== 'ONGOING' || !step.started_at) return step.duration_sec || 0

const startedAtMs = Date.parse(step.started_at)
return Number.isFinite(startedAtMs) ? Math.max(0, Math.floor((nowMs - startedAtMs) / 1_000)) : 0

@cubic-dev-ai cubic-dev-ai Bot Aug 28, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: An ONGOING step with a valid backend duration_sec but a malformed started_at returns 0 instead of the recorded duration, because the Number.isFinite branch hardcodes 0. This is inconsistent with the !step.started_at branch, which falls back to duration_sec, and can regress the 'frozen at last backend duration' symptom this PR fixes. Fall back to step.duration_sec || 0 when the parse fails.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At libs/domains/service-logs/feature/src/lib/service-step-metrics.ts, line 7:

<comment>An ONGOING step with a valid backend `duration_sec` but a malformed `started_at` returns `0` instead of the recorded duration, because the `Number.isFinite` branch hardcodes `0`. This is inconsistent with the `!step.started_at` branch, which falls back to `duration_sec`, and can regress the 'frozen at last backend duration' symptom this PR fixes. Fall back to `step.duration_sec || 0` when the parse fails.</comment>

<file context>
@@ -0,0 +1,12 @@
+  if (step.status !== 'ONGOING' || !step.started_at) return step.duration_sec || 0
+
+  const startedAtMs = Date.parse(step.started_at)
+  return Number.isFinite(startedAtMs) ? Math.max(0, Math.floor((nowMs - startedAtMs) / 1_000)) : 0
+}
+
</file context>
Suggested change
return Number.isFinite(startedAtMs) ? Math.max(0, Math.floor((nowMs - startedAtMs) / 1_000)) : 0
return Number.isFinite(startedAtMs) ? Math.max(0, Math.floor((nowMs - startedAtMs) / 1_000)) : step.duration_sec || 0
Fix with cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants