Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix: stop the template builder build progress bar from looping - #27276

Merged
jeremyruppel merged 2 commits into
mainfrom
jeremy/devex-593-stop-the-build-progress-bar-from-looping-repeatedly
Jul 16, 2026
Merged

fix: stop the template builder build progress bar from looping#27276
jeremyruppel merged 2 commits into
mainfrom
jeremy/devex-593-stop-the-build-progress-bar-from-looping-repeatedly

Conversation

@jeremyruppel

@jeremyruppel jeremyruppel commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Summary

The template builder's "Building your template" loader had a progress bar that
animated 0→100% every 5s with an infinite repeat, so it visibly restarted over
and over while a template built. It looked broken and was frustrating to watch.

This replaces the looping fill with a single ease-out fill that decelerates
toward 90% and holds until the request resolves and the loader unmounts.

Since the loader is intentionally indeterminate and no progress is streamed to
the browser, this also removes the now-dead onUpdate callback plumbing from
the backend waitForProvisionerJob (its only caller passed nil).

Resolves DEVEX-593.

Screen.Recording.2026-07-15.at.4.27.32.PM.mov

Commits

  • refactor(coderd): drop unused onUpdate callback from waitForProvisionerJob
  • fix(site/src/pages/TemplateBuilder): stop build progress bar from looping

Testing

  • go build ./coderd/ passes with the reduced waitForProvisionerJob signature.
  • Biome clean on the changed frontend file.
  • Storybook: pages/TemplateBuilder/BuildingTemplateLoader shows the bar fill
    once and hold, with no restart.
Implementation plan

DEVEX-593: Stop the build progress bar from looping repeatedly

Problem

While the template builder composes and imports a template, the FE shows
BuildingTemplateLoader. Its progress bar animates from 0% to 100% over 5s
with repeat: Number.POSITIVE_INFINITY, so it visibly restarts over and over.
Users report this looks broken and is frustrating to watch while waiting.

Decision (scope)

Minimal fix only: stop the loop, plus remove the now-dead onUpdate
plumbing from the backend. Since the UI is intentionally indeterminate and no
progress signal is streamed, the callback serves no purpose and should be
deleted rather than left as dead code.

Why not "real sync" now

  • POST /api/v2/templatebuilder/compose/template is a single blocking request.
    It composes, bundles, inserts the provisioner job, then calls
    waitForProvisionerJob(jobCtx, provisionerJob.ID, nil) and only responds once
    the job completes.
  • The onUpdate callback runs server-side only. Nothing is streamed to the
    browser during the wait, so the FE has no progress signal to bind to.
  • A provisioner job exposes no numeric percentage. Only status transitions
    (pending -> running -> succeeded) and coarse log stages
    (init/plan/graph/apply) exist. Real sync would require converting the
    endpoint to a streaming protocol (SSE/WebSocket) plus FE rework, which is
    disproportionate for this 1-point ticket.

Keep polling (do not switch to pubsub-block)

The wait could technically block instead of poll: on completion CompleteJob
publishes ProvisionerJobLogsNotifyMessage{EndOfLogs: true} on the job logs
notify channel, so we could subscribe and wait for that message with the
context timeout as a fallback. We deliberately do not do that here: correctness
would require subscribe-before-completion plus an initial DB completion check to
avoid a race, and Postgres LISTEN/NOTIFY is at-most-once (can drop under load),
so a poll fallback would still be needed. The existing backoff poll
(100ms -> 200ms -> 500ms -> 1s) is simple and robust for a short-lived
synchronous request.

Approach

Replace the looping fill with a single, non-repeating ease-out fill that
decelerates and approaches (but never reaches) ~90%, holding there until the
request resolves and the loader unmounts. This reads as continuous forward
progress for an unknown-duration operation and never restarts. The floating-icon
animation is intentional ambient motion and is not in scope.

Out of scope

  • Any behavioral change to how the endpoint waits (it still blocks on the job).
  • Streaming real job progress to the browser.
  • Changes to the floating-icon animation.

Generated by Coder Agents.

…erJob

The template builder create-template flow was the only caller and always
passed nil. The UI shows an indeterminate loader and no progress is streamed
to the client, so the callback is dead code. Remove the parameter and its
per-poll invocation; the function still polls and blocks until the job
completes or the context expires.
…ping

The progress bar animated 0-100% every 5s with an infinite repeat, so it
visibly restarted over and over while a template built, making it look
broken. Replace the looping fill with a single ease-out fill that
decelerates toward 90% and holds until the request resolves and the loader
unmounts.

DEVEX-593
@linear-code

linear-code Bot commented Jul 15, 2026

Copy link
Copy Markdown

DEVEX-593

Copy link
Copy Markdown
Contributor Author

@jeremyruppel jeremyruppel changed the title refactor(coderd): drop unused onUpdate callback from waitForProvisionerJob fix: stop the template builder build progress bar from looping Jul 15, 2026
@jeremyruppel
jeremyruppel marked this pull request as ready for review July 15, 2026 20:36
@jeremyruppel
jeremyruppel requested review from aqandrew and aslilac July 15, 2026 20:37
@jeremyruppel
jeremyruppel merged commit 3ddf7d3 into main Jul 16, 2026
63 of 65 checks passed
@jeremyruppel
jeremyruppel deleted the jeremy/devex-593-stop-the-build-progress-bar-from-looping-repeatedly branch July 16, 2026 13:14
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 16, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants